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

Adrian Zubarev adrian.zubarev at devandartist.com
Sat Jul 16 08:14:32 CDT 2016


The problem with Mirror is that it can only carry a metatype around and thats it. You may be able to extract it from there and than what? You’ll cast it the old fashion way.

As I may recall I asked the community in the following thread about Hashable ability, which isn’t implementable without compiler magic and special internal protocols: [Discussion] Can we make .Type Hashable?

Your last API for Type<T> doesn’t solve any problems:

var size: Int { return sizeof(T.self) } is the wrong way to go.
If you extract a dynamic metatype from your Mirror, you still won’t be able to use Type<T> to calculate the right size for it. Not possible with such design.
Static properties do the same as instance properties. With this we could just leave MemoryLayout and don’t need Type<T> at all.
You’re talking about the lack of the ability of dispatching static members (you also forget initializer), which is not right. We don’t remove the ability to do so. It just gets a bottleneck property metatype.

I’m busy completing your last gist with all the mentioned facts. Here is the last portion I just finished:

Metatypes

Current metatypes T.Type have one additional feature that Type<T> will not have (directly). They can invoke static methods and initializer of types they reflect.

Thus, we cannot drop metatypes. But they will be renamed: old T.Type will become Metatype<T> and old internal T.self will become T.metatype, where the public T.self returns an instance of Type<T>.

Example in Swift 2.2:

protocol HasStatic   { static func staticMethod() -> String }
struct A : HasStatic { static func staticMethod() -> String { return "A" } }
struct B : HasStatic { static func staticMethod() -> String { return "B" } }

func callStatic(_ metatype: HasStatic.Type) {
    // `Type<T>` cannot do this, but there will be a  
    // bottleneck property `metatype` to achieve this.
    let result = metatype.staticMethod()   
    print(result)
}

let a = A.self
let b = B.self
callStatic(a)  //=> A
callStatic(b)  //=> B
In other words, metatypes (continue to) allow dynamic polymorphism for static methods.

After this proposal we will have two distinct ways to achieve the same result:

// Version 1:
func callStatic(_ metatype: Metatype<HasStatic>) {
    let result = metatype.staticMethod()   
    print(result)
}

let a = A.self.metatype
let b = B.self.metatype
callStatic(a)  //=> A
callStatic(b)  //=> B

// Version 2:
func callStatic(_ type: Type<HasStatic>) {
    let result = type.metatype.staticMethod()   
    print(result)
}

let a = Type<HasStatic>(casting: A.self)!
let b = Type<HasStatic>(casting: B.self)!
callStatic(a)  //=> A
callStatic(b)  //=> B
Everything is still possible, only the casting becomes a little clumsy. Therefore I’ll add section about dynamic casts such as as, as?, as! and is which needs a little tweaking. As I already showed in my last post. It’s totally safe to introduce this tweaking post Swift 3.

Please stay patient and let me finish the addition.



-- 
Adrian Zubarev
Sent with Airmail

Am 16. Juli 2016 um 14:19:08, Anton Zhilin (antonyzhilin at gmail.com) schrieb:

My suggestion 
#2
Allow labelless initialization of 
Mirror from metatype or from value
Move dynamic 
size, 
stride, 
alignment to 
Mirror

T.self and future type literals will create instances of 
Type<T>
struct Type<T> {
    init()

    var size: Int { return sizeof(T.self) }
    var stride: Int { return strideof(T.self) }
    var alignment: Int { return alignof(T.self) }
    static var size: Int { return sizeof(T.self) }
    static var stride: Int { return strideof(T.self) }
    static var alignment: Int { return alignof(T.self) }

    var metatype: Metatype<T> { return T.metatype }
    static var metatype: Metatype<T> { return T.metatype }

    // Nothing more; no fields!
}
Metatypes will be typically created using 
Type<T>.metatype and 
dynamicType

Pro Both static and dynamic 
size, 
stride, 
alignment are in logically suited contexts

Pro Metatypes (with which few people will work) are separated from static types (which are used for function specialization etc)

Con Additional entity 
Type<T>, but I think it’s the most elegant of all solutions that introduce additional types
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160716/8d8a9fef/attachment.html>


More information about the swift-evolution mailing list