[swift-evolution] [Pitch] Tweak `Self` and introduce `Current`

Xiaodi Wu xiaodi.wu at gmail.com
Sat Jan 7 11:41:43 CST 2017


On Sat, Jan 7, 2017 at 11:34 AM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:

> `Self` _always_ refers to the dynamic type of `self`. It just happens to
> be that in the case of structs the dynamic type is the same as the static
> type. The idea of having a shorthand for the containing type (spelled #Self
> or StaticSelf) was discussed during consideration of SE-0068. The accepted
> version of the proposal rejects that idea, having adopted the position that
> "You will continue to specify full type names for any other use. Joe Groff
> writes, 'I don't think it's all that onerous to have to write ClassName.foo
> if that's really what you specifically mean.'"
>

I should add, I say this because even though we have revisited proposals
after their acceptance on discovery of an unforeseen problem, IMO it's
highly disagreeable to try to reconsider an accepted proposal before it's
even been implemented on the basis of disagreeing with the conclusion of a
discussion that was already considered previously.

On Sat, Jan 7, 2017 at 11:14 AM, thislooksfun via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>> I like this idea, however, if I understand the proposal correctly, I
>> think that the naming would make more sense the other way around. `Self`
>> is, at least in my head, tied directly and statically to the enclosing
>> type, where as `Current` sounds more dynamic, and could change from
>> place-to-place.
>>
>> -thislooksfun (tlf)
>>
>> On Jan 7, 2017, at 4:38 AM, Adrian Zubarev via swift-evolution <
>> swift-evolution at swift.org> wrote:
>>
>> Hi Swift community,
>>
>> I’d like to talk to about current Self keyword. If I’m not totally
>> mistaken then the current Self has a few meanings:
>>
>>    1. Refer to the *current* type, or refer to the dynamic type for
>>    non-final classes inside containing type (SE–0068 - not yet implemented).
>>    2. For non-final class types use Self as return type on the
>>    conforming super type (or *return an instance of receiver Self*).
>>
>> Let me visualize the behaviors quickly in some short code snippet:
>>
>> protocol Foo {
>>     func foo(_ f: Self) -> Self
>> }
>>
>> class A : Foo {
>>     // forced to use `A` as parameter type and `Self` as return type
>>     func foo(_ f: A) -> Self { return self }
>>     // Returning `A()` would cause an error: Cannot convert return expression of type 'A' to return type 'Self'
>>     func bar() -> A { return A() /* or self */ }
>>     func zoo() -> Self { return /* only */ self }
>> }
>>
>> class B : A {
>>     // Both is fine `B` or `Self` as the return type
>>     // If `B` is used you can return a different instance like `B()`
>>     // `Self` does only allow `self` to be used here
>>     override func foo(_ f: A) -> B { return self }
>> }
>>
>> struct D : Foo {
>>     // No `Self` allowed here at all
>>     func foo(_ f: D) -> D { return self /* or D() */ }
>> }
>>
>> The behavior of Self is a little magical, because it sometimes refers to
>> the *current* type it is used in, or it has a contract of using self.
>> ------------------------------
>>
>> I propose of introducing a new keyword called Current to solve a few
>> problems here.
>>
>>    1.
>>
>>    Self on parameter types would be disallowed for protocol members,
>>    because conformances to that protocol already disallow that (see A above).
>>    Instead one would use Current and get the correct meaning.
>>
>>    protocol Boo {
>>        func boo(_ b: Current) -> Self
>>    }
>>
>>    procotol Loo {
>>        func loo() -> Current
>>    }
>>
>>    class X : Boo, Loo {
>>        func boo(_ b: X) -> Self { return self }
>>        func loo() -> X { return self /* or X() */ }
>>    }
>>
>>    final class Y : Boo {
>>        func boo(_ b: X) -> Y { return self /* or Y */ }
>>    }
>>
>>    2.
>>
>>    Using Self inside the containing type would always mean as one would
>>    refer to the dynamic type, like the magical syntax function type(of:)
>>    does.
>>    3.
>>
>>    Current can only refer to the current containing type.
>>    4.
>>
>>    On classes Self has always the contract of returning self.
>>    5.
>>
>>    Self could be discouraged in favor of Current on value types, as a
>>    shorthand to refer to the containing type.
>>    6.
>>
>>    Generics could benefit from Current too:
>>
>>    extension AReallyLongNonFinalClassName {
>>        func casted<T : Current>() -> T { ... }
>>    }
>>    // `Self` wouldn't here, because it would refer to the dynamic type
>>
>>
>> #1 Would affect a lot of protocols which implies that it would affect ABI.
>> ------------------------------
>>
>> These are the first ideas I had in my mind. We can polish it further if
>> it receives positive and constructive feedback.
>>
>> Best regards,
>>
>>
>>
>> --
>> Adrian Zubarev
>> Sent with Airmail
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170107/8057afd0/attachment.html>


More information about the swift-evolution mailing list