[Draft] Change @noreturn to unconstructible return type

I disagree. We are discussing how to annotate a function in some way so that the compiler knows that the code following it will never be executed *and* so a human who reads the declaration knows that it does not return. “Never" is a poor choice for that. Never what? Never return? Never use this function? Never say never again?

"Never return". That's why it's in the return type slot, right after the `->`. If you read it out loud, you'll read "returns Never", which is exactly correct.

NoReturn, on the other hand, does *not* read well in that slot: "returns NoReturn". Huh? I mean, I suppose you won't misunderstand it, but it makes no sense whatsoever *as a type name*.

If you want bottom types for other uses, give them their own appropriate and self documenting names.

The problem is, types flow through the type system. Use a NoReturn method with optional chaining, now you have an Optional<NoReturn>. flatMap over that Optional<NoReturn>, now you have a parameter of type NoReturn. What's a *parameter* of type NoReturn? You'd want it to be, say, a different bottom type named NoPass, but you can't—the type came from a NoReturn, and it's stuck being a NoReturn.

Never works pretty well—honestly, surprisingly well—in all of these contexts. The method returns Never, so optional chaining gives you an Optional<Never>, so flatMap has a Never parameter. I have yet to discover a case where it isn't easily interpreted to mean exactly what it really does mean.

···

--
Brent Royal-Gordon
Architechies

+1 for NoReturn

···

Call it NoReturn as the comment you quoted suggests.

If you want bottom types for other uses, give them their own appropriate and self documenting names.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

I disagree. We are discussing how to annotate a function in some way so that the compiler knows that the code following it will never be executed *and* so a human who reads the declaration knows that it does not return. “Never" is a poor choice for that. Never what? Never return? Never use this function? Never say never again?

"Never return". That's why it's in the return type slot, right after the `->`. If you read it out loud, you'll read "returns Never", which is exactly correct.

A return type makes a lot of sense linguistically but does not cover all practical cases because you might not be the one deciding what the function's signature is. For example, you might implement a protocol method that is non-optional, but you never expect to be called. The only way to indicate that to the compiler is with an attribute.
-damien

···

On 7 Jun, 2016, at 09:47, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

NoReturn, on the other hand, does *not* read well in that slot: "returns NoReturn". Huh? I mean, I suppose you won't misunderstand it, but it makes no sense whatsoever *as a type name*.

If you want bottom types for other uses, give them their own appropriate and self documenting names.

The problem is, types flow through the type system. Use a NoReturn method with optional chaining, now you have an Optional<NoReturn>. flatMap over that Optional<NoReturn>, now you have a parameter of type NoReturn. What's a *parameter* of type NoReturn? You'd want it to be, say, a different bottom type named NoPass, but you can't—the type came from a NoReturn, and it's stuck being a NoReturn.

Never works pretty well—honestly, surprisingly well—in all of these contexts. The method returns Never, so optional chaining gives you an Optional<Never>, so flatMap has a Never parameter. I have yet to discover a case where it isn't easily interpreted to mean exactly what it really does mean.

--
Brent Royal-Gordon
Architechies

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

But it’s *not* a type. You’ll never have an instance of it. Since it’s not a type name, it doesn’t make sense that it needs to look like one. What it is doing is telling you something about the behavior of the function itself, not its return value. Its return value, if there were one, is irrelevant, since the function, by its very nature, will never even get to the point where it would return it. Either it’s going to kill the app via a fatalError or something, or we have something like dispatch_main() which will keep executing until the program stops, and one way or another, it won’t return.

For that reason, frankly, I don’t understand why we want to change this from being an attribute, which seems to me the more natural and logical choice to describe this behavior. If we *do* have to change it, though, NoReturn conveys the most clearly to the reader what it does.

Charles

···

On Jun 7, 2016, at 11:47 AM, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

I disagree. We are discussing how to annotate a function in some way so that the compiler knows that the code following it will never be executed *and* so a human who reads the declaration knows that it does not return. “Never" is a poor choice for that. Never what? Never return? Never use this function? Never say never again?

"Never return". That's why it's in the return type slot, right after the `->`. If you read it out loud, you'll read "returns Never", which is exactly correct.

