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

Adrian Zubarev adrian.zubarev at devandartist.com
Fri Jul 15 09:21:18 CDT 2016


If it’s possible to drop T.Metatype, sure why not to make it Metatype<T>, but I have no idea hod the core team will build this. We should consider typealias Metatype<T> = T.Metatype as an alternative implementation, but tackle for Metatype<T>.

Can you provide a full example?

let type = Type<Base>(casting: Derived)

// `type` is the same as this, where we know that `Derived` can be `Base`:
let derived = Type<Derived>()
let base = unsafeBitCast(derived, to: Type<Base>)
The global dictionary contains only the dynamicTypes which were instantiated through Type<T>.sharedInstance or dynamicType(someInstance) function.

let derived: Any = Derived()
let type = dynamicType(derived) // Type<Any>

// I'll refer to current syntax here
type.metatype is Derived.Type // true
type.metatype is Base.Type // true
That example showed me that public var metatype need a fix:

public var metatype: Metatype<T> {
    // `_underlyingMetatype` is of type `T.Type` but stored in `Any.Type`
    // we can sefely cast it back to `T.Type`
    return unsafeBitCast(self._underlyingMetatype, to: Metatype<T>)
}
I just realized what causes the SR–2085 bug I mentioned earlier.

Any.Type is not the metatype of Any
Any.Type means that this ‘thing’ can store any metatype
There is no type that expresses metatype for Any
We still can get the metatype for Any through Any.self
I updated SR–2085 and suggested that we need AnyMetatype.

I’ll update the implementation gist.



-- 
Adrian Zubarev
Sent with Airmail

Am 15. Juli 2016 um 13:26:26, Anton Zhilin (antonyzhilin at gmail.com) schrieb:

OK, then, I guess, Swift can create type metainfo at runtime, and it must work for Type<T>, as well. I'd appreciate this feature.

Next, I don't really like the following:
I’d rename T.Type to T.Metatype and produce typealias Metatype<T> = T.Metatype

Furthermore T.Metatype would be disallowed in declarations for the sake of Metatype<T>

Why not remove T.Metatype then? Metatype<T> will be a special data type that supports referring to static members of T.

Next, from "Bikeshedding". The global dictionary will only be able to contain default-constructed Type<T> values, but not such as Type<Base>(casting: Derived.self). How do you deal with those?

2016-07-15 13:47 GMT+03:00 Adrian Zubarev via swift-evolution <swift-evolution at swift.org>:
Challenge accepted: Fixing your code to make it compile.

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

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

recursivelyPrint(2.0, depth: 5)

//////////// Output
2.0
(2.0, 42)
((2.0, 42), 42)
(((2.0, 42), 42), 42)
((((2.0, 42), 42), 42), 42)
(((((2.0, 42), 42), 42), 42), 42)
Technically Type<T> should be able to reflect other Type<T>’s. There is nothing wrong about it.

let var1 = Int       // Type: Type<Int>
let var2 = Int()     // Type: Int
let var2 = Type<Int> // Type: Type<Type<Int>> where the metatype inside will be `Type<Int>.Type`
As you can see there won’t be any implicit infinite recursion.



-- 
Adrian Zubarev
Sent with Airmail

Am 15. Juli 2016 um 12:25:10, Adrian Zubarev (adrian.zubarev at devandartist.com) schrieb:

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

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


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160715/bb5c0990/attachment.html>


More information about the swift-evolution mailing list