> On 24 Jan 2017, at 01:03, Joe Groff via swift-evolution 
> <[email protected]> wrote:
> 
>> 
>> On Jan 23, 2017, at 4:00 PM, Matthew Johnson <[email protected] 
>> <mailto:[email protected]>> wrote:
>> 
>> 
>>> On Jan 23, 2017, at 5:52 PM, Joe Groff <[email protected] 
>>> <mailto:[email protected]>> wrote:
>>> 
>>>> 
>>>> On Jan 23, 2017, at 3:49 PM, Matthew Johnson <[email protected] 
>>>> <mailto:[email protected]>> wrote:
>>>> 
>>>> 
>>>> 
>>>> Sent from my iPad
>>>> 
>>>> On Jan 23, 2017, at 3:32 PM, Joe Groff via swift-evolution 
>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>> 
>>>>> This looks pretty good! It might be worth calling out explicitly that 
>>>>> matching a payloaded case by name alone still works, e.g.:
>>>>> 
>>>>> enum Foo { case foo(Int), bar(x: Int) }
>>>>> 
>>>>> switch Foo.foo(0) {
>>>>> case .foo:
>>>>>   break
>>>>> case .bar(x:):
>>>>>   break
>>>>> }
>>>> 
>>>> In your example would 'bar(x:)' be required or would a naked 'bar' also be 
>>>> valid?  I'm guessing it would not be valid which strikes me as slightly 
>>>> unfortunate.  This would create some unpleasant verbosity in some places 
>>>> that isn't required today.  (Incidentally, a nontrivial amount of this 
>>>> code would be in easily derivable "isSameCase" equivalence relations that 
>>>> compare the case used but not the associated values)
>>> 
>>> We're not terribly principled about this right now with non-pattern 
>>> declaration references. You can still reference an unapplied function by 
>>> its base name alone without its labels, if it's unambiguous:
>>> 
>>> func foo(x: Int, y: Int) {}
>>> 
>>> let foo_x_y: (Int, Int) -> () = foo
>>> 
>>> so it'd be consistent to continue to allow the same in pattern references.
>> 
>> Ok, if we follow this behavior then I am very much +1 on this direction.
>> 
>>> 
>>>> 
>>>> Another question - if labels become part of the case name does that mean 
>>>> we can "overload" the base name?
>>>> 
>>>> enum Foo {
>>>>    case bar(x: Int)
>>>>    case bar(y: Int)
>>>> }
>>>> 
>>>> The example is intentionally problematic because I'm not sure this would 
>>>> be a good idea, but more realistic examples may be possible with cases 
>>>> more meaningfully distinguished by associated value labels.  
>>>> 
>>>> This is an idea that naturally follows with a move to a more function-like 
>>>> model of enum cases with labels being part of the name so it's worth 
>>>> discussing whether or not it should be allowed.
>>> 
>>> Yeah, if labels really are part of the decl name then this isn't an 
>>> "overload" at all, so we should allow it.
>> 
>> Yeah, that’s why I put “overload” in quotes.  :)
>> 
>> If this proposal is accepted the compiler will have more flexibility for 
>> layout of enums with associated values.  Are there any other enum-related 
>> features that could impact the layout used (and therefore should be 
>> considered before ABI is locked down)?
>> 
>> For example, I’m thinking of the topic that seems to pop up fairly often 
>> related to enums that have several (or possibly all) cases sharing an 
>> associated value name and type, which are often viewed as conceptually 
>> similar to properties in the discussions that have happened.
> 
> Independent of that feature, laying out enums so that similar-shaped parts of 
> each payload overlap is a good general layout optimization, so that the 
> payload can be retain/released on copy with no or minimal switching over the 
> tag first.
> 
> -Joe
> _______________________________________________
> swift-evolution mailing list
> [email protected] <mailto:[email protected]>
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> <https://lists.swift.org/mailman/listinfo/swift-evolution>
I’ve wanted that for a long time :)

It’s not just retain/release, but in some cases also getting the payload. 
Imagine:

enum MyEnum {
    case someThing(String, Bool)
    case anotherThing(Int, Bool)
    case yetAnotherThing(Float, Bool)

    var verified: Bool {
        switch(self) {
            case .someThing(_, let v):       return v
            case .anotherThing(_, let v):    return v
            case .yetAnotherThing(_, let v): return v
        }
    }
}

The compiler could decide to lay the payload out as (Bool, <String or Int or 
Float>), and the switch statement doesn’t actually need to switch at all - it 
can just extract the Bool that is guaranteed to exist at position 0. Those 
kinds of optimisations are important for using enums in high-performance code.

- Karl


_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to