> On Sep 29, 2016, at 7:29 PM, Brent Royal-Gordon <br...@architechies.com> 
> wrote:
> 
>> On Sep 29, 2016, at 3:24 PM, Russ Bishop via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> 
>> Why would we not have type(of:) and subtype(of:)? Why would I want the 
>> Subtype<T> instead of the specific Type<T>?
> 
> Let's turn this around. Suppose you write:
> 
>       let obj: NSObject = …
>       let ty = type(of: obj)
> 
> What is `ty`? Well, it's a `Type<NSObject>`, and there's only one of those: 
> `NSObject.self`. So there's only one possible instance that could be assigned 
> to that variable.
> 
> This is true in general: If `type(of:)` returns `Type<T>`, then it can only 
> have one possible return value. In other words, the return value of 
> `type(of:)` would always be the *static* type of the variable, not its 
> dynamic type. There may be some narrow cases where that'd be useful, but 99% 
> of the time, you want `subtype(of:)` because you're trying to discover which 
> of many dynamic subtypes of the static type you're actually dealing with. So 
> most uses of `type(of:)` would probably be mistaken attempts to perform 
> `subtype(of:)` instead.
> 
>> What is the rationale for losing the meta type relationships by having 
>> Type<U> not be a subtype of Type<T>?
> 
> The relationships aren't lost; they're just expressed through `Subtype`, not 
> `Type`.
> 
> Again, turn this around. `Subtype` is the normal thing that you'll want to 
> use most of the time. `Type` is the weird thing whose existence is hard to 
> explain. (One version of this proposal used `Type` for `Subtype` and 
> `ExactType` for `Type` in order to imply that subtype is usually what you 
> want, but some of the contributors weren't happy with that.)
> 
> So, `Type` is the weird thing. Why does it exist? Two reasons:
> 
> 1. `Subtype<T>` only includes *inheritable* type members of `T`. `Type<T>` 
> also includes *non-inheritable* members, particularly non-required 
> initializers.
> 
> 2. It allows precise type matches: `subty is Subtype<NSObject>` would match 
> for any subtype of `NSObject`, whereas `subty is Type<NSObject>` would only 
> match for `NSObject` itself.
> 
> -- 
> Brent Royal-Gordon
> Architechies
> 

I understand what you’re getting at. 

This topic is confusing enough that I think it warrants being extremely clear 
about the naming. Type and Subtype feel like a class hierarchy and that’s not 
exactly what we are doing here. If Type<T> represents the static type of T then 
let’s just call it StaticType<T>. If the thing most people want to work with is 
the dynamic type Subtype<T> then let’s just call it that: DynamicType<T>.

Now this becomes really clear:

class A { }
class B: A { }

//clearly only ever represents A as a type
let metatype_1 = statictype(of: A())

//clearly might dynamically be A, B, or any subclass
let metatype_2 = dynamictype(of: A())


It also becomes trivially easy to explain because the name follows the 
explanation. Why can I only use required initializers on DynamicType<A>? 
Because we don’t know if the initializer is available; the dynamic type may 
differ at runtime. StaticType<A> knows exactly what is available on A because 
it is statically known at compile time.


Russ

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to