NoReturn, on the other hand, does *not* read well in that slot: "returns NoReturn". Huh? I mean, I suppose you won't misunderstand it, but it makes no sense whatsoever *as a type name*.

A return type makes a lot of sense linguistically but does not cover all practical cases because you might not be the one deciding what the function's signature is. For example, you might implement a protocol method that is non-optional, but you never expect to be called. The only way to indicate that to the compiler is with an attribute.

If Swift permits return type covariance—that is, for an override or implementation to tighten the return type—then this will happen naturally: Never is a subtype of all types, so you can validly change any return type to Never and meet the supertype's requirements.

I believe Swift supports return type covariance for overridden methods, but not for protocol requirements. This is, in my opinion, an incorrect behavior which should be changed.

···

--
Brent Royal-Gordon
Architechies

But it’s *not* a type.

The bottom type is as much a type as the top type (Any) is. There is a *lot* of literature on this. Respectfully, if you believe otherwise, you need to research type systems more until you change your mind.

···

--
Brent Royal-Gordon
Architechies

I disagree. We are discussing how to annotate a function in some way so that the compiler knows that the code following it will never be executed *and* so a human who reads the declaration knows that it does not return. “Never" is a poor choice for that. Never what? Never return? Never use this function? Never say never again?

"Never return". That's why it's in the return type slot, right after the `->`. If you read it out loud, you'll read "returns Never", which is exactly correct.

NoReturn, on the other hand, does *not* read well in that slot: "returns NoReturn". Huh? I mean, I suppose you won't misunderstand it, but it makes no sense whatsoever *as a type name*.

But it’s *not* a type. You’ll never have an instance of it. Since it’s not a type name, it doesn’t make sense that it needs to look like one. What it is doing is telling you something about the behavior of the function itself, not its return value. Its return value, if there were one, is irrelevant, since the function, by its very nature, will never even get to the point where it would return it. Either it’s going to kill the app via a fatalError or something, or we have something like dispatch_main() which will keep executing until the program stops, and one way or another, it won’t return.

For that reason, frankly, I don’t understand why we want to change this from being an attribute, which seems to me the more natural and logical choice to describe this behavior. If we *do* have to change it, though, NoReturn conveys the most clearly to the reader what it does.

+1 for @noreturn
We don't have to change it.
We have to keep it.

-Michael

···

Am 07.06.2016 um 19:45 schrieb Charles Srstka via swift-evolution <swift-evolution@swift.org>:

On Jun 7, 2016, at 11:47 AM, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

Charles

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

I disagree. We are discussing how to annotate a function in some way so that the compiler knows that the code following it will never be executed *and* so a human who reads the declaration knows that it does not return. “Never" is a poor choice for that. Never what? Never return? Never use this function? Never say never again?

"Never return". That's why it's in the return type slot, right after the `->`. If you read it out loud, you'll read "returns Never", which is exactly correct.

A return type makes a lot of sense linguistically but does not cover all practical cases because you might not be the one deciding what the function's signature is. For example, you might implement a protocol method that is non-optional, but you never expect to be called. The only way to indicate that to the compiler is with an attribute.
-damien

That would be lying to the type system like Java did in their collection library throwing exceptions for some method implementations which is horribly broken.
If you conform to a protocol that means you sign a contract that all the methods of the protocol may be called. There is no way out.
Except in cases with type parameters (or associated types in protocols) where you might use Never for such a type parameter, thereby making all methods taking arguments of this type uncallable without cheating the type system, e.g.

// quick and dirty example without method bodies and not to be taken too seriously

protocol QueueType {
    associatedtype In
    associatedtype Out
    func enqueue(element: In)
    func dequeue() -> Out
}

struct Queue<In, Out> : QueueType {
    func enqueue(element: In)
    func dequeue() -> Out
}

struct Source<Out> : QueueType {
    func enqueue(element: Never)
    func dequeue() -> Out
}

struct Sink<In> : QueueType {
    func enqueue(element: In)
    func dequeue() -> Never
}

let source: Source<Int> = ...
let sink: Sink<String> = ...
let queue: Queue<Int, String> = ...
queue.enqueue(source.dequeue())
sink.enqueue(queue.dequeue())
source.enqueue(1) // type error

