Re: [swift-evolution] Testing enum cases with associated values

2017-01-18 Thread Andy Chou via swift-evolution
I agree it’s overkill for what I’m really looking for, which is a simple way to 
get a Bool result from testing an enum against a specific case, without looking 
at the associated values.

Andy

> On Jan 18, 2017, at 10:15 AM, Tony Allevato  wrote:
> 
> FWIW, I'm not convinced that making enum values look like structs with 
> optional properties for the union of all their cases is a good idea. It's 
> certainly not something I would want added to all of my enums by default, and 
> it feels IMO like it's just an awkward hack around the fact that pattern 
> matching is a bit verbose in some scenarios because Swift doesn't provide a 
> case-expression to let you test/bind as part of a larger expression.
> 
> 
> On Wed, Jan 18, 2017 at 10:08 AM Andy Chou via swift-evolution 
> > wrote:
> That’s an interesting proposal. Here’s a link for reference:  
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160926/027287.html
>  
> 
> 
> The one thing is the proposed syntax doesn’t handle enum cases without 
> payloads. I think that could be handled by an optional Void, so this comment 
> in the original proposal:
> 
> > Only enum cases with a payload can be used with this syntax (it would make 
> > no sens for cases without a payload).
> 
> Would be changed to allow for empty payloads turning into Void?. For example:
> 
>> enum Result {
>> case success(Int)
>> case failure
>> }
>> 
>> let r: Result = foo()
>> 
>> let x: Int? = r.success
>> let y: Void? = r.failure
>> 
>> assert(r.success == Optional(42))
>> assert(r.failure == nil)
> I think it’s a reasonable compromise, though I still think it’s a bit awkward 
> for the common case. Looks like this is being postponed for now, so we’ll 
> have to live with the alternatives.
> 
> Andy
> 
> 
>> On Jan 18, 2017, at 12:20 AM, Anton Zhilin > > wrote:
>> 
>> AFAICS, Andy needs not default implementations of Equatable, but 
>> cases-as-optional-properties—this topic has also been discussed on the list.
>> 
>> enum Result {
>> case success(Int)
>> case failure(String)
>> }
>> 
>> let r: Result = foo()
>> 
>> let x: Int? = r.success
>> let y: String? = r.failure
>> 
>> assert(r.success == Optional(42))
>> assert(r.failure == nil)
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Testing enum cases with associated values

2017-01-18 Thread Tony Allevato via swift-evolution
FWIW, I'm not convinced that making enum values look like structs with
optional properties for the union of all their cases is a good idea. It's
certainly not something I would want added to all of my enums by default,
and it feels IMO like it's just an awkward hack around the fact that
pattern matching is a bit verbose in some scenarios because Swift doesn't
provide a case-expression to let you test/bind as part of a larger
expression.


On Wed, Jan 18, 2017 at 10:08 AM Andy Chou via swift-evolution <
swift-evolution@swift.org> wrote:

> That’s an interesting proposal. Here’s a link for reference:
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160926/027287.html
>
> The one thing is the proposed syntax doesn’t handle enum cases without
> payloads. I think that could be handled by an optional Void, so this
> comment in the original proposal:
>
> > Only enum cases with a payload can be used with this syntax (it would
> make no sens for cases without a payload).
>
> Would be changed to allow for empty payloads turning into Void?. For
> example:
>
> enum Result {
> case success(Int)
> case failure
> }
>
> let r: Result = foo()
>
> let x: Int? = r.success
> let y: Void? = r.failure
>
> assert(r.success == Optional(42))
> assert(r.failure == nil)
>
> I think it’s a reasonable compromise, though I still think it’s a bit
> awkward for the common case. Looks like this is being postponed for now, so
> we’ll have to live with the alternatives.
>
> Andy
>
>
> On Jan 18, 2017, at 12:20 AM, Anton Zhilin  wrote:
>
> AFAICS, Andy needs not default implementations of Equatable, but
> cases-as-optional-properties—this topic has also been discussed on the list.
>
> enum Result {
> case success(Int)
> case failure(String)
> }
>
> let r: Result = foo()
>
> let x: Int? = r.success
> let y: String? = r.failure
>
> assert(r.success == Optional(42))
> assert(r.failure == nil)
>
> ​
>
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Testing enum cases with associated values

