The following names were suggested: NoReturn, Bottom, None, Never.
I would pick None, because it looks like opposite to Any and fits nicely in generic types.
I discussed all of these options and more. The issue I see with None is that it could easily be interpreted as Void to those without a C background. (Actually, it's probably the most *natural* name for what we call Void.) `func x() -> None` reads like it returns nothing. `func x() -> Never` reads like it does not return.
I would prefer the type to be simple, and be implemented as a case-less enum (not a bottom value, as in Haskell).
None should be a usual enum, with no compiler magic except that functions returning None are equivalent to current @noreturn.
Could you elaborate on this? I think it would be really useful to have a bottom type—useful to the point that, within minutes of deciding to think of examples, I quickly came up with some really good ones. Why don't you like having a bottom type?
let x: None?
let y = x!
It will trap in runtime not because we discover scary bottom thing, as in Haskell, but because x had value Optional.none at that moment and we asserted otherwise.
I'm not sure what you mean by this. There is no "scary bottom thing"; Bottom or None or Never or whatever you call it is still an empty type, and the unwrap still fails because the value is `.none`, not `.some`. The only difference is that you can say something like `let total = basicBooks + fatalError("implement pro books counting")` in an expression and it will compile, since Bottom/None/Never is a subtype of `basicBooks`'s type—it's simply one that will never actually be created.
I wonder if perhaps your experience with Haskell has given you a false impression of how this would work in Swift. Haskell is a pervasively lazy language. Every operation in Haskell is lazy and you have little control over when anything executes. Because of this, `undefined` values can persist for long periods of time and spread deep into your code. But Swift is not pervasively lazy; it is (relatively) simple and obvious to figure out when a given piece of code will run. When you run a Bottom/None/Never-returning expression, it does not return. Period. There is no "it does not return six files away from where you wrote it".
We could prove that it is always true in this case, but compiler must be stupid about this.
Why? The compiler flags an error if it can statically prove a trapping overflow will occur. Why shouldn't it flag an error if it can statically prove a force unwrap will fail?
Compiler should allow including None in structures. Error will show up in constructor, when we will not be able to initialize the field.
Well, you can assign the field from a call to something like `fatalError()`, but of course that will crash at runtime. (That's true whether we use a bottom type or an empty type, by the way.)
None in an enum case makes that case never appear in values of such a type. But compiler can not know about that.
Again: Why? If one of the associated values is Bottom/None/Never, how is my code improved by the fact that I still need a case for it in a `switch` statement? What's the advantage of not being able to eliminate dead code, or call out code that will inevitably fail? We already want these things for other uses of Bottom/None/Never, like dead code elimination after a precondition fails. Why not here?