This is certainly surprisingly behavior to me! +1 l8r Sean
> On Jun 23, 2016, at 2:53 PM, Slava Pestov via swift-evolution > <swift-evolution@swift.org> wrote: > > Consistent formal type for 'self' in class methods > > • Proposal: SE-9999 > • Author: Slava Pestov > • Status: Awaiting review > • Review manager: TBD > > Introduction > > This proposal makes the self value behave consistently whether or not it is > used from a method with a Self return type. > > Swift-evolution thread: Discussion thread topic for that proposal > > > Motivation > > Right now, we exhibit inconsistent behavior when self is used as an argument > to a generic function, violating the principle of least surprise. > > Consider the following code: > > class > Base { > > @discardableResult > > > func methodWithDynamicSelf() -> > Self { > doSomething( > self > ) > > return self > > } > > > func methodWithoutDynamicSelf > () { > doSomething( > self > ) > } > } > > > class Derived : > Base {} > > > func doSomething<T>(_ t > : T) { > > print(T.self > ) > } > > Base() > . > methodWithDynamicSelf() > Base() > . > methodWithoutDynamicSelf() > > Derived() > . > methodWithDynamicSelf() > Derived() > .methodWithoutDynamicSelf() > Currently, it prints the following output: > > Base > Base > Derived > Base > > Note that there's no inconsistency when the method is called on the base > class. When called on the derived class however, we see that in a method with > a dynamic Self return type, the type of self is Derived, whereas in a method > with any other return type, the type of self is Base. > > > Proposed solution > > The proposal is to change the type of self to always be Self, which can be > thought of as a special generic type parameter bound to the dynamic type of > the instance. > > With this proposal, the above code will instead produce the following: > > Base > Base > Derived > Derived > > Here, the type of self would always be Derived when called on an instance of > the derived class. > > Of course a more useful program could instead do something with the type > parameter T, such as constraining it to a protocol or a class with a required > initializer, and then using the type to construct a new instance of the class. > > This also dovetails nicely with SE-0068. > > Finally, it opens the door to generalizing dynamic Self, allowing it to > appear in covariant position within parameter types: > > class > ArtClass { > > func paint(withBrush: (Self) -> ()) { ... > } > } > > This would allow a class to conform to a protocol with a requirement written > like the following, something that is currently not possible at all: > > protocol > OddProtocol { > > func weaken<X, Y>((Self) -> > (X) -> Y) -> (X) -> Y > } > > > Detailed design > > There's really not much more to say here. The code for typing self with a > dynamic Self is in place already, however enabling this change might expose > some new bugs we have not yet encountered, because currently, methods with > dynamic Self return type are relatively rare. > > > Impact on existing code > > This will have a small impact on existing code that uses a pattern similar to > the above. > > > Alternatives considered > > One alternative is to simply do nothing, but this makes the language less > consistent than it could be. > > _______________________________________________ > 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