[swift-evolution] [Pitch] Rename `x.dynamicType` to `x.Self`

Joe Groff jgroff at apple.com
Fri Apr 15 11:57:29 CDT 2016


> On Apr 14, 2016, at 12:29 PM, Dave Abrahams via swift-evolution <swift-evolution at swift.org> wrote:
> 
> 
> on Wed Apr 13 2016, Joe Groff <swift-evolution at swift.org> wrote:
> 
>> It's been pitched before, but I don't think we've had a dedicated
>> thread to this idea. Erica has proposed making `Self` generally
>> available within methods in types to refer to the dynamic type of the
>> current receiver. One could think of `Self` as a special associated
>> type member that exists in every type for this purpose. This also
>> happens to be what you get when ask for the `dynamicType` member of a
>> value. We could unify these concepts and get rid of the clunky
>> `dynamicType` keyword, replacing it with `x.Self`.
>> 
>> There's another benefit to this syntax change. Looking to the future,
>> one of the many features Doug pitched in his generics manifesto was to
>> generalize protocol existentials, lifting our current restrictions on
>> protocols "with Self or associated types" and allowing them to be used
>> as dynamic types in addition to static generic constraints. Once you
>> do this, you often want to "open" the type of the existential, so that
>> you can refer to its Self and associated types in the types of other
>> values. I think a natural way would be to let you directly use Self
>> and associated type members of existentials as types themselves, for
>> example:
>> 
>> 	let a: Equatable = /*...*/
>> 	let b: Equatable = /*...*/
>> 
>> 	// This is not allowed, since Equatable requires two values
>> with the same static type, but
>> 	// a and b may have different dynamic types.
>> 	a == b 
>> 
>> 	// However, we can dynamically cast one to the other's dynamic
>> type:
>> 	if let bAsA = b as? a.Self {
>> 		return a == bAsA
>> 	}
> 
> This doesn't entirely work, I think:
> 
>     class Z : Equatable {} // ...
>     class A : Z {}
>     class B : Z {}
> 
>     let a: Equatable = A()
>     let b: Equatable = B()
>     if let bAsA = b as? a.Self { ... } // test fails.
> 
> Of course, one could decide we don't care about classes conforming to
> protocols with Self requirements.

I see, I misread in my previous response. You're right this wouldn't necessarily just work. This is far from the only subtle issue with existentials containing subclasses, though; unfortunately there are two levels of dynamic type at play, and we're pretty inconsistent about keeping them, well, consistent. One approach here might be to try to always store the upper bound class as the existential-dynamic-type of the existential wrapper.

-Joe

>> 	let x: RangeReplaceableCollection = /*...*/
>> 	let y: Collection = /*...*/
>> 
>> 	// If y has the same dynamic Element type as x, append it to x
>> 	var z: x.Self = x
>> 	if let yAsX = y as? Any<Collection where Element == x.Element>
> 
> I don't think x.Element can work.  Do you mean x.Self.Element?
> 
>> 
>> { z.append(yAsX) }
>> 
>> `x.Self` then becomes just the first step in this direction.
>> 
>> -Joe
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> -- 
> Dave
> 
> _______________________________________________
> 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