-Thorsten

···

Am 07.06.2016 um 20:11 schrieb Damien Sorresso via swift-evolution <swift-evolution@swift.org>:
On 7 Jun, 2016, at 09:47, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

NoReturn, on the other hand, does *not* read well in that slot: "returns NoReturn". Huh? I mean, I suppose you won't misunderstand it, but it makes no sense whatsoever *as a type name*.

If you want bottom types for other uses, give them their own appropriate and self documenting names.

The problem is, types flow through the type system. Use a NoReturn method with optional chaining, now you have an Optional<NoReturn>. flatMap over that Optional<NoReturn>, now you have a parameter of type NoReturn. What's a *parameter* of type NoReturn? You'd want it to be, say, a different bottom type named NoPass, but you can't—the type came from a NoReturn, and it's stuck being a NoReturn.

Never works pretty well—honestly, surprisingly well—in all of these contexts. The method returns Never, so optional chaining gives you an Optional<Never>, so flatMap has a Never parameter. I have yet to discover a case where it isn't easily interpreted to mean exactly what it really does mean.

--
Brent Royal-Gordon
Architechies

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

I disagree. We are discussing how to annotate a function in some way so that the compiler knows that the code following it will never be executed *and* so a human who reads the declaration knows that it does not return. “Never" is a poor choice for that. Never what? Never return? Never use this function? Never say never again?

"Never return". That's why it's in the return type slot, right after the `->`. If you read it out loud, you'll read "returns Never", which is exactly correct.

I would read it as “returns an object of type “Never” if I hadn’t been reading this thread. “Never" is a bad choice if all you want to do is indicate to a human that the function does not return.

NoReturn, on the other hand, does *not* read well in that slot: "returns NoReturn". Huh? I mean, I suppose you won't misunderstand it, but it makes no sense whatsoever *as a type name*.

Who cares? We want it to be as obvious as possible that the function does not return not that the construct reads like an English sentence.

If you want bottom types for other uses, give them their own appropriate and self documenting names.

The problem is, types flow through the type system. Use a NoReturn method with optional chaining, now you have an Optional<NoReturn>. flatMap over that Optional<NoReturn>, now you have a parameter of type NoReturn. What's a *parameter* of type NoReturn? You'd want it to be, say, a different bottom type named NoPass, but you can't—the type came from a NoReturn, and it's stuck being a NoReturn.

This is a method that *does not return*. The compiler should error if you try to use the “result” of a no return function. In fact, it should error if there is any more code after the method that can’t be reached by a path that avoids the call.

I think you have convinced me that the idea of indicating noreturn methods with a return type is pretty stupid.

Never works pretty well—honestly, surprisingly well—in all of these contexts.

It might do logically and from the ivory tower purist point of view, but for a casual reader of the code who just wants to understand the API

    @noreturn func foo()

is vastly superior to

   func foo() -> Never

···

On 7 Jun 2016, at 17:47, Brent Royal-Gordon <brent@architechies.com> wrote:

Not fully sure of the possibility and usefulness, but I think that moving from the current attribute to a type could allow the registration of non returning escaping closure.

I'll leave further investigation/discussion on the use of this '-> Never' with closure to people using Swift on a daily basis, but something tell me it could be handy.

Dany

···

Le 7 juin 2016 à 13:45, Charles Srstka via swift-evolution <swift-evolution@swift.org> a écrit :

On Jun 7, 2016, at 11:47 AM, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

I disagree. We are discussing how to annotate a function in some way so that the compiler knows that the code following it will never be executed *and* so a human who reads the declaration knows that it does not return. “Never" is a poor choice for that. Never what? Never return? Never use this function? Never say never again?

"Never return". That's why it's in the return type slot, right after the `->`. If you read it out loud, you'll read "returns Never", which is exactly correct.

NoReturn, on the other hand, does *not* read well in that slot: "returns NoReturn". Huh? I mean, I suppose you won't misunderstand it, but it makes no sense whatsoever *as a type name*.

