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

Adrian Zubarev adrian.zubarev at devandartist.com
Sat Jul 9 06:02:08 CDT 2016


Currently I could implement the whole type like this:

public struct Type<T> : Hashable, CustomStringConvertible, CustomDebugStringConvertible {
     
    // Anyone knows a better name?
    public let sealed: T.Type = T.self
     
    public let hashValue: Int = ObjectIdentifier(T.self).hashValue
     
    // Inspired by SE-0101
    public static var size: Int { return sizeof(T.self) }
    public static var stride: Int { return strideof(T.self) }
    public static var alignment: Int { return alignof(T.self) }
     
    public var size: Int { return Type<T>.size }
    public var stride: Int { return Type<T>.stride }
    public var alignment: Int { return Type<T>.alignment }
     
    public var description: String { return "Type<\(self.sealed)>" }
     
    public var debugDescription: String {
        return "<" + self.description + " size: \(self.size) stride: \(self.stride) alignment: \(self.alignment)>"
    }
}

public func ==<T, U>(lhs: Type<T>, rhs: Type<U>) -> Bool {
     
    return lhs.hashValue == rhs.hashValue
}
I also added static computed properties to access the the memory layout without any initialization.

Type<Int>.size reads really great to me.

I’m curious about the feedback from the Swift community. :)

PS: All my replies are markdown formatted. If anyone can’t read them, here is a formatted gist: https://gist.github.com/DevAndArtist/c35284ac12806c13eff302d1cf347ac8



-- 
Adrian Zubarev
Sent with Airmail

Am 9. Juli 2016 um 12:03:39, Adrian Zubarev (adrian.zubarev at devandartist.com) schrieb:

Correcting the function from the very first post:

public func ==<T, U>(lhs: Type<T>, rhs: Type<U>) -> Bool {
       
    return lhs.hashValue == rhs.hashValue
}


-- 
Adrian Zubarev
Sent with Airmail

Am 9. Juli 2016 um 11:55:00, Adrian Zubarev (adrian.zubarev at devandartist.com) schrieb:

Here are a few more thoughts on solving a few problems with dropped .self in mind:

Type<SomeType> cannot become Type<Type<SomeType>> to prevent infinite recursion.

Any other type without the short form for initializer SomeType(...) or explicit access to static members or initializer like SomeType.init(...) or SomeType.staticMember will be automatically become Type<SomeType> - if it’s not part of an array or dictionary shorthand syntax.

For array and dictionary shorthand syntax any type (except other nested array and dictionary shorthand types) does not follow the second rule from above (dropped .self in mind):

[SomeType]() equals Array<SomeType>()
[Type<SomeType>]() equals Array<Type<SomeType>>()
[SomeKeyType: SomeValueType]() equals Dictionary<SomeKeyType, SomeValueType>()
[Type<SomeKeyType>: Type<SomeValueType>]() equals Dictionary<Type<SomeKeyType>, Type<SomeValueType>>()
We also could extend Type<T> to provide more useful informations:

public struct Type<T> : Hashable, CustomStringConvertible, CustomDebugStringConvertible {
        
    // Anyone knows a better name?
    public let sealed: T.Type
        
    public var hashValue: Int { /* implement */ }
       
    // Inspired by SE-0101
    public var size: Int { /* implement */ }
    public var stride: Int { /* implement */ }
    public var alignment: Int { /* implement */ }
       
    public var description: String { /* implement */ }
       
    public var debugDescription: String { /* implement */ }
        
    public init() { /* implement */ }
}


-- 
Adrian Zubarev
Sent with Airmail

Am 8. Juli 2016 um 22:06:30, Adrian Zubarev (adrian.zubarev at devandartist.com) schrieb:

Hello Swift community, before Swift 3 drops I’d like to discuss if it is reasonable to consider to create a standalone type to drop/seal the T.Type magic?

However this change does not play well with the proposal of dropping the .self compiler magic.

Some bikeshedding:

public struct Type<T> : Hashable {
        
    // Seal the `.Type` magic into this standalone type.
    // Disallow `.Type` usage elsewhere
        
    public let sealed: T.Type
        
    public var hashValue: Int { /* implement somehow */ }
        
    public init() {
            
        // Or do it somehow different for the sake of dropping `.self` magic
        self.sealed = T.self
    }
}

public func ==<T>(lhs: Type<T>, rhs: Type<T>) -> Bool {
        
    return lhs.hashValue == rhs.hashValue
}
Downside of this approach is the accessibility of the .Type instance:

protocol Initializable {
    init()
}

func foo<T : Initializable>(type: Type<T>) -> T {
        
    // It would be nice if we could use `type.init()` instead, but than we
    // would need more compiler magic :/
    return type.sealed.init()
}
I couldn’t come up with a better name than sealed, if anyone has a better idea feel free to share your thoughts.

Remember this is a discussion and not (yet) a detailed proposal, where everyone can provide feedback and bikeshedding for a better design.



-- 
Adrian Zubarev
Sent with Airmail
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160709/f625774a/attachment.html>


More information about the swift-evolution mailing list