[swift-evolution] [swift-evolution-announce] [Review] SE-0068: Expanding Swift Self to class members and value types
Michael Peternell
michael.peternell at gmx.at
Mon Apr 25 12:18:59 CDT 2016
Is "Self" dynamically dispatched? What would the following program print?
class A: NSObject {
static func myClassName() -> String {
return "A"
}
func hello() -> String {
return "I am a \(Self.myClassName())"
}
}
class B: A {
static func myClassName() -> String {
return "B"
}
}
print(B.init().hello())
Because I think "Self" would only cause confusion if it is statically dispatched. assert(B.init().hello() == "I am a B")
-Michael
> Am 25.04.2016 um 13:33 schrieb Vladimir.S via swift-evolution <swift-evolution at swift.org>:
>
> On 25.04.2016 4:57, Brent Royal-Gordon via swift-evolution wrote:
> >> https://github.com/apple/swift-evolution/blob/master/proposals/0068-universal-self.md
> >
> > I'm not totally clear what's being proposed here.
> >
> > Is this valid?
> > ...
>
> Yes, I'm also confused if it is a final proposal or some additions/changes are expected here? As we were also discussing #Self (in meaning "placeholder for name of current defining type", resolving at compilation time)
>
> Also, there were notes regarding this proposal by @Alex Martini<amartini at apple.com> 21.04.2016 18:58 (quoted below), with suggestion for "dynamictype" keyword / "dynamicType" standard library function.
>
> @Brent, your questions could be(in general) answered by replacing "Self" to "dynamicType", but actually there are more questions on this proposal, which I suggest to discuss.
>
> We have some mess *right now* with all these dynamicType/self/Self :
>
> * "self" in meaning of current instance reference (OK), dynamicType is dynamic type of the instance :
> class A { func f() { self.something() } }
> self.dynamicType is A
>
> * "self" in meaning of current type object in static/class methods, dynamicType is meta type
> class A { static func f() { self.something() } }
> self.dynamicType is A.Type
>
> * "Self" in meaning "placeholder to concrete defining class name" :
> protocol AProtocol { func assignFrom(a: Self) }
> class A : AProtocol { func assignFrom(a: A) {..} } // "A" here,not "Self"
>
> * "Self" in meaning of dynamic type in runtime:
> class A { func f() -> Self { return self } }
>
>
> I'd like to discuss how the following current code should looks in Swift 3.0 :
>
> ----------------------------
> protocol Proto {
> func z() -> Self
> func z(s: Self) // I propose the #Self here
> }
>
> class X: Proto {
> required init () {}
> func x() -> Self { return self.dynamicType.init() }
> func z() -> Self { return self }
> func z(s: X) {} // propose z(s: #Self) here
>
> static func staticF() -> Self {..} // shouldn't be #Self here?
> class func classF() -> Self {..}
> }
> ----------------------------
>
>
>
> "Notes from Swift core team 2016-04-20 design discussion" :
>
> On 21.04.2016 18:58, Alex Martini via swift-evolution wrote:
>>
>> SE-0068: Expanding Swift Self to class members and value types
>>
>> https://github.com/apple/swift-evolution/blob/master/proposals/0068-universal-self.md
>>
>> We have one keyword left in the language, dynamicType, which is camel
>> cased. This proposal renames it to Self instead.
>>
>> In a static function today, self.dynamicType will give you a metatype but
>> the non-member Self will not. The most useful reason to reference it is to
>> call an initializer. It makes accessing the metatype weirder. It’s
>> not Self.Type; that’s a type — you have to spell it Self.type.
>>
>> Quiz time! What do each of the permutations mean?
>>
>> Self.self
>> self.Self
>> Self.Self
>> self.self
>>
>> The number of capital letters gives you the level of meta-ness. This is
>> very subtle, which is probably not a good thing.
>>
>> Another approach would be to introduce a new dynamictype keyword that
>> doesn’t need to be accessed as a member of self, and keep Self the way it
>> is. Self should work in structs as a type alias.
>>
>> Why don’t we turn this into a standard library function? It’s not something
>> you need so often that the member access is very valuable. Putting it in
>> the standard library as dynamicType(_:) does still allow for that function
>> to be implemented using compiler magic.
>>
>> func dynamicType<T>(_: T) -> T.Type { }
>>
>> We have a proposal to remove .self on types. One reason .self exists is to
>> avoid the mistake of writing let x = Int — the compiler will give you a
>> weird type error later on in code if the value of x is what we today
>> call Int.self but you meant to call the Int() initializer. Creating a
>> metatype is not a common operation, so doing it explicitly is a good thing.
>>
>> It’s weird that you can use the metatype directly to construct something or
>> to do member access, but you can’t access it as a bare value.
>>
>> Coming back to this proposal, if we removed .self why would we want to
>> add .Self?
>>
>> If you have a variable whose value is a metatype, you also keep its name in
>> lower case. So Self makes a little less sense from that aspect too.
>>
>> Another perspective is that .dynamicType is just an implicitly synthesized
>> property on all type.
>>
>> We do have other keywords that follow the dot on
>> types, Int.Type and Fooable.Protocol, so this isn’t the only thing. Those
>> things are magic nested types.
>>
>> Subjectively, having dynamicType as a member feels weird.
>>
>> If .self goes away, the four-self example above is simplified,
>> and .Self doesn’t make sense anymore. There’s also the difference
>> that .Self would be a runtime thing.
>>
> _______________________________________________
> 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