[swift-evolution] [Draft] Change @noreturn to unconstructible return type

Michael Peternell michael.peternell at gmx.at
Mon Jun 6 14:40:11 CDT 2016

> Am 06.06.2016 um 00:53 schrieb Charles Srstka <cocoadev at charlessoft.com>:
>> On Jun 5, 2016, at 5:41 PM, Michael Peternell via swift-evolution <swift-evolution at swift.org> wrote:
>>> Am 05.06.2016 um 20:26 schrieb Антон Жилин via swift-evolution <swift-evolution at swift.org>:
>>> 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 would like to call the type `Void`. `Void` is a type with zero possible values. The current `Void` would have to be renamed to `Unit`, the data type with exactly one possible value. Less C, More Haskell :) But wait, that's not really Haskell-ish, and it's not C-ish either.
> That is the most confusing possible thing that this could possibly be called. Seeing a Void return will cause anyone coming from a C, C++, ObjC, etc. background to think of something that is definitely *not* a no-return function.

I agree. For this reason, my email continued after that paragraph. I deliberately ended the last sentence of that paragraph with "But wait, that's not really..."

There is a really really good reason why Haskell doesn't have a named "bottom type" like "None" or "Void". The bottom type has type `forall a. a`, corresponding to the mathematical fact that from "false" follows anything. Assigning a bottom type to a variable makes only sense in Haskell, because it uses lazy evaluation. With strict evaluation, a bottom type is just confusing at best. And a `Nothing` type corresponds to Haskell's `Void` type, not to its bottom type - a really exotic type that is seldom used. Its not consistent to have a @noreturn-function return `Nothing` instead, because `Nothing` that's not a proper type. You can write a foo-function that is really unintuitive:

func foo() -> NoReturn {
   let x = fatalError("crash please")
   return x

Shouldn't we all just try to understand the rationale for the current language behavior before we try to propose changes?

E.g. with the proposal, the following function:

@noreturn func error<T>(msg: String = "") -> T {
    fatalError("bottom: \(msg)")

has to be written as

func error<T>(msg: String = "") -> T {
    fatalError("bottom: \(msg)")

It still returns bottom, but there is no way to say so in the declaration. The proposal just made the language less expressive!

See also:
for a more in-depth explanation why "bottom" is not an ordinary type with a name.


More information about the swift-evolution mailing list