Sorry, my question at least has nothing to do with bikeshedding. I'm confused about why the proposal feels it's necessary to have both Type and Subtype. I don't understand Brent's two reasons and was hoping for some elaboration. I've tried to clarify my question in a gist:
https://gist.github.com/xwu/0cc2c8d358f1fdf066ba739bcd151167 On Fri, Sep 30, 2016 at 2:09 PM, Adrian Zubarev via swift-evolution < [email protected]> wrote: > About the proposed names: > > To be crystal clear we could use more descriptive names for our two types. > Today T.Type is referred as *metatype* and serving two different purposes > at once. > > 1. > > It’s a concrete type; we call it Type<T> or other suggested names > looked like ExactType<T>, StaticType<T> etc. > 2. > > T.Type is also the *base type* for all subtypes of T. > > Protocols has one exception here. > > 1.1. The concrete type for protocols is not T.Type but T.Protocol. > > 2.1. T.Protocol has only one supertype, which is the existential (#2) > Any.Type type. > > Our proposal slices this behaviour into two different types, where you > only can create a *concrete type* Type<T> with T.self or shadow a > concrete type behind Subtype<U> with subtype(of:) function. > > To be precise the correct names should be: > > - Metatype<T> for the concrete type (#1). > - ExistentialMetatype<T> for the existential type (#2). > > But we felt that we should adopt the existing name from T.Type and use > the short form for the *concrete type* Type<T>. > ------------------------------ > > Brent already showed in multiple examples but the question seems to come > up over and over about the correct name of the current type(of:) function. > > Imagine this scenario: > > protocol P {} > struct A : P {} > > let proto: P = A() > let any: Any = proto > > // the old behaviour looked like this > > // *concrete* `A.Type` is hidden behind the existential `Any.Type` > let anyMetatype: Any.Type = any.dynamicType > > anyMetatype is P.Type //=> true `P.Type` is the existential type here > anyMetatype is A.Type //=> true > let aMetatype = anyMetatype as! A.Type // Okay > > // today `type(of:)` does the same trick > > // After this proposal: > // subtype<T>(of instance: T) -> Subtype<T> > > // The function will extract `Type<A>` for `any` but shadow it behind > `Subtype<Any>` > let anyMetatype: `Subtype<Any>` = subtype(of: any) > > // The correct relationship look like this: > // Subtype<P> : Subtype<Any> > // Subtype<A> : Subtype<P> > // Type<A> : Subtype<A> > > anyMetatype is Subtype<P> //=> true > anyMetatype is Subtype<A> //=> true > anyMetatype is Type<A> //=> true > anyMetatype is Type<P> //=> false > anyMetatype is Type<Any> //=> false > let aMetatype_1 = anyMetatype as! Subtype<A> // Okay > let aMetatype_2 = anyMetatype as! Type<A> // Okay > > subtype(of:) function extracts the *concrete type* from the given > instance but shadows it behind the *existential type* equal to the type of > the given instance. > > subtype(of: T) returns a existential metatype instance Subtype<T> where > in reality it’s a concrete metatype Type<U> with the relationship like U > : T. > > This is exact the same behaviour as the old .dynamicType had. > > I hope that cleared some raising questions. > > > > -- > Adrian Zubarev > Sent with Airmail > > Am 30. September 2016 um 09:00:53, Goffredo Marocchi via swift-evolution ( > [email protected]) schrieb: > > Calling it SuperTypeOf<T> and SubTypeOf<T> would make it less confusing as > that is how I read it in my mind in your last example. > > > _______________________________________________ > swift-evolution mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-evolution > >
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