2017-01-18 Thread Andy Chou via swift-evolution
That’s an interesting proposal. Here’s a link for reference:  
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160926/027287.html
 


The one thing is the proposed syntax doesn’t handle enum cases without 
payloads. I think that could be handled by an optional Void, so this comment in 
the original proposal:

> Only enum cases with a payload can be used with this syntax (it would make no 
> sens for cases without a payload).

Would be changed to allow for empty payloads turning into Void?. For example:

> enum Result {
> case success(Int)
> case failure
> }
> 
> let r: Result = foo()
> 
> let x: Int? = r.success
> let y: Void? = r.failure
> 
> assert(r.success == Optional(42))
> assert(r.failure == nil)
I think it’s a reasonable compromise, though I still think it’s a bit awkward 
for the common case. Looks like this is being postponed for now, so we’ll have 
to live with the alternatives.

Andy


> On Jan 18, 2017, at 12:20 AM, Anton Zhilin  wrote:
> 
> AFAICS, Andy needs not default implementations of Equatable, but 
> cases-as-optional-properties—this topic has also been discussed on the list.
> 
> enum Result {
> case success(Int)
> case failure(String)
> }
> 
> let r: Result = foo()
> 
> let x: Int? = r.success
> let y: String? = r.failure
> 
> assert(r.success == Optional(42))
> assert(r.failure == nil)

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Testing enum cases with associated values

2017-01-18 Thread Andy Chou via swift-evolution
This is nice, but it doesn’t solve the issue at hand because there is only one 
enum value. I would like to have something like:

if value == .TWO { … }

I can’t use this == operator for this because I’d have to create:

if value == .TWO(str) { … }

But I don’t have a specific str, and I want the condition to be true no matter 
what the value of str is.

Andy


> On Jan 17, 2017, at 10:53 PM, Rien  wrote:
> 
> A guy named Matthias recently commented this on my blog:
> 
> func == (left: Enum3, right: Enum3) -> Bool {
> switch (left, right) {
> case (.ONE, .ONE):
> return true
> case (.TWO(let str1), .TWO(let str2)):
> return str1 == str2
> default:
> return false
> }
> }
> 
> http://swiftrien.blogspot.nl/2015/05/swift-enum-compare-design-pattern.html
> 
> Regards,
> Rien
> 
> Site: http://balancingrock.nl
> Blog: http://swiftrien.blogspot.com
> Github: http://github.com/Swiftrien
> Project: http://swiftfire.nl
> 
> 
> 
> 
>> On 18 Jan 2017, at 01:15, Andy Chou via swift-evolution 
>>  wrote:
>> 
>> Enums with associated values can be very useful in Swift, but once you add 
>> associated values you lose some properties, especially equality:
>> 
>> ```
>> enum AuthenticationResponse {
>>   case success
>>   case alert(Alert)
>>   case reauthenticate
>> }
>> ```
>> 
>> Testing for a specific case requires a switch statement or the if pattern 
>> match syntax:
>> 
>>  if case .success = response { … }
>> 
>> But while this works well for control flow, it doesn’t work well for cases 
>> where we want a Bool, such as assert(). There are also common situations 
>> with lists and libraries like RxSwift where a filtering function uses a Bool 
>> valued closure. In these situations the best we can do is write functions 
>> like:
>> 
>> ```
>> enum AuthenticationResponse {
>>   case success
>>   case alert(Alert)
>>   case reauthenticate
>> 
>>   var isSuccess: Bool {
>>   if case .success = self {
>>   return true
>>   } else {
>>   return false
>>   }
>>   }
>> 
>>   var isReauthenticate: Bool {
>>   if case .reauthenticate = self {
>>   return true
>>   } else {
>>   return false
>>   }
>>   }
>> 
>>   var isAlert: Bool {
>>   if case .alert(_) = self {
>>   return true
>>   } else {
>>   return false
>>   }
>>   }
>> }
>> ```
>> Any suggestions better than writing out each of these functions explicitly?
>> 
>> The conditional conformances proposal coming in Swift 4 solves some of this 
>> issue, but not completely. If Alert isn’t Equatable, it is still useful to 
>> test whether the result is .success.  For example:
>> 
>>  assert(response == .success)
>> 
>> This is perfectly intelligible and I would argue that equality should be 
>> defined for enums with associated values omitted:
>> 
>>  assert(response == .alert)
>> 
>> Here we are ignoring the associated values, and merely checking if the enum 
>> case is the same.
>> 
>> Andy
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Testing enum cases with associated values

