One more thing to consider. If we had no Type<T> struct/class there would be no 
way to get the size of a dynamic metatype after SE–0101 and SE–0096.

func dynamicType(_ instance: T) -> Metatype<T>

MemoryLayout<??>.size
We can not check the size of T because then we might end up with the wrong size 
if Metatype<T> was downcasted from Metatype<U>.

Our current Type<T> solves that issue with instance properties which calculate 
the correct value for the dynamic metatype.



-- 
Adrian Zubarev
Sent with Airmail

Am 16. Juli 2016 um 11:57:33, Adrian Zubarev (adrian.zuba...@devandartist.com) 
schrieb:

Hmmmm, currently I’m inserting some changes and tweaks into your last gist 
update.

Metatypes are still in the language; it turned out that they must remain in the 
language
Type<T> wraps around metatypes and will provide better maintenance if ever 
needed, because metatype instantiation will be sealed to Type<T>.metatype or 
typeInstance.metatype.

The new primary Type<T> struct duplicates semantics and interface of metatypes.
True, but properties of a Type<T> instance work with a ‘dynamic’ metatype, 
which can be up- and downcased. However static properties are used for quick 
access and do only with the fixed metatype for T.

But it cannot get extensive native support, so it uses init?(casting:) instead 
of as cast, is(_:) method instead of is, etc.
I believe this is not a huge problem. I’m sure dynamic casts can be teched to 
work with with Type<T> instances. This can be purely additional and added after 
Swift 3.

class A {}
class B: A {}

// In Swift 3
let typeB: Type<B> = B.self
let typeA: Type<A>? = Type<A>(casting: typeB)
let anotherTypeA: Type<A> = Type<A>(casting: typeB)!

// Post Swift 3 - Easy migration and removing `init?(casting:)`
let typeA: Type<A>? = typeB as? Type<A>   
let anotherTypeA: Type<A> = typeB as! Type<A>   
Same for for is:

let typeB: Type<B> = B.self
typeB.`is`(A.self) // true

// Post Swift 3 - Easy migration and removing `func `is`(_:) -> Bool`
// Here the `is` cast extract `A` from `Type<A>` and checks the   
// metatype inside of `typeB` if it's compatible with `A`
typeB is Type<A> // true
The as dynamic cast needs additional teaching post Swift 3 without any regrets. 
Type<T> would be a special case for dynamic casts.

Type<T> does not add new possibilities right now, although the proposal 
promises to add reflection to Type<T> in the future.
This is my personal opinion, but we’d move SE–0101 into a better place tied 
side by side to the (dynamic) metatype. MemoryLayout doesn’t provide an 
instance of itself, it’s purely static.

An instance of Type<T> can be casted and we still can get nicely all the needed 
information and do not need to extract the dynamic metatype.

let typeB: Type<B> = B.self
let typeA: Type<A>? = Type<A>(casting: typeB)
let anotherTypeA: Type<A> = Type<A>(casting: typeB)!

typeB.size
typeA?.size
anotherTypeA.size
Mirror already does reflection. It wraps Any.Type statically, which is a 
simpler and more suitable model for reflection.
I can’t argue on that one. The only thing that I know and have a strong feeling 
about is that Any.Type is broken. There should be AnyMetatype and current 
Any.Type should be the metatype for Any returned from the current Any.self. The 
bug is mentioned in our proposal.

We should move reflection to possible future direction.

Rename metatypes T.Type to Type<T>
I don’t like .Type the way it is right now. T.Metatype makes more sense, which 
would implies (MHO) it should be called Metatype<T>. This is coved in our 
proposal.

Rename T.self to T
It’s not about renaming here. SE–0090 aims to drop .self completely. Okay we 
could go the same way like I already mentioned in some previous examples:

// Only renaming `T.Type` into `Metatype<T>`
let const1: Metatype<T> = T
let const2: T = T()
let const3: T = T.init()
let const4: SomeOtherType = T.staticMember

// My vision
let const1: Type<T> = T
let const2: T = T()
let const3: T = T.init()
let const4: SomeOtherType = T.staticMember
I asked the community if’s possible to make current T.Type conform to Hashable 
protocol. The response was positive, because this would be really handy.

Such a change would need more compiler magic or an internal protocol which I 
believe isn’t the best way to solve this. There I come up with the idea 
wrapping the metatype into a type called Type<T> and make the public T.self 
notation construct an instance of Type<T> instead.

Allow Type<Type<T>>
Already possible with our current Type<T>.

Extend Mirror for Swift 4
Maybe, but I would still tackle the proposal for Type<T>. Maybe we’ll find a 
solution which will suit everyone.

PS:

I’m updating your last gist and preparing two refactored up (possible) 
implementation.
I’ll need a few hours, because I’m not that fast. :)
Stay patient.


-- 
Adrian Zubarev
Sent with Airmail
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to