But it’s *not* a type. You’ll never have an instance of it. Since it’s not a type name, it doesn’t make sense that it needs to look like one. What it is doing is telling you something about the behavior of the function itself, not its return value. Its return value, if there were one, is irrelevant, since the function, by its very nature, will never even get to the point where it would return it. Either it’s going to kill the app via a fatalError or something, or we have something like dispatch_main() which will keep executing until the program stops, and one way or another, it won’t return.

For that reason, frankly, I don’t understand why we want to change this from being an attribute, which seems to me the more natural and logical choice to describe this behavior. If we *do* have to change it, though, NoReturn conveys the most clearly to the reader what it does.

I disagree. We are discussing how to annotate a function in some way so that the compiler knows that the code following it will never be executed *and* so a human who reads the declaration knows that it does not return. “Never" is a poor choice for that. Never what? Never return? Never use this function? Never say never again?

"Never return". That's why it's in the return type slot, right after the `->`. If you read it out loud, you'll read "returns Never", which is exactly correct.

NoReturn, on the other hand, does *not* read well in that slot: "returns NoReturn". Huh? I mean, I suppose you won't misunderstand it, but it makes no sense whatsoever *as a type name*.

But it’s *not* a type. You’ll never have an instance of it. Since it’s not a type name, it doesn’t make sense that it needs to look like one. What it is doing is telling you something about the behavior of the function itself, not its return value. Its return value, if there were one, is irrelevant, since the function, by its very nature, will never even get to the point where it would return it. Either it’s going to kill the app via a fatalError or something, or we have something like dispatch_main() which will keep executing until the program stops, and one way or another, it won’t return.

For that reason, frankly, I don’t understand why we want to change this from being an attribute, which seems to me the more natural and logical choice to describe this behavior. If we *do* have to change it, though, NoReturn conveys the most clearly to the reader what it does.

+1 for @noreturn
We don't have to change it.
We have to keep it.

+1 from me too.
Logically, “does not return" is an annotation: the function doesn’t return something that can’t be returned, it just doesn’t resume execution at the call point.

···

On Jun 7, 2016, at 12:49 PM, Michael Peternell via swift-evolution <swift-evolution@swift.org> wrote:

Am 07.06.2016 um 19:45 schrieb Charles Srstka via swift-evolution <swift-evolution@swift.org>:

On Jun 7, 2016, at 11:47 AM, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

-Michael

Charles

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

>
>>
>>> I disagree. We are discussing how to annotate a function in some way
so that the compiler knows that the code following it will never be
executed *and* so a human who reads the declaration knows that it does not
return. “Never" is a poor choice for that. Never what? Never return? Never
use this function? Never say never again?
>>
>> "Never return". That's why it's in the return type slot, right after
the `->`. If you read it out loud, you'll read "returns Never", which is
exactly correct.
>>
>> NoReturn, on the other hand, does *not* read well in that slot:
"returns NoReturn". Huh? I mean, I suppose you won't misunderstand it, but
it makes no sense whatsoever *as a type name*.
>
> But it’s *not* a type. You’ll never have an instance of it.

That's the dictionary definition of a bottom type
<https://en.wikipedia.org/wiki/Bottom_type&gt;, though: a type which has no
values.

Since it’s not a type name, it doesn’t make sense that it needs to look
like one. What it is doing is telling you something about the behavior of
the function itself, not its return value. Its return value, if there were
one, is irrelevant, since the function, by its very nature, will never even
get to the point where it would return it.

And that's the dictionary definition of a function where the return type is
bottom. This isn't something being made up just for Swift...

···

On Tue, Jun 7, 2016 at 2:49 PM, Michael Peternell via swift-evolution < swift-evolution@swift.org> wrote:

> Am 07.06.2016 um 19:45 schrieb Charles Srstka via swift-evolution < > swift-evolution@swift.org>:
>> On Jun 7, 2016, at 11:47 AM, Brent Royal-Gordon via swift-evolution < > swift-evolution@swift.org> wrote:

Either it’s going to kill the app via a fatalError or something, or we
have something like dispatch_main() which will keep executing until the
program stops, and one way or another, it won’t return.
>
> For that reason, frankly, I don’t understand why we want to change this
from being an attribute, which seems to me the more natural and logical
choice to describe this behavior. If we *do* have to change it, though,
NoReturn conveys the most clearly to the reader what it does.