2017-01-18 Thread Pierre Monod-Broca via swift-evolution
The last time I was in this situation, I resolved it by having a shadow enum 
with the same cases but without any associated value.

I also created shadow enums for error enums. The shadow enum wouldn't have any 
associated value, and Int as RawValue, and I would also use it as an error code 
when converting to NSError.

But it's not really fun to maintain.

Pierre

> Le 18 janv. 2017 à 05:51, Andy Chou via swift-evolution 
>  a écrit :
> 
> I see your point about conformances. In my example, AuthenticationResponse 
> isn't a generic type, so the conformances spec won't apply.
> 
> I'll go out on a limb and say that 80%+ of the use cases for equality will be 
> to distinguish enum cases, not the associated values.
> 
> I do like your proposal though. In the thread talking about it someone 
> mentioned a 'derived' keyword to specify conformance and derivation 
> simultaneously. I like the idea of being able to say:
> 
>   enum AuthenticationResponse: derived Equatable { ... }
> 
> Still, even with derived conformance, it can still be very useful to be able 
> to test against specific enum cases when the associated values aren't 
> Equatable. Maybe this example would make it clearer:
> 
> ```
> enum OpaqueResponse {
>   case success(OpaqueResult)
>   case failure
> }
> ```
> 
> If OpaqueResult is from a library module and its implementation uses private 
> variables, it may not be easy to make it conform to Equatable. Yet, it would 
> be nice to be able to say:
> 
> ```
> let result: OpaqueResponse = request()
> if request == .failure  { ... }
> ```
> 
> A more realistic example comes from the world of Rx, where the original issue 
> I have came from:
> 
> ```
> let result: Observable = request()
> 
> result.filter { $0 == .failure } ...
> result.filter { $0 == .success } ...
> 
> // The best we can do today looks more like:
> result.filter { if case .failure = $0 { return true} else { return false } }
> result.filter { $0.isFailure }// but we have to define isFailure ourselves
> 
> // There's a similar issue with assertions
> if case .failure = result { assert(false) }
> assert({ if case .failure = result { return true } else { return false } }())
> ```
> 
> I agree it's less of an issue with test cases. The issue arises when we want 
> a Bool valued expression...
> 
> Andy
> 
>> On Jan 17, 2017, at 6:38 PM, Tony Allevato  wrote:
>> 
>> Conditional conformances doesn't solve enum equality though, because there 
>> likely won't be a way to utter "enum Foo : Equatable where > all associated value payloads are Equatable>" with the generics syntax 
>> that's available, and conformance alone wouldn't be able to derive the 
>> implementation. It'll require some work on the compiler's part to generate 
>> the right implementation—I mentioned a draft proposal I wrote a while back 
>> for auto-equality of enums and structs where all the components are 
>> equatable 
>>  in 
>> another thread, but as Robert mentioned, the missing piece is how users opt 
>> in/out of it.
>> 
>> If you just want to check the case of an enum in a test, what about this?
>> 
>> enum Foo {
>>   case bar
>>   case baz(Int)
>> }
>> let foo = Foo.baz(5)
>> guard case .baz = foo else { XCTFail("expected baz"); return }
>> 
>> The "return" being required isn't ideal because XCTFail doesn't return 
>> Never, but other than that it's not *horrible*. You can do whatever pattern 
>> matching you need to use or ignore associated values as part of your 
>> comparison.
>> 
>> 
>>> On Tue, Jan 17, 2017 at 5:59 PM Andy Chou via swift-evolution 
>>>  wrote:
>>> Yes, here's a reference to the conditional conformance proposal which was 
>>> accepted:
>>> 
>>> https://github.com/apple/swift-evolution/blob/master/proposals/0143-conditional-conformances.md
>>> 
>>> But as I mention in my post, there are cases it doesn't handle. 
>>> Specifically, when the associated types for an enum aren't equatable 
>>> themselves, it's still possible to define equality on the enum cases 
>>> without associated values.
>>> 
>>> Andy
>>> 
 On Jan 17, 2017, at 5:45 PM, Robert Widmann  
 wrote:
 
 Automatic “equatability” of aggregates that contain equatable members has 
 been discussed on this list quite a few times.  (I think I had a branch at 
 one point that was exploring this kind of deriving mechanism… It seems to 
 be lost to the sands of time).  Everybody seems to agree that it’s a 
 worthwhile feature, but there needs to be thought put into how it is 
 exposed to the end user.  e.g. Should we continue with silently 
 implementing these protocols if we can, or should there be some kind of 
 annotation to tell the compiler to only synthesize what the user wants?
 
