DIP 1017--Add Bottom Type--Final Review
Johannes Loher
johannes.loher at fg4f.de
Wed Jan 16 08:09:39 UTC 2019
On Wednesday, 16 January 2019 at 07:04:37 UTC, Neia Neutuladh
wrote:
> Kotlin has a type called Nothing. It doesn't do implicit
> conversions. It supports the ternary logic that this DIP
> proposes as a side effect (you can use throw and return in the
> same way). You can have variables of this type, pass it to
> functions, assign it to things, etc.
>
> fun foo(): Nothing {
> throw Exception("this doesn't work")
> }
> fun foo2(n: Nothing) {}
> fun bar() {
> try {
> var n: Nothing = foo()
> foo2(n)
> var n2 = if (true) { 12 } else { foo() }
> } catch (e: Exception) {}
> }
This is not completely accurate. Nothing actually is the bottom
type in Kotlin in the sense that it DOES implicitly convert to
any type. E.g.
```
fun foo() : Nothing {
throw Exception()
}
fun bar(s: String)
{
}
fun main(args: Array<String>) {
bar(foo())
}
```
is a valid Kotlin program.
As you mention, you can however pass around variables of type
`Nothing`. You can also somewhat do this with the type proposed
by the DIP, but it is kind of limited: You can return expressions
of type `Tbottom`, but you cannot declare a variable of that type
or use it as parameter, similar to `void`. The reason for this is
probably that in D every declared variable must by default be
initiated to some value and this is not possible for void and
`Tbottom`. However, I think this limitation is a bit arbitrary.
We also have other types which do not have default
initialization. Also this is valid D:
```
struct Tbottom {
@disable this();
this(const ref Tbottom t)
{
}
@disable static Tbottom init() @property;
}
struct A {}
Tbottom fun()
{
assert(0);
return cast(Tbottom) A();
}
void main()
{
Tbottom t = fun();
}
```
Granted, this still allows casting to `Tbottom` and this type is
not implicitly convertible to every other type (these properties
need to be baked into the language, I think) and you can still
use the struct literal syntax to initialize variables of type
`Tbottom`.
But I think this showcases that it is not necessary conceptually
to disallow declaring variables of type Tbottom. They just need
to be initialized to an expression of type `Tbottom`. They still
can never have an actual value or be used because by definition,
the expression they are initialized to never returns. The same is
true for function parameters.
I actually also think it is correct to do the same for `void`,
but `void` should even a single value and thus it should be
default constructible and have an `init` property. As I mentioned
earlier in this thread, this would make `void` a proper unit
type, drawing a clear line between `Tbottom` and `void`. It is
however very complicated to get this to work with
C-interoperability.
More information about the Digitalmars-d
mailing list