Forgive me if this was/is discussed already, I am new to the process
here....
(code is attached as a playground too)
Sometimes when I am working with a String? nil can be a reasonable value,
and what I want to do is something like the following:
import UIKit
var str:String? = "Hello, playground"
switch str{
case nil:
print("Nil!")
case "Hello, playground": //it would be super nice if this worked.
print("Match")
default:
print("Some other non nil value?")
}
But it does not work, the orange text is a compile time error, "Expression
pattern of type 'String' cannot match value of type 'String?'. I realize
that this can be replaced with a let statement (case let s where s == "Hello,
playground":), but that is verbose.
Seems like the compiler could be OK with the orange text, since it is
clearly not nil.
On Jun 28, 2016, at 06:40, Lucas Jordan via swift-evolution <swift-evolution@swift.org> wrote:
Forgive me if this was/is discussed already, I am new to the process here....
(code is attached as a playground too)
Sometimes when I am working with a String? nil can be a reasonable value, and what I want to do is something like the following:
import UIKit
var str:String? = "Hello, playground"
switch str{
case nil:
print("Nil!")
case "Hello, playground": //it would be super nice if this worked.
print("Match")
default:
print("Some other non nil value?")
}
But it does not work, the orange text is a compile time error, "Expression pattern of type 'String' cannot match value of type 'String?'. I realize that this can be replaced with a let statement (case let s where s == "Hello, playground":), but that is verbose.
Seems like the compiler could be OK with the orange text, since it is clearly not nil.
On Tuesday, June 28, 2016, Kevin Nattinger via swift-evolution < swift-evolution@swift.org> wrote:
Case .none:
Case .some("string"):
On Jun 28, 2016, at 06:40, Lucas Jordan via swift-evolution < > swift-evolution@swift.org > <javascript:_e(%7B%7D,'cvml','swift-evolution@swift.org');>> wrote:
Forgive me if this was/is discussed already, I am new to the process
here....
(code is attached as a playground too)
Sometimes when I am working with a String? nil can be a reasonable value,
and what I want to do is something like the following:
import UIKit
var str:String? = "Hello, playground"
switch str{
case nil:
print("Nil!")
case "Hello, playground": //it would be super nice if this worked.
print("Match")
default:
print("Some other non nil value?")
}
But it does not work, the orange text is a compile time error,
"Expression pattern of type 'String' cannot match value of type 'String?'.
I realize that this can be replaced with a let statement (case let s where
s == "Hello, playground":), but that is verbose.
Seems like the compiler could be OK with the orange text, since it is
clearly not nil.
7> switch str {
8. case "foo": print("case foo")
9. case .none: print("(nil)")
10. }
error: repl.swift:8:6: error: value of optional type 'String?' not unwrapped; did you mean to use '!' or '?'?
case "foo": print("case foo")
^
!
Odd error, but at least it suggests it’s an issue with optionaity.
···
On Jun 28, 2016, at 9:27 AM, Nevin Brackett-Rozinsky <nevin.brackettrozinsky@gmail.com> wrote:
Does `case "text"?` work?
On Tuesday, June 28, 2016, Kevin Nattinger via swift-evolution <swift-evolution@swift.org> wrote:
Case .none:
Case .some("string"):
On Jun 28, 2016, at 06:40, Lucas Jordan via swift-evolution <swift-evolution@swift.org> wrote:
Forgive me if this was/is discussed already, I am new to the process here....
(code is attached as a playground too)
Sometimes when I am working with a String? nil can be a reasonable value, and what I want to do is something like the following:
import UIKit
var str:String? = "Hello, playground"
switch str{
case nil:
print("Nil!")
case "Hello, playground": //it would be super nice if this worked.
print("Match")
default:
print("Some other non nil value?")
}
But it does not work, the orange text is a compile time error, "Expression pattern of type 'String' cannot match value of type 'String?'. I realize that this can be replaced with a let statement (case let s where s == "Hello, playground":), but that is verbose.
Seems like the compiler could be OK with the orange text, since it is clearly not nil.
This is sort of weird right? because comparing nil to a non nil string is a
reasonable thing to do:
var nilString:String? = nil
if nilString == "this always fails" {}
is totally reasonable.
···
On Tue, Jun 28, 2016 at 12:33 PM, Kevin Nattinger <swift@nattinger.net> wrote:
No
7> switch str {
8. case "foo": print("case foo")
9. case .none: print("(nil)")
10. }
error: repl.swift:8:6: error: value of optional type 'String?' not
unwrapped; did you mean to use '!' or '?'?
case "foo": print("case foo")
^
!
Odd error, but at least it suggests it’s an issue with optionaity.
On Jun 28, 2016, at 9:27 AM, Nevin Brackett-Rozinsky < > nevin.brackettrozinsky@gmail.com> wrote:
Does `case "text"?` work?
On Tuesday, June 28, 2016, Kevin Nattinger via swift-evolution < > swift-evolution@swift.org> wrote:
Case .none:
Case .some("string"):
On Jun 28, 2016, at 06:40, Lucas Jordan via swift-evolution < > swift-evolution@swift.org> wrote:
Forgive me if this was/is discussed already, I am new to the process
here....
(code is attached as a playground too)
Sometimes when I am working with a String? nil can be a reasonable value,
and what I want to do is something like the following:
import UIKit
var str:String? = "Hello, playground"
switch str{
case nil:
print("Nil!")
case "Hello, playground": //it would be super nice if this worked.
print("Match")
default:
print("Some other non nil value?")
}
But it does not work, the orange text is a compile time error,
"Expression pattern of type 'String' cannot match value of type 'String?'.
I realize that this can be replaced with a let statement
(case let s where s == "Hello, playground":), but that is verbose.
Seems like the compiler could be OK with the orange text, since it is
clearly not nil.
I just got home and tested. The answer is yes, `case "text"?` does work.
let optStr : String? = "text"
switch optStr {
case nil : print("Nil")
case "text"? : print("Success")
default : print("Default")
}
// Prints `Success`
Nevin
···
On Tue, Jun 28, 2016 at 12:27 PM, Nevin Brackett-Rozinsky < nevin.brackettrozinsky@gmail.com> wrote:
Does `case "text"?` work?
On Tuesday, June 28, 2016, Kevin Nattinger via swift-evolution < > swift-evolution@swift.org> wrote:
Case .none:
Case .some("string"):
On Jun 28, 2016, at 06:40, Lucas Jordan via swift-evolution < >> swift-evolution@swift.org> wrote:
Forgive me if this was/is discussed already, I am new to the process
here....
(code is attached as a playground too)
Sometimes when I am working with a String? nil can be a reasonable value,
and what I want to do is something like the following:
import UIKit
var str:String? = "Hello, playground"
switch str{
case nil:
print("Nil!")
case "Hello, playground": //it would be super nice if this worked.
print("Match")
default:
print("Some other non nil value?")
}
But it does not work, the orange text is a compile time error,
"Expression pattern of type 'String' cannot match value of type 'String?'.
I realize that this can be replaced with a let statement (case let s
where s == "Hello, playground":), but that is verbose.
Seems like the compiler could be OK with the orange text, since it is
clearly not nil.
I’ve always thought it’s a bit odd, but that’s the way it is. FWIW, if you define `T? ~= T?` (switch uses `~=` under the hood), you can use that syntax:
public func ~=<T : Equatable>(a: T?, b: T?) -> Bool {
return a == b
}
switch str {
case "foo": print("foo")
case "bar": print("bar")
case nil: print("nil")
default: print("other")
}
For better or worse, this prevents you from using the `.some(x)` / `.none` version.
You could propose adding this to the standard library to the swift-evolution list, see how they react.
···
On Jun 28, 2016, at 9:52 AM, Lucas Jordan <lucasjordan@gmail.com> wrote:
This is sort of weird right? because comparing nil to a non nil string is a reasonable thing to do:
var nilString:String? = nil
if nilString == "this always fails" {}
is totally reasonable.
On Tue, Jun 28, 2016 at 12:33 PM, Kevin Nattinger <swift@nattinger.net> wrote:
No
7> switch str {
8. case "foo": print("case foo")
9. case .none: print("(nil)")
10. }
error: repl.swift:8:6: error: value of optional type 'String?' not unwrapped; did you mean to use '!' or '?'?
case "foo": print("case foo")
^
!
Odd error, but at least it suggests it’s an issue with optionaity.
On Jun 28, 2016, at 9:27 AM, Nevin Brackett-Rozinsky <nevin.brackettrozinsky@gmail.com> wrote:
Does `case "text"?` work?
On Tuesday, June 28, 2016, Kevin Nattinger via swift-evolution <swift-evolution@swift.org> wrote:
Case .none:
Case .some("string"):
On Jun 28, 2016, at 06:40, Lucas Jordan via swift-evolution <swift-evolution@swift.org> wrote:
Forgive me if this was/is discussed already, I am new to the process here....
(code is attached as a playground too)
Sometimes when I am working with a String? nil can be a reasonable value, and what I want to do is something like the following:
import UIKit
var str:String? = "Hello, playground"
switch str{
case nil:
print("Nil!")
case "Hello, playground": //it would be super nice if this worked.
print("Match")
default:
print("Some other non nil value?")
}
But it does not work, the orange text is a compile time error, "Expression pattern of type 'String' cannot match value of type 'String?'. I realize that this can be replaced with a let statement (case let s where s == "Hello, playground":), but that is verbose.
Seems like the compiler could be OK with the orange text, since it is clearly not nil.
Slight amendment for `let` case, which does evidently still require the explicit `.some`
switch str {
case "foo": print("foo")
case .some(let string): print(string) // `case let .some(string)` also works
case nil: print("nil")
}
···
On Jun 28, 2016, at 11:10 AM, Kevin Nattinger via swift-evolution <swift-evolution@swift.org> wrote:
I’ve always thought it’s a bit odd, but that’s the way it is. FWIW, if you define `T? ~= T?` (switch uses `~=` under the hood), you can use that syntax:
public func ~=<T : Equatable>(a: T?, b: T?) -> Bool {
return a == b
}
switch str {
case "foo": print("foo")
case "bar": print("bar")
case nil: print("nil")
default: print("other")
}
For better or worse, this prevents you from using the `.some(x)` / `.none` version.
You could propose adding this to the standard library to the swift-evolution list, see how they react.
On Jun 28, 2016, at 9:52 AM, Lucas Jordan <lucasjordan@gmail.com> wrote:
This is sort of weird right? because comparing nil to a non nil string is a reasonable thing to do:
var nilString:String? = nil
if nilString == "this always fails" {}
is totally reasonable.
On Tue, Jun 28, 2016 at 12:33 PM, Kevin Nattinger <swift@nattinger.net> wrote:
No
7> switch str {
8. case "foo": print("case foo")
9. case .none: print("(nil)")
10. }
error: repl.swift:8:6: error: value of optional type 'String?' not unwrapped; did you mean to use '!' or '?'?
case "foo": print("case foo")
^
!
Odd error, but at least it suggests it’s an issue with optionaity.
On Jun 28, 2016, at 9:27 AM, Nevin Brackett-Rozinsky <nevin.brackettrozinsky@gmail.com> wrote:
Does `case "text"?` work?
On Tuesday, June 28, 2016, Kevin Nattinger via swift-evolution <swift-evolution@swift.org> wrote:
Case .none:
Case .some("string"):
On Jun 28, 2016, at 06:40, Lucas Jordan via swift-evolution <swift-evolution@swift.org> wrote:
Forgive me if this was/is discussed already, I am new to the process here....
(code is attached as a playground too)
Sometimes when I am working with a String? nil can be a reasonable value, and what I want to do is something like the following:
import UIKit
var str:String? = "Hello, playground"
switch str{
case nil:
print("Nil!")
case "Hello, playground": //it would be super nice if this worked.
print("Match")
default:
print("Some other non nil value?")
}
But it does not work, the orange text is a compile time error, "Expression pattern of type 'String' cannot match value of type 'String?'. I realize that this can be replaced with a let statement (case let s where s == "Hello, playground":), but that is verbose.
Seems like the compiler could be OK with the orange text, since it is clearly not nil.
I nevertheless think that this is a bug and should be addressed. There is no reason where
if stringOptional == stringNonOptional { ... }
works, but pretty much the same construct doesn't work in the switch-case. It should be perhaps solved via a bugreport at http://bugs.swift.org <Issues · apple/swift · GitHub; and via evolution, though...
···
On Jun 29, 2016, at 12:31 AM, Nevin Brackett-Rozinsky via swift-evolution <swift-evolution@swift.org> wrote:
I just got home and tested. The answer is yes, `case "text"?` does work.
let optStr : String? = "text"
switch optStr {
case nil : print("Nil")
case "text"? : print("Success")
default : print("Default")
}
// Prints `Success`
Nevin
On Tue, Jun 28, 2016 at 12:27 PM, Nevin Brackett-Rozinsky <nevin.brackettrozinsky@gmail.com <mailto:nevin.brackettrozinsky@gmail.com>> wrote:
Does `case "text"?` work?
On Tuesday, June 28, 2016, Kevin Nattinger via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Case .none:
Case .some("string"):
On Jun 28, 2016, at 06:40, Lucas Jordan via swift-evolution <swift-evolution@swift.org <>> wrote:
Forgive me if this was/is discussed already, I am new to the process here....
(code is attached as a playground too)
Sometimes when I am working with a String? nil can be a reasonable value, and what I want to do is something like the following:
import UIKit
var str:String? = "Hello, playground"
switch str{
case nil:
print("Nil!")
case "Hello, playground": //it would be super nice if this worked.
print("Match")
default:
print("Some other non nil value?")
}
But it does not work, the orange text is a compile time error, "Expression pattern of type 'String' cannot match value of type 'String?'. I realize that this can be replaced with a let statement (case let s where s == "Hello, playground":), but that is verbose.
Seems like the compiler could be OK with the orange text, since it is clearly not nil.
I don't see it as a bug. The if statement calls an equality function which promotes the lhs to an Optional (or that accepts a non optional as lhs - can't remember) but the switch statement does pattern matching. Does the the compiler warn you when pattern matching an optional with a non-optional case?
···
On 29 Jun 2016, at 07:16, Charlie Monroe via swift-evolution <swift-evolution@swift.org> wrote:
I nevertheless think that this is a bug and should be addressed. There is no reason where
if stringOptional == stringNonOptional { ... }
works, but pretty much the same construct doesn't work in the switch-case. It should be perhaps solved via a bugreport at http://bugs.swift.org and via evolution, though...
On Jun 29, 2016, at 12:31 AM, Nevin Brackett-Rozinsky via swift-evolution <swift-evolution@swift.org> wrote:
I just got home and tested. The answer is yes, `case "text"?` does work.
let optStr : String? = "text"
switch optStr {
case nil : print("Nil")
case "text"? : print("Success")
default : print("Default")
}
// Prints `Success`
Nevin
On Tue, Jun 28, 2016 at 12:27 PM, Nevin Brackett-Rozinsky <nevin.brackettrozinsky@gmail.com> wrote:
Does `case "text"?` work?
On Tuesday, June 28, 2016, Kevin Nattinger via swift-evolution <swift-evolution@swift.org> wrote:
Case .none:
Case .some("string"):
On Jun 28, 2016, at 06:40, Lucas Jordan via swift-evolution <swift-evolution@swift.org> wrote:
Forgive me if this was/is discussed already, I am new to the process here....
(code is attached as a playground too)
Sometimes when I am working with a String? nil can be a reasonable value, and what I want to do is something like the following:
import UIKit
var str:String? = "Hello, playground"
switch str{
case nil:
print("Nil!")
case "Hello, playground": //it would be super nice if this worked.
print("Match")
default:
print("Some other non nil value?")
}
But it does not work, the orange text is a compile time error, "Expression pattern of type 'String' cannot match value of type 'String?'. I realize that this can be replaced with a let statement (case let s where s == "Hello, playground":), but that is verbose.
Seems like the compiler could be OK with the orange text, since it is clearly not nil.
Yes, you get a warning. But I don't see why it should - when you're matching against an optional, it's evident that you mean .some("Hello")... This should be automatically inferred.
I find this a confusing part of the switch statement where
let obj: Any? = "Hello"
switch obj {
case let str as String:
print("Hey, found String!")
default:
print("No find.")
}
will print "Hey found String", but it won't allow you to match against a string literal. This is one of the first things that I found confusing when I first learned Swift.
···
On Jun 29, 2016, at 8:49 AM, David Hart <david@hartbit.com> wrote:
I don't see it as a bug. The if statement calls an equality function which promotes the lhs to an Optional (or that accepts a non optional as lhs - can't remember) but the switch statement does pattern matching. Does the the compiler warn you when pattern matching an optional with a non-optional case?
On 29 Jun 2016, at 07:16, Charlie Monroe via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
I nevertheless think that this is a bug and should be addressed. There is no reason where
if stringOptional == stringNonOptional { ... }
works, but pretty much the same construct doesn't work in the switch-case. It should be perhaps solved via a bugreport at http://bugs.swift.org <Issues · apple/swift · GitHub; and via evolution, though...
On Jun 29, 2016, at 12:31 AM, Nevin Brackett-Rozinsky via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
I just got home and tested. The answer is yes, `case "text"?` does work.
let optStr : String? = "text"
switch optStr {
case nil : print("Nil")
case "text"? : print("Success")
default : print("Default")
}
// Prints `Success`
Nevin
On Tue, Jun 28, 2016 at 12:27 PM, Nevin Brackett-Rozinsky <nevin.brackettrozinsky@gmail.com <mailto:nevin.brackettrozinsky@gmail.com>> wrote:
Does `case "text"?` work?
On Tuesday, June 28, 2016, Kevin Nattinger via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Case .none:
Case .some("string"):
On Jun 28, 2016, at 06:40, Lucas Jordan via swift-evolution <swift-evolution@swift.org <>> wrote:
Forgive me if this was/is discussed already, I am new to the process here....
(code is attached as a playground too)
Sometimes when I am working with a String? nil can be a reasonable value, and what I want to do is something like the following:
import UIKit
var str:String? = "Hello, playground"
switch str{
case nil:
print("Nil!")
case "Hello, playground": //it would be super nice if this worked.
print("Match")
default:
print("Some other non nil value?")
}
But it does not work, the orange text is a compile time error, "Expression pattern of type 'String' cannot match value of type 'String?'. I realize that this can be replaced with a let statement (case let s where s == "Hello, playground":), but that is verbose.
Seems like the compiler could be OK with the orange text, since it is clearly not nil.
Perhaps it should provide a Fix-It, but I don't see it as an an issue, more as an opportunity to understand the pattern matching behind it :)
···
On 29 Jun 2016, at 08:59, Charlie Monroe <charlie@charliemonroe.net> wrote:
Yes, you get a warning. But I don't see why it should - when you're matching against an optional, it's evident that you mean .some("Hello")... This should be automatically inferred.
I find this a confusing part of the switch statement where
let obj: Any? = "Hello"
switch obj {
case let str as String:
print("Hey, found String!")
default:
print("No find.")
}
will print "Hey found String", but it won't allow you to match against a string literal. This is one of the first things that I found confusing when I first learned Swift.
On Jun 29, 2016, at 8:49 AM, David Hart <david@hartbit.com> wrote:
I don't see it as a bug. The if statement calls an equality function which promotes the lhs to an Optional (or that accepts a non optional as lhs - can't remember) but the switch statement does pattern matching. Does the the compiler warn you when pattern matching an optional with a non-optional case?
On 29 Jun 2016, at 07:16, Charlie Monroe via swift-evolution <swift-evolution@swift.org> wrote:
I nevertheless think that this is a bug and should be addressed. There is no reason where
if stringOptional == stringNonOptional { ... }
works, but pretty much the same construct doesn't work in the switch-case. It should be perhaps solved via a bugreport at http://bugs.swift.org and via evolution, though...
On Jun 29, 2016, at 12:31 AM, Nevin Brackett-Rozinsky via swift-evolution <swift-evolution@swift.org> wrote:
I just got home and tested. The answer is yes, `case "text"?` does work.
let optStr : String? = "text"
switch optStr {
case nil : print("Nil")
case "text"? : print("Success")
default : print("Default")
}
// Prints `Success`
Nevin
On Tue, Jun 28, 2016 at 12:27 PM, Nevin Brackett-Rozinsky <nevin.brackettrozinsky@gmail.com> wrote:
Does `case "text"?` work?
On Tuesday, June 28, 2016, Kevin Nattinger via swift-evolution <swift-evolution@swift.org> wrote:
Case .none:
Case .some("string"):
On Jun 28, 2016, at 06:40, Lucas Jordan via swift-evolution <swift-evolution@swift.org> wrote:
Forgive me if this was/is discussed already, I am new to the process here....
(code is attached as a playground too)
Sometimes when I am working with a String? nil can be a reasonable value, and what I want to do is something like the following:
import UIKit
var str:String? = "Hello, playground"
switch str{
case nil:
print("Nil!")
case "Hello, playground": //it would be super nice if this worked.
print("Match")
default:
print("Some other non nil value?")
}
But it does not work, the orange text is a compile time error, "Expression pattern of type 'String' cannot match value of type 'String?'. I realize that this can be replaced with a let statement (case let s where s == "Hello, playground":), but that is verbose.
Seems like the compiler could be OK with the orange text, since it is clearly not nil.