> On Jan 17, 2017, at 7:15 PM, Andy Chou via 

Re: [swift-evolution] Testing enum cases with associated values

2017-01-18 Thread Anton Zhilin via swift-evolution
AFAICS, Andy needs not default implementations of Equatable, but
cases-as-optional-properties—this topic has also been discussed on the list.

enum Result {
case success(Int)
case failure(String)
}

let r: Result = foo()

let x: Int? = r.success
let y: String? = r.failure

assert(r.success == Optional(42))
assert(r.failure == nil)

​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Testing enum cases with associated values

2017-01-17 Thread Rien via swift-evolution
A guy named Matthias recently commented this on my blog:

func == (left: Enum3, right: Enum3) -> Bool {
switch (left, right) {
case (.ONE, .ONE):
return true
case (.TWO(let str1), .TWO(let str2)):
return str1 == str2
default:
return false
}
}

http://swiftrien.blogspot.nl/2015/05/swift-enum-compare-design-pattern.html

Regards,
Rien

Site: http://balancingrock.nl
Blog: http://swiftrien.blogspot.com
Github: http://github.com/Swiftrien
Project: http://swiftfire.nl




> On 18 Jan 2017, at 01:15, Andy Chou via swift-evolution 
>  wrote:
> 
> Enums with associated values can be very useful in Swift, but once you add 
> associated values you lose some properties, especially equality:
> 
> ```
> enum AuthenticationResponse {
>case success
>case alert(Alert)
>case reauthenticate
> }
> ```
> 
> Testing for a specific case requires a switch statement or the if pattern 
> match syntax:
> 
>   if case .success = response { … }
> 
> But while this works well for control flow, it doesn’t work well for cases 
> where we want a Bool, such as assert(). There are also common situations with 
> lists and libraries like RxSwift where a filtering function uses a Bool 
> valued closure. In these situations the best we can do is write functions 
> like:
> 
> ```
> enum AuthenticationResponse {
>case success
>case alert(Alert)
>case reauthenticate
> 
>var isSuccess: Bool {
>if case .success = self {
>return true
>} else {
>return false
>}
>}
> 
>var isReauthenticate: Bool {
>if case .reauthenticate = self {
>return true
>} else {
>return false
>}
>}
> 
>var isAlert: Bool {
>if case .alert(_) = self {
>return true
>} else {
>return false
>}
>}
> }
> ```
> Any suggestions better than writing out each of these functions explicitly?
> 
> The conditional conformances proposal coming in Swift 4 solves some of this 
> issue, but not completely. If Alert isn’t Equatable, it is still useful to 
> test whether the result is .success.  For example:
> 
>   assert(response == .success)
> 
> This is perfectly intelligible and I would argue that equality should be 
> defined for enums with associated values omitted:
> 
>   assert(response == .alert)
> 
> Here we are ignoring the associated values, and merely checking if the enum 
> case is the same.
> 
> Andy
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Testing enum cases with associated values

2017-01-17 Thread Andy Chou via swift-evolution

> if request == .failure  { ... }

Typo. It should read

if result == .failure { ... }

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Testing enum cases with associated values

2017-01-17 Thread Andy Chou via swift-evolution
I see your point about conformances. In my example, AuthenticationResponse 
isn't a generic type, so the conformances spec won't apply.

I'll go out on a limb and say that 80%+ of the use cases for equality will be 
to distinguish enum cases, not the associated values.

