On Wed, Oct 18, 2017 at 9:29 PM, Brent Royal-Gordon <br...@architechies.com> wrote:
> On Oct 9, 2017, at 11:02 PM, Xiaodi Wu via swift-evolution < > swift-evolution@swift.org> wrote: > > This idea was discussed long ago and the present design was selected. > > > But this design was discussed in the proposal as a "future direction", > 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. > You're right that it was chosen in part because it was easier to implement. But this does not at all mean that "@discardable" is the blessed future direction; whether it is wise ever to adopt the "@discardable" design was not thoroughly evaluated--it was simply decided that, for Swift 3, @discardableResult was preferable to @discardable in the totality of things. In my view, this means the "@discardable" idea needs to meet a higher bar than a never-before presented idea, not a lower one. > * * * > > Now, the proposal specifically suggests we delay `@discardable` "until > such time as there's a strong motivation to use such an approach". Do we > have such a motivation? > > 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 "implicitly discardable". That is, you don'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. > > Why? Because there are other types we would like to be implicitly > discardable. You can already make an argument for types like `Array<Void>`, > but concurrency will bring types like `Future<Void>` which could get pretty > strong benefits from it. Since we'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's pretty > natural to make ad-hoc discardibility a property attached to the type, too. > > (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.) > > [1]: https://github.com/apple/swift-evolution/blob/master/ > proposals/0047-nonvoid-warn.md#future-directions > [2]: https://github.com/apple/swift/blob/e907031d3d4555e917ca3ad7fffeac > 7f580331a0/lib/Sema/TypeCheckStmt.cpp#L991 > I am not sure this is entirely wise, for a few reasons. a) I sure don't know why you'd want to return `Void?`, but if you do, it doesn'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's the return type of a pure function that certainly shouldn't be discardable. b) Based on (a), I don't think that types composed of discardable types are therefore discardable. I need to think this through further. c) If you reject (b), then this brings up a larger issue. `@discardableResult` is an attribute of the function; here, you'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't want their return value to be discardable? Like, a `@nondiscardableResult func foo() -> Void? /* implicitly discardable type */`? I think this further demonstrates how it's not really the type but the function that we want to annotate. d) Does a class that override a `@discardable` type inherit that annotation? If not, they it's kind of a weird exception to the inheritance thing, no? If so, then we'd need a @nondiscardable annotation to do type-level overrides of @discardable. 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. 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 "discardable error"? Can we choose not to catch it?
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution