[swift-evolution] [Discussion] Seal `T.Type` into `Type<T>`
Adrian Zubarev
adrian.zubarev at devandartist.com
Fri Jul 15 05:25:03 CDT 2016
Good morning everyone. Welcome to our discussion Brent.
There is nothing bad about Type<T> being a final class. To be honest I played with the idea of Type<T> being a class for optimization purposes, because it does feel like a performance drop if we had to instantiate tons of the same types (which may or may not be really heavy):
func dynamicType<T>(_ instance: T) -> Type<T>
let someHeavyViewController = …
dynamicType(someHeavyViewController)
dynamicType(someHeavyViewController)
dynamicType(someHeavyViewController)
dynamicType(someHeavyViewController)
dynamicType(someHeavyViewController)
With structs we would do the heavy work over and over again which can decrease our performance.
The reason why I dropped the class was because I though someone might subclass it, and I totally forgot about final.
If we had public final class Type<T> we can optimize the above example and return a reference to the specific Type<T> we already instantiated once.
Bikeshedding:
internal var _typeStore: [Int: Type<Any>] = [:]
extension Type {
internal static var sharedInstance: Type<T> {
let identifier = _uniqueIdentifierOf(Type<T>.metatype)
if let typeReference = Type<T>(casting: _typeStore[identifier]) {
return typeReference
}
let newType = Type<T>()
// downcast `T` to `Any` but still store `T` in `_underlyingMetatype`
if let downcastedType = Type<Any>(casting: newType) {
_typeStore[identifier] = downcastedType
}
return newType
}
}
Now we can use Type<T>.sharedInstance to instantiate it or just to return an existing instance.
I did some tweaking to the Type<T> api to make this work. I also filed a bug SR–2085 where Metatype<T> does not behave like T.Type which is strange. Furthermore the api uses a workaround T.Metatype (renamed T.Type).
init?(casting: Type<T>?) is now optional, to make sharedInstance work with the dictionary. This change doesn’t hurt at all.
I also implemented a check if T is Any to make downcasting to Any work as expected (T.self is Any.Type is the wrong way to go, because it’s always true no matter what). Took me a few hours to debug and fix these strange bugs.
You can check the (not compiling) gist here: https://gist.github.com/DevAndArtist/a5744f21107812b2d4e6baee2c55e0bf.
If anyone want me to implement a version that does compile, just let me know. It’s already possible, but I’ll have to use .self, .Type instead of .metatype and Metatype<T>.
--
Adrian Zubarev
Sent with Airmail
Am 15. Juli 2016 um 08:25:40, Brent Royal-Gordon (brent at architechies.com) schrieb:
> 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.
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 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)
--
Brent Royal-Gordon
Architechies
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160715/9d6af0e6/attachment.html>
More information about the swift-evolution
mailing list