I do like your proposal though. In the thread talking about it someone 
mentioned a 'derived' keyword to specify conformance and derivation 
simultaneously. I like the idea of being able to say:

enum AuthenticationResponse: derived Equatable { ... }

Still, even with derived conformance, it can still be very useful to be able to 
test against specific enum cases when the associated values aren't Equatable. 
Maybe this example would make it clearer:

```
enum OpaqueResponse {
case success(OpaqueResult)
case failure
}
```

If OpaqueResult is from a library module and its implementation uses private 
variables, it may not be easy to make it conform to Equatable. Yet, it would be 
nice to be able to say:

```
let result: OpaqueResponse = request()
if request == .failure  { ... }
```

A more realistic example comes from the world of Rx, where the original issue I 
have came from:

```
let result: Observable = request()

result.filter { $0 == .failure } ...
result.filter { $0 == .success } ...

// The best we can do today looks more like:
result.filter { if case .failure = $0 { return true} else { return false } }
result.filter { $0.isFailure }// but we have to define isFailure ourselves

// There's a similar issue with assertions
if case .failure = result { assert(false) }
assert({ if case .failure = result { return true } else { return false } }())
```

I agree it's less of an issue with test cases. The issue arises when we want a 
Bool valued expression...

Andy

> On Jan 17, 2017, at 6:38 PM, Tony Allevato  wrote:
> 
> Conditional conformances doesn't solve enum equality though, because there 
> likely won't be a way to utter "enum Foo : Equatable where  all associated value payloads are Equatable>" with the generics syntax that's 
> available, and conformance alone wouldn't be able to derive the 
> implementation. It'll require some work on the compiler's part to generate 
> the right implementation—I mentioned a draft proposal I wrote a while back 
> for auto-equality of enums and structs where all the components are equatable 
>  > in 
> another thread, but as Robert mentioned, the missing piece is how users opt 
> in/out of it.
> 
> If you just want to check the case of an enum in a test, what about this?
> 
> enum Foo {
>   case bar
>   case baz(Int)
> }
> let foo = Foo.baz(5)
> guard case .baz = foo else { XCTFail("expected baz"); return }
> 
> The "return" being required isn't ideal because XCTFail doesn't return Never, 
> but other than that it's not *horrible*. You can do whatever pattern matching 
> you need to use or ignore associated values as part of your comparison.
> 
> 
> On Tue, Jan 17, 2017 at 5:59 PM Andy Chou via swift-evolution 
> > wrote:
> Yes, here's a reference to the conditional conformance proposal which was 
> accepted:
> 
> https://github.com/apple/swift-evolution/blob/master/proposals/0143-conditional-conformances.md
>  
> 
> 
> But as I mention in my post, there are cases it doesn't handle. Specifically, 
> when the associated types for an enum aren't equatable themselves, it's still 
> possible to define equality on the enum cases without associated values.
> 
> Andy
> 
>> On Jan 17, 2017, at 5:45 PM, Robert Widmann > > wrote:
>> 
>> Automatic “equatability” of aggregates that contain equatable members has 
>> been discussed on this list quite a few times.  (I think I had a branch at 
>> one point that was exploring this kind of deriving mechanism… It seems to be 
>> lost to the sands of time).  Everybody seems to agree that it’s a worthwhile 
>> feature, but there needs to be thought put into how it is exposed to the end 
>> user.  e.g. Should we continue with silently implementing these protocols if 
>> we can, or should there be some kind of annotation to tell the compiler to 
>> only synthesize what the user wants?
>> 
>>> On Jan 17, 2017, at 7:15 PM, Andy Chou via swift-evolution 
>>> > wrote:
>>> 
>>> Enums with associated values can be very useful in Swift, but once you add 
>>> associated values you lose some properties, especially equality:
>>> 
>>> ```
>>> enum AuthenticationResponse {
>>>   case success
>>>   case alert(Alert)
>>>   case reauthenticate
>>> }
>>> ```
>>> 
>>> Testing for a specific case requires a 

Re: [swift-evolution] Testing enum cases with associated values

2017-01-17 Thread Tony Allevato via swift-evolution
Conditional conformances doesn't solve enum equality though, because there
likely won't be a way to utter "enum Foo : Equatable where " with the generics
syntax that's available, and conformance alone wouldn't be able to derive
the implementation. It'll require some work on the compiler's part to
generate the right implementation—I mentioned a draft proposal I wrote a
while back for auto-equality of enums and structs where all the components
are equatable <
https://gist.github.com/allevato/2fd10290bfa84accfbe977d8ac07daad> in
another thread, but as Robert mentioned, the missing piece is how users opt
in/out of it.

If you just want to check the case of an enum in a test, what about this?

enum Foo {
  case bar
  case baz(Int)
}
let foo = Foo.baz(5)
guard case .baz = foo else { XCTFail("expected baz"); return }

The "return" being required isn't ideal because XCTFail doesn't return
Never, but other than that it's not *horrible*. You can do whatever pattern
matching you need to use or ignore associated values as part of your
comparison.


On Tue, Jan 17, 2017 at 5:59 PM Andy Chou via swift-evolution <
swift-evolution@swift.org> wrote:

> Yes, here's a reference to the conditional conformance proposal which was
> accepted:
>
>
> https://github.com/apple/swift-evolution/blob/master/proposals/0143-conditional-conformances.md
>
> But as I mention in my post, there are cases it doesn't handle.
> Specifically, when the associated types for an enum aren't equatable
> themselves, it's still possible to define equality on the enum cases
> without associated values.
>
> Andy
>
> On Jan 17, 2017, at 5:45 PM, Robert Widmann 
> wrote:
>
> Automatic “equatability” of aggregates that contain equatable members has
> been discussed on this list quite a few times.  (I think I had a branch at
> one point that was exploring this kind of deriving mechanism… It seems to
> be lost to the sands of time).  Everybody seems to agree that it’s a
> worthwhile feature, but there needs to be thought put into how it is
> exposed to the end user.  e.g. Should we continue with silently
> implementing these protocols if we can, or should there be some kind of
> annotation to tell the compiler to only synthesize what the user wants?
>
> On Jan 17, 2017, at 7:15 PM, Andy Chou via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> Enums with associated values can be very useful in Swift, but once you add
> associated values you lose some properties, especially equality:
>
> ```
> enum AuthenticationResponse {
>   case success
>   case alert(Alert)
>   case reauthenticate
> }
> ```
>
> Testing for a specific case requires a switch statement or the if pattern
> match syntax:
>
> if case .success = response { … }
>
> But while this works well for control flow, it doesn’t work well for cases
> where we want a Bool, such as assert(). There are also common situations
> with lists and libraries like RxSwift where a filtering function uses a
> Bool valued closure. In these situations the best we can do is write
> functions like:
>
> ```
> enum AuthenticationResponse {
>   case success
>   case alert(Alert)
>   case reauthenticate
>
>   var isSuccess: Bool {
>   if case .success = self {
>   return true
>   } else {
>   return false
>   }
>   }
>
>   var isReauthenticate: Bool {
>   if case .reauthenticate = self {
>   return true
>   } else {
>   return false
>   }
>   }
>
>   var isAlert: Bool {
>   if case .alert(_) = self {
>   return true
>   } else {
>   return false
>   }
>   }
> }
> ```
> Any suggestions better than writing out each of these functions explicitly?
>
> The conditional conformances proposal coming in Swift 4 solves some of
> this issue, but not completely. If Alert isn’t Equatable, it is still
> useful to test whether the result is .success.  For example:
>
> assert(response == .success)
>
> This is perfectly intelligible and I would argue that equality should be
> defined for enums with associated values omitted:
>
> assert(response == .alert)
>
> Here we are ignoring the associated values, and merely checking if the
> enum case is the same.
>
> Andy
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Testing enum cases with associated values

2017-01-17 Thread Robert Widmann via swift-evolution
This is distinct from conditional conformances (we could add this feature 
today).

~Robert Widmann

> On Jan 17, 2017, at 8:59 PM, Andy Chou  wrote:
> 
> Yes, here's a reference to the conditional conformance proposal which was 
> accepted:
> 
> https://github.com/apple/swift-evolution/blob/master/proposals/0143-conditional-conformances.md
>  
> 
> 
> But as I mention in my post, there are cases it doesn't handle. Specifically, 
> when the associated types for an enum aren't equatable themselves, it's still 
> possible to define equality on the enum cases without associated values.
> 
> Andy
> 
>> On Jan 17, 2017, at 5:45 PM, Robert Widmann > > wrote:
>> 
>> Automatic “equatability” of aggregates that contain equatable members has 
>> been discussed on this list quite a few times.  (I think I had a branch at 
>> one point that was exploring this kind of deriving mechanism… It seems to be 
>> lost to the sands of time).  Everybody seems to agree that it’s a worthwhile 
>> feature, but there needs to be thought put into how it is exposed to the end 
>> user.  e.g. Should we continue with silently implementing these protocols if 
>> we can, or should there be some kind of annotation to tell the compiler to 
>> only synthesize what the user wants?
>> 
>>> On Jan 17, 2017, at 7:15 PM, Andy Chou via swift-evolution 
>>> > wrote:
>>> 
>>> Enums with associated values can be very useful in Swift, but once you add 
>>> associated values you lose some properties, especially equality:
>>> 
>>> ```
>>> enum AuthenticationResponse {
>>>   case success
>>>   case alert(Alert)
>>>   case reauthenticate
>>> }
>>> ```
>>> 
>>> Testing for a specific case requires a switch statement or the if pattern 
>>> match syntax:
>>> 
>>> if case .success = response { … }
>>> 
>>> But while this works well for control flow, it doesn’t work well for cases 
>>> where we want a Bool, such as assert(). There are also common situations 
>>> with lists and libraries like RxSwift where a filtering function uses a 
>>> Bool valued closure. In these situations the best we can do is write 
>>> functions like:
>>> 
>>> ```
>>> enum AuthenticationResponse {
>>>   case success
>>>   case alert(Alert)
>>>   case reauthenticate
>>> 
>>>   var isSuccess: Bool {
>>>   if case .success = self {
>>>   return true
>>>   } else {
>>>   return false
>>>   }
>>>   }
>>> 
>>>   var isReauthenticate: Bool {
>>>   if case .reauthenticate = self {
>>>   return true
>>>   } else {
>>>   return false
>>>   }
>>>   }
>>> 
>>>   var isAlert: Bool {
>>>   if case .alert(_) = self {
>>>   return true
>>>   } else {
>>>   return false
>>>   }
>>>   }
>>> }
>>> ```
>>> Any suggestions better than writing out each of these functions explicitly?
>>> 
>>> The conditional conformances proposal coming in Swift 4 solves some of this 
>>> issue, but not completely. If Alert isn’t Equatable, it is still useful to 
>>> test whether the result is .success.  For example:
>>> 
>>> assert(response == .success)
>>> 
>>> This is perfectly intelligible and I would argue that equality should be 
>>> defined for enums with associated values omitted:
>>> 
>>> assert(response == .alert)
>>> 
>>> Here we are ignoring the associated values, and merely checking if the enum 
>>> case is the same.
>>> 
>>> Andy
>>> 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org 
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Testing enum cases with associated values

2017-01-17 Thread Andy Chou via swift-evolution
Yes, here's a reference to the conditional conformance proposal which was 
accepted:

https://github.com/apple/swift-evolution/blob/master/proposals/0143-conditional-conformances.md
 


But as I mention in my post, there are cases it doesn't handle. Specifically, 
when the associated types for an enum aren't equatable themselves, it's still 
possible to define equality on the enum cases without associated values.

Andy