+1 for @noreturn
We don't have to change it.
We have to keep it.

-Michael

>
> Charles
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

What’s the dictionary definition of a do loop? Or a for loop? Or try/catch?

Swift doesn’t do things the same as other languages in lots of places. I don’t see why it has to be different here. @noreturn is a clearer description of what this construct does.

Charles

···

On Jun 7, 2016, at 3:12 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Tue, Jun 7, 2016 at 2:49 PM, Michael Peternell via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

> Am 07.06.2016 um 19:45 schrieb Charles Srstka via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>:
>
>> On Jun 7, 2016, at 11:47 AM, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>
>>> I disagree. We are discussing how to annotate a function in some way so that the compiler knows that the code following it will never be executed *and* so a human who reads the declaration knows that it does not return. “Never" is a poor choice for that. Never what? Never return? Never use this function? Never say never again?
>>
>> "Never return". That's why it's in the return type slot, right after the `->`. If you read it out loud, you'll read "returns Never", which is exactly correct.
>>
>> NoReturn, on the other hand, does *not* read well in that slot: "returns NoReturn". Huh? I mean, I suppose you won't misunderstand it, but it makes no sense whatsoever *as a type name*.
>
> But it’s *not* a type. You’ll never have an instance of it.

That's the dictionary definition of a bottom type <https://en.wikipedia.org/wiki/Bottom_type&gt;, though: a type which has no values.

Since it’s not a type name, it doesn’t make sense that it needs to look like one. What it is doing is telling you something about the behavior of the function itself, not its return value. Its return value, if there were one, is irrelevant, since the function, by its very nature, will never even get to the point where it would return it.

And that's the dictionary definition of a function where the return type is bottom. This isn't something being made up just for Swift...

>
>>
>>> I disagree. We are discussing how to annotate a function in some way
so that the compiler knows that the code following it will never be
executed *and* so a human who reads the declaration knows that it does not
return. “Never" is a poor choice for that. Never what? Never return? Never
use this function? Never say never again?
>>
>> "Never return". That's why it's in the return type slot, right after
the `->`. If you read it out loud, you'll read "returns Never", which is
exactly correct.
>>
>> NoReturn, on the other hand, does *not* read well in that slot:
"returns NoReturn". Huh? I mean, I suppose you won't misunderstand it, but
it makes no sense whatsoever *as a type name*.
>
> But it’s *not* a type. You’ll never have an instance of it.

That's the dictionary definition of a bottom type
<https://en.wikipedia.org/wiki/Bottom_type&gt;, though: a type which has no
values.

Since it’s not a type name, it doesn’t make sense that it needs to look
like one. What it is doing is telling you something about the behavior of
the function itself, not its return value. Its return value, if there were
one, is irrelevant, since the function, by its very nature, will never even
get to the point where it would return it.

And that's the dictionary definition of a function where the return type
is bottom. This isn't something being made up just for Swift...

What’s the dictionary definition of a do loop? Or a for loop? Or try/catch?

Swift doesn’t do things the same as other languages in lots of places. I
don’t see why it has to be different here. @noreturn is a clearer
description of what this construct does.

My response was simply to say that Never or NoReturn would in fact be a
type, which is a good justification for looking like one. This behavior
would be learnable and is theoretically sound, not an ad hoc idea being
made up on the spot. No doubt, @noreturn is clearer today, but how much of
that is because it's what we already know? And FWIW, "returns never" is
hard to misinterpret, no?

···

On Tue, Jun 7, 2016 at 3:36 PM, Charles Srstka <cocoadev@charlessoft.com> wrote:

On Jun 7, 2016, at 3:12 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:
On Tue, Jun 7, 2016 at 2:49 PM, Michael Peternell via swift-evolution < > swift-evolution@swift.org> wrote:

> Am 07.06.2016 um 19:45 schrieb Charles Srstka via swift-evolution < >> swift-evolution@swift.org>:
>> On Jun 7, 2016, at 11:47 AM, Brent Royal-Gordon via swift-evolution < >> swift-evolution@swift.org> wrote:

Charles

No doubt, @noreturn is clearer today, but how much of that is because it's what we already know?

