[swift-evolution] [proposal] Treat (case .Foo = bar) as a Boolean expression
Patrick Smith
pgwsmith at gmail.com
Tue May 10 09:18:09 CDT 2016
I like the idea of a boolean expression! I think it is cleaner; the required if statement is a pain.
For the second idea, I’ve wondered if there could be some way of unwrapping the associated values:
case .foo(?) = bar
It would produce an optional. This would let you do:
let isAlan = (case .foo(?) = bar) == “Alan”
There’s also force unwrap:
let name = (case .foo(!) = bar)
Even better would be a way of unwrapping multiple values of the same type:
enum Bar {
case foo(name: String)
case goo(kind: GooKind, name: String)
var name: String {
return case .foo(!), .goo(_, !) = bar
}
}
> On 10 May 2016, at 9:33 PM, Sam Dods via swift-evolution <swift-evolution at swift.org> wrote:
>
> I propose that (case .Foo = bar) should be treated as an expression with a Boolean value, so the result can be set to a variable or returned from a method.
>
> Considering the following enumeration:
>
> enum Bar {
> case foo(name: String)
> case notFoo
> case unknownFoo
> }
>
> Instead of having to do the following:
>
> func isBarFoo(bar: Bar) -> Bool {
> if case .Foo = bar {
> return true
> }
> return false
> }
>
> We could simply do the following:
>
> func isBarFoo(bar: Bar) -> Bool {
> return (case .Foo = bar)
> }
>
> We could also do things like this:
>
> let isBarFoo = (case .Foo = bar)
> XCTAssert(isBarFoo)
>
> Of course, this change is only required for enumerations that don't have a raw value type (String, Int, etc).
>
> It assumes the developer does not care what the associated value is, which could lead to issues. But this is already the case with the `if case ... return true/false` syntax. So it is not a degrading feature, just a more concise syntax for something that already exists.
>
> Something to consider is whether `case let ...` could be treated as an expression in the same way. For example:
>
> if (case let .Foo(name) = bar) && name == "Alan" {
> return true
> }
> return false
>
> The above could be simplified to:
>
> return (case let .Foo(name) = bar) && name == "Alan"
>
> Due to the way AND-ed expression results are computed at runtime, the second expression would not be computed unless the first was true, so `name` must have a value. The compiler would know that when OR-ing expressions, the second expression is only computed if the first expression was false, so `name` definitely doesn't have a value:
>
> return (case let .Foo(name) = bar) || name == "Alan"
>
> I would expect a compiler error similar to `Variable declared in 'guard' condition is not usable in its body`.
>
> What does everyone think of this? It would have no impact on existing code.
>
>
> alternative, not proposing...
>
> An alternative would be defaulting what equality means for enumerations, such that the `==` operator is automatically defined for enumerations in the following way:
>
> func ==(lhs: Bar, rhs: Bar) -> Bool {
> if case rhs = lhs {
> return true
> }
> return false
> }
>
> However, I think that having a default implementation for enum is a bad idea, because it's adding default behaviour that the developer might not know about. And this could lead to a less experienced developer making a mistake when comparing two enum values with associated values. Developers that know the `if case ...` syntax are already expected to understand that they are ignoring the associated value and they can use `if case let ...` if they care about the associated value. So my proposal is in-line with an existing expectation.
>
>
> _______________________________________________
> 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/20160511/0a0e5531/attachment.html>
More information about the swift-evolution
mailing list