[swift-evolution] [Pitch] Hashable types on RawRepresentable enums or a protocol for custom enum-like types

Adrian Zubarev adrian.zubarev at devandartist.com
Tue Oct 4 02:07:46 CDT 2016


There are still a lot of open questions here to solve.

How to statically guarantee the uniqueness + immutability of the hashValues?
Should we allow only the usage of an initializer?

Sometimes an init might be not enough and you’d wish you can use custom function which would return the same value for the same input you provide.

struct A : Hashable { … }
         
enum B : A {
    case a: A(someLabel: someInput)
    case b: createAFunction()
    case c: createA(with: someOtherInput)
}
Should we allow only value types here or how do we handle reference types?

A protocol to create custom enum-like types would be really interesting and useful. Instead of switch checking the value that conforms to that new protocol directly I’d suggest that we need some kind of an interface to satisfy and enable the enum-like switch usage (or maybe I’m totally wrong here).

protocol SomeFancyName : RawRepresentable {
    var interface: SomeType { get }
}

struct C : SomeFancyName { /* implement */ }

let c = C.someCase

switch c.interface {
     
case .someCase:
    // Handle
     
case .someOtherCase:
    // Handle
     
// No need for `default` when all cases are present
}
I couldn’t think up a simple and elegant model for such a protocol. Any suggestions is welcome.

Does the core team and the community feel this might have some potential future?

Does this impact the ABI somehow?



-- 
Adrian Zubarev
Sent with Airmail

Am 4. Oktober 2016 um 08:25:24, Rien (rien at balancingrock.nl) schrieb:

+1.  

I have several cases where I cannot use enums, this proposal would solve that.  


> On 03 Oct 2016, at 21:53, Adrian Zubarev via swift-evolution <swift-evolution at swift.org> wrote:  
>  
> I made a typo in my previous post.  
>  
> Bikeshdding with correct types:  
>  
> struct A : Hashable { /* implement everything */ }  
>  
> // Variant 1:  
> enum Test : A {  
> case something = A(value: "something")  
> case nothing = A(value: "nothing")  
> }  
>  
> // Variant 2:  
>  
> protocol SomeFancyName : RawRepresentable { … }  
>  
> struct Test : SomeFancyName {  
>  
> let rawValue: A  
> init?(rawValue: A) {  
> // Implement + reject unwanted `A`s  
> }  
>  
> static let something = Test(rawValue: A(value: "something"))  
> static let nothing = Test(rawValue: A(value: "nothing"))  
> }  
>  
> let value = Test.something  
>  
> switch value {  
>  
> case .something:  
> // handle  
>  
> case .nothing:  
> // handle  
>  
> // Because of `SomeFancyName` the switch can use enum-like pattern matching + does not need the `default` case when all cases are present  
> }  
>  
>  
>  
>  
> --  
> Adrian Zubarev  
> Sent with Airmail  
>  
> Am 3. Oktober 2016 um 21:50:07, Adrian Zubarev (adrian.zubarev at devandartist.com) schrieb:  
>  
>> Hi there,  
>>  
>> I’m interested if this idea has some potential future in Swift or not.  
>>  
>> Currently RawRepresentable enums accept only a subset of literal types like String, Character and the Integer family (enum Name : String { … }).  
>>  
>> Sometimes this is not enough for my use-case and I wish I could feed my enums with other Hashable types!  
>>  
>> As a workaround I can create a custom struct or even a class and conform it to RawRepresentable and fake an enum with some static variables (similar to what is done with OptionSet types).  
>>  
>> The problem there is that I cannot use the same switch pattern matching like with enums. I’d wish either enums could accept Hashable types (maybe with some restriction) or the existence on a protocol to build custom enum-like types with strucs/classes and use the same switch pattern matching.  
>>  
>> struct A : Hashable { /* implement everything */ }  
>>  
>> // Variant 1:  
>> enum Test : A {  
>> case something = A(rawValue: A(value: "something"))  
>> case nothing = A(rawValue: A(value: "nothing"))  
>> }  
>>  
>> // Variant 2:  
>>  
>> protocol SomeFancyName : RawRepresentable { … }  
>>  
>> struct Test : SomeFancyName {  
>>  
>> let rawValue: A  
>> init?(rawValue: A) {  
>> // Implement + reject unwanted `A`s  
>> }  
>>  
>> static let something = A(rawValue: A(value: "something"))  
>> static let nothing = A(rawValue: A(value: "nothing"))  
>> }  
>>  
>> let value = Test.something  
>>  
>> switch value {  
>>  
>> case .something:  
>> // handle  
>>  
>> case .nothing:  
>> // handle  
>>  
>> // Because of `SomeFancyName` the switch can use enum-like pattern matching + does not need the `default` case when all cases are present  
>> }  
>>  
>>  
>>  
>> --  
>> Adrian Zubarev  
>> Sent with Airmail  
>  
> _______________________________________________  
> swift-evolution mailing list  
> swift-evolution at swift.org  
> https://lists.swift.org/mailman/listinfo/swift-evolution  

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20161004/e67f4562/attachment.html>


More information about the swift-evolution mailing list