None. It’s clearer because it does exactly what it says on the tin. Show it to someone who’s familiar with the concept of functions and returning but who's never seen Swift before, and they will intuit what it does.

And FWIW, "returns never" is hard to misinterpret, no?

“returns never” isn’t what you have, though. You have func foo() -> Never, which could mean a bunch of things. It could mean it never returns a *value*, i.e. a void return. It could mean someone made some crazy struct and named it Never. It’s not obvious from looking at it without prior knowledge of the system.

Charles

···

On Jun 7, 2016, at 3:56 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

I disagree. We are discussing how to annotate a function in some way so that the compiler knows that the code following it will never be executed *and* so a human who reads the declaration knows that it does not return. “Never" is a poor choice for that. Never what? Never return? Never use this function? Never say never again?

"Never return". That's why it's in the return type slot, right after the `->`. If you read it out loud, you'll read "returns Never", which is exactly correct.

A return type makes a lot of sense linguistically but does not cover all practical cases because you might not be the one deciding what the function's signature is. For example, you might implement a protocol method that is non-optional, but you never expect to be called. The only way to indicate that to the compiler is with an attribute.
-damien

That would be lying to the type system like Java did in their collection library throwing exceptions for some method implementations which is horribly broken.
If you conform to a protocol that means you sign a contract that all the methods of the protocol may be called. There is no way out.
Except in cases with type parameters (or associated types in protocols) where you might use Never for such a type parameter, thereby making all methods taking arguments of this type uncallable without cheating the type system, e.g.

In this scenario, the protocol has been defined in a sub-optimal way that is outside the bounds of your control. I'm totally sympathetic to the argument that it's wrong, but it does happen, so I am sympathetic to API clients who want to do as much of the right thing as possible while also registering their displeasure via an attribute.
-damien

···

On 7 Jun, 2016, at 13:46, Thorsten Seitz <tseitz42@icloud.com> wrote:

Am 07.06.2016 um 20:11 schrieb Damien Sorresso via swift-evolution <swift-evolution@swift.org>:
On 7 Jun, 2016, at 09:47, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

// quick and dirty example without method bodies and not to be taken too seriously

protocol QueueType {
   associatedtype In
   associatedtype Out
   func enqueue(element: In)
   func dequeue() -> Out
}

struct Queue<In, Out> : QueueType {
   func enqueue(element: In)
   func dequeue() -> Out
}

struct Source<Out> : QueueType {
   func enqueue(element: Never)
   func dequeue() -> Out
}

struct Sink<In> : QueueType {
   func enqueue(element: In)
   func dequeue() -> Never
}

let source: Source<Int> = ...
let sink: Sink<String> = ...
let queue: Queue<Int, String> = ...
queue.enqueue(source.dequeue())
sink.enqueue(queue.dequeue())
source.enqueue(1) // type error

-Thorsten

NoReturn, on the other hand, does *not* read well in that slot: "returns NoReturn". Huh? I mean, I suppose you won't misunderstand it, but it makes no sense whatsoever *as a type name*.

If you want bottom types for other uses, give them their own appropriate and self documenting names.

The problem is, types flow through the type system. Use a NoReturn method with optional chaining, now you have an Optional<NoReturn>. flatMap over that Optional<NoReturn>, now you have a parameter of type NoReturn. What's a *parameter* of type NoReturn? You'd want it to be, say, a different bottom type named NoPass, but you can't—the type came from a NoReturn, and it's stuck being a NoReturn.

Never works pretty well—honestly, surprisingly well—in all of these contexts. The method returns Never, so optional chaining gives you an Optional<Never>, so flatMap has a Never parameter. I have yet to discover a case where it isn't easily interpreted to mean exactly what it really does mean.

--
Brent Royal-Gordon
Architechies

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

I strongly agree. Just because it can be modelled as a type doesn’t mean it’s the best way to represent the concept. It feels like uniformity for uniformity’s sake.

func fatalError() -> Never

@noreturn func fatalError()

The first one probably isn't too hard to explain to a learner. The second one probably doesn’t need an explanation.

Jordan

···

On Jun 7, 2016, at 12:49, Michael Peternell via swift-evolution <swift-evolution@swift.org> wrote:

