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 ([email protected]) 
schrieb:

> On Jul 14, 2016, at 6:33 PM, Anton Zhilin <[email protected]> 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  

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to