Struct or enum | Class | Protocol |
---|---|---|
struct S { } (A) |
class Base { } (B) |
protocol P { } (C) |
class Derived : Base { } (D) |
struct Impl : P { } (E) |
Currently, given func foo<T>(_ bar: T.Type) {...}
, T.Type
is one of (A), (B), (C) or (D) but not (E). A way of referring to (A), (B), (D) and (E) is desired.
The authors propose, in the same context, the following:
Type<T>
is (A), (B) and (C)Subtype<T>
is (A), (B), (D), (E)
Without bikeshedding names, what is the utility of having both Type
and Subtype
, which distinguish between (B) and (D)? The answer cannot be for exact matching, because it is possible to perform exact matching without the proposed Type
.
That is, given an instance d
of type Derived
, it is currently the case that type(of: d) != Base.self
. In the proposed syntax, this would be subtype(of: d) != Base.self
.
An alternative, simpler design which would address the stated motivating issues would be:
Type<T>
is (A), (B), (D), (E)Protocol<T>
is (C)
What benefits of distinguishing Type
and Subtype
cannot be captured by this simpler design?
I though I made it crystal clear in my last post what the main problem is.
Again:
T.Type
serves two jobs at once.T
.T
where other metatypes whereU
is a subtype ofT
(U : T
) are subtypes of this existential metatype.Forget about protocols for a moment:
It should be clear by now that there is this odd
T.Type : T.Type
relationship. We want to correct this behaviour + solve the problem that raises with protocols with one simple and single design.Let's see what happens with protocols:
There is a huge overlap in the current design. I hope this cleared your question here.
Side note: The following function isn't possible to implement with the current
T.Type
design because in generic context a protocol will end upT.Protocol
.The proposed design however solves these problems and the relationship becomes clearer:
The only way to work with
Subtype<T>
is by usingsubtype(of:)
function of by manually shadowing a concrete metatypeType<T>
.The only way to instantiate a concrete metatype is done with
T.self
.