spand
04/23/2021, 7:54 AMT?
ย . Here I invented theย T!!
ย type operator for it. Should be clear from the example here why it could be useful.
interface LoadingCache<K : Any, V> {
fun get(key: K): V // <-- If it can return null then it must be specified by type V
// If load returns null then entries are missing hence it doesnt make sense to have here : Map<K,V?>
fun getAll(keys: Iterable<K>): Map<K, V!!> {
return keys.mapNotNull { k -> get(k)?.let { k to it } }.toMap()
}
}
Thoughts ?Tomasz Krakowiak
04/23/2021, 8:27 AMinterface LoadingCache<K : Any, V : Any> {
fun get(key: K): V?
fun getAll(keys: Iterable<K>): Map<K, V> {
return keys.map { k -> get(k)?.let { k to it } }.toMap()
}
}
Seems semantically more correct to me.spand
04/23/2021, 9:22 AMLoadingCache
is serves values from a total function then it does not make sense for get
to have a nullable type.Ruckus
04/23/2021, 3:31 PMFleshgrinder
04/23/2021, 7:48 PMfun <T : Any> f(input: T): T? { /* awesome stuff */ }
fun <T> f(input: T!!): T { /* awesome stuff */ }
Ruckus
04/23/2021, 8:01 PMFleshgrinder
04/23/2021, 8:24 PMnull
.Fleshgrinder
04/23/2021, 8:26 PMRuckus
04/23/2021, 8:28 PMval x: String? = f<String>("asdf")
The second would allow either
val x: String? = f<String?>("asdf")
val y: String = f<String>("asdf")
And I don't see a practical way for the function to distinguish them:
val x = f("asdf")
Is x
a String
or a String?
? There's no way to know.Fleshgrinder
04/23/2021, 8:30 PMRuckus
04/23/2021, 8:31 PMFleshgrinder
04/23/2021, 8:31 PMFleshgrinder
04/23/2021, 8:31 PMRuckus
04/23/2021, 8:34 PMFleshgrinder
04/23/2021, 8:36 PMRuckus
04/23/2021, 8:37 PMFleshgrinder
04/23/2021, 8:43 PMFleshgrinder
04/23/2021, 8:43 PMRuckus
04/23/2021, 8:44 PMType theory is closely related to, and in some cases overlaps with, computational type systems, which are a programming language feature used to reduce bugs.So even if they (type theory and set theory) were "the same" it still doesn't necesarily apply to type systems at all.
Fleshgrinder
04/23/2021, 8:46 PMtype theory is just set theoryWhich was an oversimplification to explain, draw an analogy, trying to explain with different concepts to arrive at something that is comprehensible. Sorry for that. I'll go and do something else. Really sorry.
Ruckus
04/23/2021, 8:52 PMtype theory is just set theory, so it's basically ๐ โ ๐...If the root claim that "type theory is just set theory" doesn't hold, then the claim that "The two signatures given above are 1:1 equivalent in choice, just different locations." fundamentally isn't true. Does that make sense? Am I missing something important?
Fleshgrinder
04/23/2021, 8:58 PMT?
means T
or null
then T!!
means T
not null
. So, if T
is <T : Any?>
then T!!
is <T : Any>
. This is like the referenced ๐ โ ๐ where ๐ is T
and everything except ๐ which is null
.Fleshgrinder
04/23/2021, 9:06 PMFleshgrinder
04/23/2021, 9:08 PMOptional
to model this. Then the whole problem goes away and we can distinguish any Map.get
returned value between key doesn't exist and value is not present.spand
04/26/2021, 5:29 AMgetAll()
is a real native function that must be overridable and as I said earlier I would like to express the potential totallity of get()
without getting an ugly return type on getAll() : Map<K, V?>
in the non total case.
Current workarounds in Kotlin is using the extension method overloads as Richard shows. This workarounds is only really useable on functions. For interfaces we cannot just use the same workaround. Kotlin also "almost" has T!!
in the form of `T : Any`:
interface LoadingCache<K : Any, V> {
fun get(key: K): V // <-- If it can return null then it must be specified by type V
// If load returns null then entries are missing hence it doesnt make sense to have here : Map<K,V?>
fun <MV> getAll(keys: Iterable<K>): Map<K, MV> where MV : V, MV : Any {
return keys.mapNotNull { k -> get(k)?.let { k to it } }.toMap()
}
}
This is however prohibited by the Kotlin compiler. Not sure if this is a fundamental problem.elizarov
05/13/2021, 3:32 PMT!!
is internally supported by Kotlin's type system in the form of intersection type T & Any
, and you may enounter this type from time to time, for example, as a result of a smartcast in if (t != null)
expression. However this type is not directly denotable in the source code, but we do plan to make it denotable via this specific T!!
syntax in the future.spand
05/17/2021, 7:22 AMelizarov
05/17/2021, 8:26 AM