[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