> On Jan 17, 2017, at 5:45 PM, Robert Widmann  wrote:
> 
> Automatic “equatability” of aggregates that contain equatable members has 
> been discussed on this list quite a few times.  (I think I had a branch at 
> one point that was exploring this kind of deriving mechanism… It seems to be 
> lost to the sands of time).  Everybody seems to agree that it’s a worthwhile 
> feature, but there needs to be thought put into how it is exposed to the end 
> user.  e.g. Should we continue with silently implementing these protocols if 
> we can, or should there be some kind of annotation to tell the compiler to 
> only synthesize what the user wants?
> 
>> On Jan 17, 2017, at 7:15 PM, Andy Chou via swift-evolution 
>>  wrote:
>> 
>> Enums with associated values can be very useful in Swift, but once you add 
>> associated values you lose some properties, especially equality:
>> 
>> ```
>> enum AuthenticationResponse {
>>   case success
>>   case alert(Alert)
>>   case reauthenticate
>> }
>> ```
>> 
>> Testing for a specific case requires a switch statement or the if pattern 
>> match syntax:
>> 
>>  if case .success = response { … }
>> 
>> But while this works well for control flow, it doesn’t work well for cases 
>> where we want a Bool, such as assert(). There are also common situations 
>> with lists and libraries like RxSwift where a filtering function uses a Bool 
>> valued closure. In these situations the best we can do is write functions 
>> like:
>> 
>> ```
>> enum AuthenticationResponse {
>>   case success
>>   case alert(Alert)
>>   case reauthenticate
>> 
>>   var isSuccess: Bool {
>>   if case .success = self {
>>   return true
>>   } else {
>>   return false
>>   }
>>   }
>> 
>>   var isReauthenticate: Bool {
>>   if case .reauthenticate = self {
>>   return true
>>   } else {
>>   return false
>>   }
>>   }
>> 
>>   var isAlert: Bool {
>>   if case .alert(_) = self {
>>   return true
>>   } else {
>>   return false
>>   }
>>   }
>> }
>> ```
>> Any suggestions better than writing out each of these functions explicitly?
>> 
>> The conditional conformances proposal coming in Swift 4 solves some of this 
>> issue, but not completely. If Alert isn’t Equatable, it is still useful to 
>> test whether the result is .success.  For example:
>> 
>>  assert(response == .success)
>> 
>> This is perfectly intelligible and I would argue that equality should be 
>> defined for enums with associated values omitted:
>> 
>>  assert(response == .alert)
>> 
>> Here we are ignoring the associated values, and merely checking if the enum 
>> case is the same.
>> 
>> Andy
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Testing enum cases with associated values

2017-01-17 Thread Robert Widmann via swift-evolution
Automatic “equatability” of aggregates that contain equatable members has been 
discussed on this list quite a few times.  (I think I had a branch at one point 
that was exploring this kind of deriving mechanism… It seems to be lost to the 
sands of time).  Everybody seems to agree that it’s a worthwhile feature, but 
there needs to be thought put into how it is exposed to the end user.  e.g. 
Should we continue with silently implementing these protocols if we can, or 
should there be some kind of annotation to tell the compiler to only synthesize 
what the user wants?

> On Jan 17, 2017, at 7:15 PM, Andy Chou via swift-evolution 
>  wrote:
> 
> Enums with associated values can be very useful in Swift, but once you add 
> associated values you lose some properties, especially equality:
> 
> ```
> enum AuthenticationResponse {
>case success
>case alert(Alert)
>case reauthenticate
> }
> ```
> 
> Testing for a specific case requires a switch statement or the if pattern 
> match syntax:
> 
>   if case .success = response { … }
> 
> But while this works well for control flow, it doesn’t work well for cases 
> where we want a Bool, such as assert(). There are also common situations with 
> lists and libraries like RxSwift where a filtering function uses a Bool 
> valued closure. In these situations the best we can do is write functions 
> like:
> 
> ```
> enum AuthenticationResponse {
>case success
>case alert(Alert)
>case reauthenticate
> 
>var isSuccess: Bool {
>if case .success = self {
>return true
>} else {
>return false
>}
>}
> 
>var isReauthenticate: Bool {
>if case .reauthenticate = self {
>return true
>} else {
>return false
>}
>}
> 
>var isAlert: Bool {
>if case .alert(_) = self {
>return true
>} else {
>return false
>}
>}
> }
> ```
> Any suggestions better than writing out each of these functions explicitly?
> 
> The conditional conformances proposal coming in Swift 4 solves some of this 
> issue, but not completely. If Alert isn’t Equatable, it is still useful to 
> test whether the result is .success.  For example:
> 
>   assert(response == .success)
> 
> This is perfectly intelligible and I would argue that equality should be 
> defined for enums with associated values omitted:
> 
>   assert(response == .alert)
> 
> Here we are ignoring the associated values, and merely checking if the enum 
> case is the same.
> 
> Andy
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution