<div dir="ltr">On Wed, Oct 18, 2017 at 9:29 PM, Brent Royal-Gordon <span dir="ltr">&lt;<a href="mailto:brent@architechies.com" target="_blank">brent@architechies.com</a>&gt;</span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><span class="gmail-"><div><blockquote type="cite"><div>On Oct 9, 2017, at 11:02 PM, Xiaodi Wu via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><br class="gmail-m_-8619549930888531622Apple-interchange-newline"><div><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline">This idea was discussed long ago and the present design was selected.</span></div></blockquote><br></div></span><div>But this design was discussed in the proposal as a &quot;future direction&quot;, because @discardableResult was chosen partially because it was easier to implement. It says so [in the proposal][1]. This is why we write formal proposals, Xiaodi—so we remember why we made the decisions we made.</div></div></blockquote><div><br></div><div><div>You&#39;re right that it was chosen in part because it was easier to implement.</div><div><br></div><div>But this does not at all mean that &quot;@discardable&quot; is the blessed future direction; whether it is wise ever to adopt the &quot;@discardable&quot; design was not thoroughly evaluated--it was simply decided that, for Swift 3, @discardableResult was preferable to @discardable in the totality of things.</div></div><div><br></div><div>In my view, this means the &quot;@discardable&quot; idea needs to meet a higher bar than a never-before presented idea, not a lower one.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><div> </div></div></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><div></div><div><span class="gmail-m_-8619549930888531622Apple-tab-span" style="white-space:pre-wrap">        </span>* * *</div><div><br></div><div>Now, the proposal specifically suggests we delay `@discardable` &quot;until such time as there&#39;s a strong motivation to use such an approach&quot;. Do we have such a motivation?</div><div><br></div><div>I actually think we do (although it may not be strong enough). Currently, we have two types—`Void` (as well as optionals, of any depth, wrapping `Void`) and `Never`—which are &quot;implicitly discardable&quot;. That is, you don&#39;t need to mark a function which returns those types with `@discardableResult`; it inherently is. This is currently handled with [an ad-hoc test][2], but I think we should consider strengthening and opening up this mechanism.</div><div><br></div><div>Why? Because there are other types we would like to be implicitly discardable. You can already make an argument for types like `Array&lt;Void&gt;`, but concurrency will bring types like `Future&lt;Void&gt;` which could get pretty strong benefits from it. Since we&#39;re planning to leave a lot of async stuff to userspace, there ought to be a userspace way to mark types as implicitly discardable. And if discardability stems from the type system, it&#39;s pretty natural to make ad-hoc discardibility a property attached to the type, too.</div><div><br></div><div>(We could then mark `Never` with @discardable, make tuples discardable unless one of their elements is not discardable, make optionals discardable if the type they wrap is discardable, and—et voilà!—we have a nice, general language feature with as little magic as we can manage.)</div><div><br></div><div><span class="gmail-m_-8619549930888531622Apple-tab-span" style="white-space:pre-wrap">        </span>[1]: <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0047-nonvoid-warn.md#future-directions" target="_blank">https://github.com/apple/<wbr>swift-evolution/blob/master/<wbr>proposals/0047-nonvoid-warn.<wbr>md#future-directions</a></div><div><span class="gmail-m_-8619549930888531622Apple-tab-span" style="white-space:pre-wrap">        </span>[2]: <a href="https://github.com/apple/swift/blob/e907031d3d4555e917ca3ad7fffeac7f580331a0/lib/Sema/TypeCheckStmt.cpp#L991" target="_blank">https://github.com/apple/<wbr>swift/blob/<wbr>e907031d3d4555e917ca3ad7fffeac<wbr>7f580331a0/lib/Sema/<wbr>TypeCheckStmt.cpp#L991</a></div></div></blockquote><div><br></div><div><br></div><div>I am not sure this is entirely wise, for a few reasons.<br></div><div><br></div><div>a) I sure don&#39;t know why you&#39;d want to return `Void?`, but if you do, it doesn&#39;t follow that it should be discardable simply because `Void` is discardable. It may well be so, or it may be (for some odd reason) that it&#39;s the return type of a pure function that certainly shouldn&#39;t be discardable.</div><div><br></div><div>b) Based on (a), I don&#39;t think that types composed of discardable types are therefore discardable. I need to think this through further.<br></div><div><br></div><div>c) If you reject (b), then this brings up a larger issue. `@discardableResult` is an attribute of the function; here, you&#39;re saying that not only should the _spelling_ be moved to the other side of the function arrow, but that the attribute should apply to the type. Would we then have to invent a new overriding attribute for functions that return `@discardable` types which don&#39;t want their return value to be discardable? Like, a `@nondiscardableResult func foo() -&gt; Void? /* implicitly discardable type */`? I think this further demonstrates how it&#39;s not really the type but the function that we want to annotate.</div><div><br></div><div>d) Does a class that override a `@discardable` type inherit that annotation? If not, they it&#39;s kind of a weird exception to the inheritance thing, no? If so, then we&#39;d need a @nondiscardable annotation to do type-level overrides of @discardable.</div><div><br></div><div>e) `Never` was explicitly designed to have no magic that any other uninhabited enum would not get. To stick with this design, every enum without any cases would have to be implicitly `@discardable`. This might be surprising.</div><div><br></div><div>f) Speaking of enums: if types are discardable, then some errors are discardable. By contrast, we do not currently have a `@discardableError` annotation. What does it mean if a function throws a &quot;discardable error&quot;? Can we choose not to catch it?</div><div><br></div></div></div></div>