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 ([email protected]) 
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 ([email protected]) 
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 ([email protected]) 
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
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to