+1.  I have not encountered this issue myself but it looks like something that 
would cause a lot of head scratching if I had.  It is also something that I am 
unlikely to remember immediately if I run into it in the future.  The current 
behavior appears broken to me.  It will be great to have it fixed.

> On Jun 23, 2016, at 2:53 PM, Slava Pestov via swift-evolution 
> <[email protected]> wrote:
> 
> Consistent formal type for 'self' in class methods
> 
> Proposal: SE-9999 
> <https://github.com/slavapestov/swift-evolution/blob/self-formal-type-in-class/proposals/9999-self-formal-type-in-class.md>
> Author: Slava Pestov <https://github.com/slavapestov>
> Status: Awaiting review
> Review manager: TBD
> 
>  
> <https://github.com/slavapestov/swift-evolution/tree/self-formal-type-in-class#introduction>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 
> <http://news.gmane.org/gmane.comp.lang.swift.evolution>
>  
> <https://github.com/slavapestov/swift-evolution/tree/self-formal-type-in-class#motivation>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.
> 
> 
>  
> <https://github.com/slavapestov/swift-evolution/tree/self-formal-type-in-class#proposed-solution>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 
> <https://github.com/slavapestov/swift-evolution/blob/self-formal-type-in-class/proposals/0068-universal-self.md>.
> 
> 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
> }
> 
>  
> <https://github.com/slavapestov/swift-evolution/tree/self-formal-type-in-class#detailed-design>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.
> 
> 
>  
> <https://github.com/slavapestov/swift-evolution/tree/self-formal-type-in-class#impact-on-existing-code>Impact
>  on existing code
> 
> This will have a small impact on existing code that uses a pattern similar to 
> the above.
> 
> 
>  
> <https://github.com/slavapestov/swift-evolution/tree/self-formal-type-in-class#alternatives-considered>Alternatives
>  considered
> 
> One alternative is to simply do nothing, but this makes the language less 
> consistent than it could be.
> 
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to