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

Joe Groff jgroff at apple.com
Thu Apr 14 14:57:37 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 don't see the problem. B is-an A, so equating an A to a B is equating an A to an A (from the conformance's perspective, Self == A). A() == B() works by the same principle.

>> 	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?

TBD, when we get there, but requiring `x.Self.Element` doesn't seem necessary to me.


More information about the swift-evolution mailing list