Am 07.06.2016 um 19:45 schrieb Charles Srstka via swift-evolution <swift-evolution@swift.org>:

On Jun 7, 2016, at 11:47 AM, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

I disagree. We are discussing how to annotate a function in some way so that the compiler knows that the code following it will never be executed *and* so a human who reads the declaration knows that it does not return. “Never" is a poor choice for that. Never what? Never return? Never use this function? Never say never again?

"Never return". That's why it's in the return type slot, right after the `->`. If you read it out loud, you'll read "returns Never", which is exactly correct.

NoReturn, on the other hand, does *not* read well in that slot: "returns NoReturn". Huh? I mean, I suppose you won't misunderstand it, but it makes no sense whatsoever *as a type name*.

But it’s *not* a type. You’ll never have an instance of it. Since it’s not a type name, it doesn’t make sense that it needs to look like one. What it is doing is telling you something about the behavior of the function itself, not its return value. Its return value, if there were one, is irrelevant, since the function, by its very nature, will never even get to the point where it would return it. Either it’s going to kill the app via a fatalError or something, or we have something like dispatch_main() which will keep executing until the program stops, and one way or another, it won’t return.

For that reason, frankly, I don’t understand why we want to change this from being an attribute, which seems to me the more natural and logical choice to describe this behavior. If we *do* have to change it, though, NoReturn conveys the most clearly to the reader what it does.

+1 for @noreturn
We don't have to change it.
We have to keep it.

All my +1s to this line of reasoning.

l8r
Sean

···

On Jun 7, 2016, at 7:21 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:

On Jun 7, 2016, at 12:49, Michael Peternell via swift-evolution <swift-evolution@swift.org> wrote:

Am 07.06.2016 um 19:45 schrieb Charles Srstka via swift-evolution <swift-evolution@swift.org>:

On Jun 7, 2016, at 11:47 AM, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

I disagree. We are discussing how to annotate a function in some way so that the compiler knows that the code following it will never be executed *and* so a human who reads the declaration knows that it does not return. “Never" is a poor choice for that. Never what? Never return? Never use this function? Never say never again?

"Never return". That's why it's in the return type slot, right after the `->`. If you read it out loud, you'll read "returns Never", which is exactly correct.

NoReturn, on the other hand, does *not* read well in that slot: "returns NoReturn". Huh? I mean, I suppose you won't misunderstand it, but it makes no sense whatsoever *as a type name*.

But it’s *not* a type. You’ll never have an instance of it. Since it’s not a type name, it doesn’t make sense that it needs to look like one. What it is doing is telling you something about the behavior of the function itself, not its return value. Its return value, if there were one, is irrelevant, since the function, by its very nature, will never even get to the point where it would return it. Either it’s going to kill the app via a fatalError or something, or we have something like dispatch_main() which will keep executing until the program stops, and one way or another, it won’t return.

For that reason, frankly, I don’t understand why we want to change this from being an attribute, which seems to me the more natural and logical choice to describe this behavior. If we *do* have to change it, though, NoReturn conveys the most clearly to the reader what it does.

+1 for @noreturn
We don't have to change it.
We have to keep it.

I strongly agree. Just because it can be modelled as a type doesn’t mean it’s the best way to represent the concept. It feels like uniformity for uniformity’s sake.

func fatalError() -> Never

@noreturn func fatalError()

The first one probably isn't too hard to explain to a learner. The second one probably doesn’t need an explanation.

Jordan

On the other hand...

The first is rather clever and beautiful looking...making it somewhat Swifty.

I never cared for annotations:
- they make it look noisy
- they seem like a "hack" rather than a true part of the standard library

Also technically,

@noreturn func fatalError()

can be modeled as (I think?):
@noreturn func fatalError() -> Void

which doesn't make much sense.

Also, could this fix this issue:
"That said, you can’t override a function or method that is marked with the noreturnattribute with a function or method that is not. Similar rules apply when you implement a protocol method in a conforming type."

Overriding a method without this as an attribute could allow this. I'm not sure if this is something people would need though or if it even makes sense.

Brandon

···

On Jun 7, 2016, at 8:21 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:

