if-case syntax ambiguity


(Nicholas Outram) #1

Hi

I’ve been drilling down on the syntax of enumerated types with associated data in the current release version of Swift 3.
I’ve pasted below a section of a Playground that captures an issue I’d like to raise.

In summary:

Consider the following
enum Vehicle {
   case car(petrol: Bool, sizeCC: Int)
   case plane(engines : Int)
   case other(String)
   case none
}
let myJourney : Vehicle = .other("pogo stick")

Whereas the following is clear
if case .other(_) = myJourney

the following shorthand equivalent is potentially confusing for the sake of 3 characters
if case .other = myJourney

- In the first case, the presence of the underscore does communicate that something is being assigned, but dropped.
- In the second case, the reader could easily be mislead into thinking that = was supposed to be == as there no apparent place to assign anything.

My suggestion would simply be to drop the shorthand as it’s ambiguous?

Nick Outram

import Foundation

//: Consider the following enumerated type with associated data
enum Vehicle {
   case car(petrol: Bool, sizeCC: Int)
   case plane(engines : Int)
   case other(String)
   case none
}

//: Let's pick an example
let myJourney : Vehicle = .other("pogo stick")

//: I now want to test what case `myJourney` is.
//:
//: We cannot use the `==` operator because `Vehicle` has associated data. Instead we use `if case` and *simply drop the associated value* with `_` as shown above
if case .other(_) = myJourney {
   print("Somewhere nice?")
} else {
   print("Ok, it's a secret?")
}
//:The above is clear enough once you get used to the syntax. The `_` communicates that a value has been dropped.
//:
//: **However**, Swift 3 allows us to drop the parenthesis altogether and use the following shorthand:
if case .other = myJourney {
   print("Somewhere nice?")
} else {
   print("Ok, it's a secret?")
}
//: *Unlike the previous example, I do wonder if this is a language feature that needs review?*
//:
//: - On face value, reading this code as is there is an assignment operator `=` with nothing apparently being assigned.
//: - It also reads as if `=` should be `==`

EnumChangeSuggestion.playground.zip (11.5 KB)


(Zhao Xin) #2

The `if case` is the same meaning as `switch-case`, so I don't think there
is anything ambitious. For `switch-case`, it is not equal, it is matching.

Zhaoxin

···

On Wed, Nov 9, 2016 at 7:17 PM, Nicholas Outram via swift-users < swift-users@swift.org> wrote:

Hi

I’ve been drilling down on the syntax of enumerated types with associated
data in the current release version of Swift 3.
I’ve pasted below a section of a Playground that captures an issue I’d
like to raise.

In summary:

Consider the following
enum Vehicle {
   case car(petrol: Bool, sizeCC: Int)
   case plane(engines : Int)
   case other(String)
   case none
}
let myJourney : Vehicle = .other("pogo stick")

*Whereas the following is clear*
if case .other(_) = myJourney

*the following shorthand equivalent is potentially confusing for the sake
of 3 characters*
if case .other = myJourney

- In the first case, the presence of the underscore does communicate that
something is being assigned, but dropped.
- In the second case, the reader could easily be mislead into thinking
that = was supposed to be == as there no apparent place to assign anything.

My suggestion would simply be to drop the shorthand as it’s ambiguous?

Nick Outram

import Foundation

//: Consider the following enumerated type with associated data
enum Vehicle {
   case car(petrol: Bool, sizeCC: Int)
   case plane(engines : Int)
   case other(String)
   case none
}

//: Let's pick an example
let myJourney : Vehicle = .other("pogo stick")

//: I now want to test what case `myJourney` is.
//:
//: We cannot use the `==` operator because `Vehicle` has associated data.
Instead we use `if case` and *simply drop the associated value* with `_` as
shown above
if case .other(_) = myJourney {
   print("Somewhere nice?")
} else {
   print("Ok, it's a secret?")
}
//:The above is clear enough once you get used to the syntax. The `_`
communicates that a value has been dropped.
//:
//: **However**, Swift 3 allows us to drop the parenthesis altogether and
use the following shorthand:
if case .other = myJourney {
   print("Somewhere nice?")
} else {
   print("Ok, it's a secret?")
}
//: *Unlike the previous example, I do wonder if this is a language
feature that needs review?*
//:
//: - On face value, reading this code as is there is an assignment
operator `=` with nothing apparently being assigned.
//: - It also reads as if `=` should be `==`

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Michael Nisi) #3

Yes, equals isn't assignment but pattern matching here. Reminds of Erlang, which I love.

Michael

···

On 9 Nov 2016, at 12:57, Zhao Xin via swift-users <swift-users@swift.org> wrote:

The `if case` is the same meaning as `switch-case`, so I don't think there is anything ambitious. For `switch-case`, it is not equal, it is matching.

Zhaoxin

On Wed, Nov 9, 2016 at 7:17 PM, Nicholas Outram via swift-users <swift-users@swift.org> wrote:
Hi

