<div dir="ltr"><div>&gt; Why? The compiler flags an error if it can statically prove a trapping overflow will occur. Why shouldn&#39;t it flag an error if it can statically prove a force unwrap will fail?</div><div>&gt; 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?<br></div><div><br></div>Nice points! I tried to keep things as simple as possible, but it looks like such special cases would really help here.<div><br></div><div>&gt; 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 &quot;it does not return six files away from where you wrote it&quot;.<br></div><div><br></div><div>We need Never to be subtype of any type, including structs and final classes, but it&#39;s difficult to wrap my head around this while we don&#39;t have subtypes in Swift.</div><div>Anyway, I see little to no problems with this. Just the proposal is going to become longer than I expected :)</div><div><br></div><div>- Anton</div></div><div class="gmail_extra"><br><div class="gmail_quote">2016-06-06 11:12 GMT+03:00 Brent Royal-Gordon <span dir="ltr">&lt;<a href="mailto:brent@architechies.com" target="_blank">brent@architechies.com</a>&gt;</span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">&gt; The following names were suggested: NoReturn, Bottom, None, Never.<br>
&gt; I would pick None, because it looks like opposite to Any and fits nicely in generic types.<br>
<br>
</span>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&#39;s probably the most *natural* name for what we call Void.) `func x() -&gt; None` reads like it returns nothing. `func x() -&gt; Never` reads like it does not return.<br>
<span class=""><br>
&gt; I would prefer the type to be simple, and be implemented as a case-less enum (not a bottom value, as in Haskell).<br>
&gt;<br>
&gt; None should be a usual enum, with no compiler magic except that functions returning None are equivalent to current @noreturn.<br>
<br>
</span>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&#39;t you like having a bottom type?<br>
<span class=""><br>
&gt; Example 1.<br>
&gt; let x: None?<br>
&gt; // ...<br>
&gt; let y = x!<br>
&gt;<br>
&gt; 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.<br>
<br>
</span>I&#39;m not sure what you mean by this. There is no &quot;scary bottom thing&quot;; 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(&quot;implement pro books counting&quot;)` in an expression and it will compile, since Bottom/None/Never is a subtype of `basicBooks`&#39;s type—it&#39;s simply one that will never actually be created.<br>
<br>
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 &quot;it does not return six files away from where you wrote it&quot;.<br>
<span class=""><br>
&gt; We could prove that it is always true in this case, but compiler must be stupid about this.<br>
<br>
</span>Why? The compiler flags an error if it can statically prove a trapping overflow will occur. Why shouldn&#39;t it flag an error if it can statically prove a force unwrap will fail?<br>
<span class=""><br>
&gt; Example 2.<br>
&gt; Compiler should allow including None in structures. Error will show up in constructor, when we will not be able to initialize the field.<br>
<br>
</span>Well, you can assign the field from a call to something like `fatalError()`, but of course that will crash at runtime. (That&#39;s true whether we use a bottom type or an empty type, by the way.)<br>
<span class=""><br>
&gt; Example 3.<br>
&gt; None in an enum case makes that case never appear in values of such a type. But compiler can not know about that.<br>
<br>
</span>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&#39;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?<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
Brent Royal-Gordon<br>
Architechies<br>
<br>
</font></span></blockquote></div><br></div>