[swift-evolution] [Pitch] Make the formal type of 'self' consistent in class methods
Vladimir.S
svabox at gmail.com
Fri Jun 24 09:13:07 CDT 2016
+1. This should be fixed.
On 23.06.2016 22:53, Slava Pestov via swift-evolution 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
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
More information about the swift-evolution
mailing list