I’ve been drilling down on the syntax of enumerated types with associated data in the current release version of Swift 3.
I’ve pasted below a section of a Playground that captures an issue I’d like to raise.

In summary:

Consider the following
enum Vehicle {
   case car(petrol: Bool, sizeCC: Int)
   case plane(engines : Int)
   case other(String)
   case none
}
let myJourney : Vehicle = .other("pogo stick")

Whereas the following is clear
if case .other(_) = myJourney

the following shorthand equivalent is potentially confusing for the sake of 3 characters
if case .other = myJourney

- In the first case, the presence of the underscore does communicate that something is being assigned, but dropped.
- In the second case, the reader could easily be mislead into thinking that = was supposed to be == as there no apparent place to assign anything.

My suggestion would simply be to drop the shorthand as it’s ambiguous?

Nick Outram

import Foundation

//: Consider the following enumerated type with associated data
enum Vehicle {
   case car(petrol: Bool, sizeCC: Int)
   case plane(engines : Int)
   case other(String)
   case none
}

//: Let's pick an example
let myJourney : Vehicle = .other("pogo stick")

//: I now want to test what case `myJourney` is.
//:
//: We cannot use the `==` operator because `Vehicle` has associated data. Instead we use `if case` and *simply drop the associated value* with `_` as shown above
if case .other(_) = myJourney {
   print("Somewhere nice?")
} else {
   print("Ok, it's a secret?")
}
//:The above is clear enough once you get used to the syntax. The `_` communicates that a value has been dropped.
//:
//: **However**, Swift 3 allows us to drop the parenthesis altogether and use the following shorthand:
if case .other = myJourney {
   print("Somewhere nice?")
} else {
   print("Ok, it's a secret?")
}
//: *Unlike the previous example, I do wonder if this is a language feature that needs review?*
//:
//: - On face value, reading this code as is there is an assignment operator `=` with nothing apparently being assigned.
//: - It also reads as if `=` should be `==`

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Nicholas Outram) #4

Thanks for that, it was really helpful. I see it now.

I’m happy to admit I had not fully appreciated the notion of pattern matching, and I very much doubt I'm alone either.

The Swift Programming book goes some way to explain it (in the language reference section) - maybe this is an area that needs some attention (from an educational perspective).

Many thanks for replying.

Nick

p.s. I looked up some Erlang examples - it did help

···

On 9 Nov 2016, at 12:50, Michael Nisi <michael.nisi@gmail.com> wrote:

Yes, equals isn't assignment but pattern matching here. Reminds of Erlang, which I love.

Michael

On 9 Nov 2016, at 12:57, Zhao Xin via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

The `if case` is the same meaning as `switch-case`, so I don't think there is anything ambitious. For `switch-case`, it is not equal, it is matching.

Zhaoxin

On Wed, Nov 9, 2016 at 7:17 PM, Nicholas Outram via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
Hi

I’ve been drilling down on the syntax of enumerated types with associated data in the current release version of Swift 3.
I’ve pasted below a section of a Playground that captures an issue I’d like to raise.

In summary:

Consider the following
enum Vehicle {
   case car(petrol: Bool, sizeCC: Int)
   case plane(engines : Int)
   case other(String)
   case none
}
let myJourney : Vehicle = .other("pogo stick")

Whereas the following is clear
if case .other(_) = myJourney

the following shorthand equivalent is potentially confusing for the sake of 3 characters
if case .other = myJourney

- In the first case, the presence of the underscore does communicate that something is being assigned, but dropped.
- In the second case, the reader could easily be mislead into thinking that = was supposed to be == as there no apparent place to assign anything.

My suggestion would simply be to drop the shorthand as it’s ambiguous?

Nick Outram

import Foundation

//: Consider the following enumerated type with associated data
enum Vehicle {
   case car(petrol: Bool, sizeCC: Int)
   case plane(engines : Int)
   case other(String)
   case none
}

//: Let's pick an example
let myJourney : Vehicle = .other("pogo stick")

//: I now want to test what case `myJourney` is.
//:
//: We cannot use the `==` operator because `Vehicle` has associated data. Instead we use `if case` and *simply drop the associated value* with `_` as shown above
if case .other(_) = myJourney {
   print("Somewhere nice?")
} else {
   print("Ok, it's a secret?")
}
//:The above is clear enough once you get used to the syntax. The `_` communicates that a value has been dropped.
//:
//: **However**, Swift 3 allows us to drop the parenthesis altogether and use the following shorthand:
if case .other = myJourney {
   print("Somewhere nice?")
} else {
   print("Ok, it's a secret?")
}
//: *Unlike the previous example, I do wonder if this is a language feature that needs review?*
//:
//: - On face value, reading this code as is there is an assignment operator `=` with nothing apparently being assigned.
//: - It also reads as if `=` should be `==`

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users