[swift-evolution] [Discussion] Seal `T.Type` into `Type<T>`

Anton Zhilin antonyzhilin at gmail.com
Fri Jul 15 04:28:22 CDT 2016


2016-07-15 9:25 GMT+03:00 Brent Royal-Gordon <brent at architechies.com>:

> > On Jul 14, 2016, at 6:33 PM, Anton Zhilin <antonyzhilin at gmail.com>
> wrote:
> >
> > And such a feature would look odd on a struct.
>
> But why would it be a struct? Types are obvious candidates to have
> identities; the type is the same "thing" everywhere it's referred to. Types
> don't have value semantics; if you perform a mutating operation on a type,
> that mutation is visible everywhere. Types (at least class types) have
> subtype relationships; structs can't express those.
>

Current plan is that Type<T> will contain T.Type that will do all the work
for us. Maybe it will be better to pour internals of T.Type directly into
Type<T> and make it a class?
Classes can't help here in terms of inheritance, because types will also
reflect subtyping relationships for protocols. Current plan is to use
methods instead of casts and subtyping behaviour of Type<T>.

I like the `Type<>` syntax, especially if it's something that could at
> least partially be written in the standard library (how nice would it be if
> we had `final class Type<Describing>` in the generated headers?), and I
> really like the idea of extending a metatype to conform to a protocol. But
> a lot of what's being discussed here, I just don't get. What's the benefit
> of switching to structs? Of removing type members?
>

I finally could understand what metatypes can do and Type<T> cannot, namely
dynamic dispatch of static/class methods.
If that usage is important enough, then I'm for leaving (sealed) T.Type
because of that feature.

> I don't see any problems with Type<Type<T>>. There is finite number of
> types that are used in the program, and compiler can collect and store
> information about them all statically. Am I right?
>
> Maybe not:
>
>         func recursivelyPrint<T>(type: T.Type, depth: Int) {
>                 print(type)
>                 guard depth > 0 else { return }
>                 recursivelyPrint(type: type.dynamicType, depth: depth - 1)
>         }
>         recursivelyPrint(type: Int.self, depth: 5)


Great example. But we can adapt it to tuples or any generic type:

typealias SomeGeneric<T> = (T, Int)
func wrap<T>(_ value: T) -> SomeGeneric<T>

func recursivelyPrint<T>(_ value: T, depth: Int) {
    print(type)
    guard depth > 0 else { return }
    recursivelyPrint(wrap(value), depth: delth - 1)
}

Currently, such code does not compile, because compiler can't create any
types dynamically, not only for SomeGeneric<T> = T.Type.
So this problem is not specific to Type<T>, and should not be solved
separately.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160715/542c0c71/attachment.html>


More information about the swift-evolution mailing list