On Jun 7, 2016, at 12:49, Michael Peternell via swift-evolution <swift-evolution@swift.org> wrote:

Am 07.06.2016 um 19:45 schrieb Charles Srstka via swift-evolution <swift-evolution@swift.org>:

On Jun 7, 2016, at 11:47 AM, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

I disagree. We are discussing how to annotate a function in some way so that the compiler knows that the code following it will never be executed *and* so a human who reads the declaration knows that it does not return. “Never" is a poor choice for that. Never what? Never return? Never use this function? Never say never again?

"Never return". That's why it's in the return type slot, right after the `->`. If you read it out loud, you'll read "returns Never", which is exactly correct.

NoReturn, on the other hand, does *not* read well in that slot: "returns NoReturn". Huh? I mean, I suppose you won't misunderstand it, but it makes no sense whatsoever *as a type name*.

But it’s *not* a type. You’ll never have an instance of it. Since it’s not a type name, it doesn’t make sense that it needs to look like one. What it is doing is telling you something about the behavior of the function itself, not its return value. Its return value, if there were one, is irrelevant, since the function, by its very nature, will never even get to the point where it would return it. Either it’s going to kill the app via a fatalError or something, or we have something like dispatch_main() which will keep executing until the program stops, and one way or another, it won’t return.

For that reason, frankly, I don’t understand why we want to change this from being an attribute, which seems to me the more natural and logical choice to describe this behavior. If we *do* have to change it, though, NoReturn conveys the most clearly to the reader what it does.

+1 for @noreturn
We don't have to change it.
We have to keep it.

I strongly agree. Just because it can be modelled as a type doesn’t mean it’s the best way to represent the concept. It feels like uniformity for uniformity’s sake.

func fatalError() -> Never

@noreturn func fatalError()

The first one probably isn't too hard to explain to a learner. The second one probably doesn’t need an explanation.

Jordan

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

I disagree. We are discussing how to annotate a function in some way so that the compiler knows that the code following it will never be executed *and* so a human who reads the declaration knows that it does not return. “Never" is a poor choice for that. Never what? Never return? Never use this function? Never say never again?

"Never return". That's why it's in the return type slot, right after the `->`. If you read it out loud, you'll read "returns Never", which is exactly correct.

NoReturn, on the other hand, does *not* read well in that slot: "returns NoReturn". Huh? I mean, I suppose you won't misunderstand it, but it makes no sense whatsoever *as a type name*.

But it’s *not* a type. You’ll never have an instance of it. Since it’s not a type name, it doesn’t make sense that it needs to look like one. What it is doing is telling you something about the behavior of the function itself, not its return value. Its return value, if there were one, is irrelevant, since the function, by its very nature, will never even get to the point where it would return it. Either it’s going to kill the app via a fatalError or something, or we have something like dispatch_main() which will keep executing until the program stops, and one way or another, it won’t return.

For that reason, frankly, I don’t understand why we want to change this from being an attribute, which seems to me the more natural and logical choice to describe this behavior. If we *do* have to change it, though, NoReturn conveys the most clearly to the reader what it does.

+1 for @noreturn
We don't have to change it.
We have to keep it.

this is so unfortunate… IMHO the proposal is the right move because it goes into the direction of unifying things in the language. the problem is that it is difficult to see it without looking at the language as a whole. then we realize that this can be connected to the change of dynamicType to a function or to the fact that .Type and .Self might also warrant a revisiting.

I do hope the core team does pull ranks and goes with it. Frankly I have no stake in the name, and I would even argue that there might be a possible case for doing something even more un-explainable than this change:

1) create a protocol SwiftBottomType { } [ the core team might defend the idea that it should really be BuiltinBottomType, which I have no issues with ]

2) then create a enum NoReturn: SwiftBottomType {}

When looking at this question and a couple of other related ones, a pattern should form, and the rational become self evident.

···

On Jun 7, 2016, at 9:49 PM, Michael Peternell via swift-evolution <swift-evolution@swift.org> wrote:

Am 07.06.2016 um 19:45 schrieb Charles Srstka via swift-evolution <swift-evolution@swift.org>:

On Jun 7, 2016, at 11:47 AM, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

-Michael

Charles

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution