[swift-evolution] [swift-evolution-announce] [Review] SE-0102: Remove @noreturn attribute and introduce an empty NoReturn type

Brent Royal-Gordon brent at architechies.com
Tue Jun 21 18:42:01 CDT 2016

> 	* What is your evaluation of the proposal?

I like the idea, but not the name. I would prefer a more general name like `Never`.

If `NoReturn` becomes a universal bottom type, it's going to need a more universal name than `NoReturn` It's very narrow and specialized, so it's not appropriate for bottom types in other contexts; just think of the `NoReturn?` variable created by optional chaining, or the `[NoReturn]` array created by `map`. As soon as you take even the tiniest step away from a return value, the name doesn't really make sense anymore.

Therefore, I strongly suspect we'll have to change this name again in the future as `NoReturn` becomes a more powerful bottom type. I'm not really looking forward to changing `@noreturn` to `-> NoReturn` in Swift 3 and then changing it again to `-> Never` in Swift 4, so I think we should just do it here and now.

I also don't like the way `NoReturn` reads. It *is* understandable, but it bluntly disobeys type naming conventions by describing not the value being returned, but the member returning it. There are many sensible names we might have given `Void` if not for C—`Nothing`, `None`, `Empty`—but I don't think anybody would advocate for `EmptyReturn`. It just isn't an appropriate type name.

An attribute is an adjective describing a member, and `@noreturn` (or rather, `@nonreturning`) is a perfectly fine adjective to attach to a function, so the name works fine there. But a type is a *noun* describing a *value*, and `NoReturn` is not. You are trying to cram a square peg into a round hole.

> 	* Is the problem being addressed significant enough to warrant a change to Swift?

Yes. Something should be done about `@noreturn`, and this basic approach is the most elegant one available.

> 	* Does this proposal fit well with the feel and direction of Swift?

The approach, but not the name. As I pointed out previously, it does not match naming conventions or even the general semantic meaning of a return type.

(Incidentally, another reason I like the idea of eventually having a subtype-of-all-types `Never` is that I think we should treat `UnsafePointer<Never>` as our "pointer of uncertain type" type. That is, `void *` should be imported to Swift as `UnsafePointer<Never>`. That would inherently prevent you from using the `pointee` property, and if you thought of `sizeof(Never)` as being infinite—a plausible interpretation since `Never` *could* be a subtype of a type of any size—it would also imply that pointer arithmetic or allocation of `Never` buffers would always overflow unless you were handling zero `Never`s.)

> 	* If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

I've used other languages with equivalents to `@noreturn`, and I think the bottom return value approach will be an improvement on that.

> 	* How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Quick reading of the final proposal, but I've participated in much of the discussion about this feature.

Brent Royal-Gordon

More information about the swift-evolution mailing list