Pitch: I'd like to simplify `if case`/`guard case` to drop `case` and replace 
the equal sign with the pattern matching (`~=`) operator. I think it's simpler, 
reads better, and emphasizes "this is pattern matching" in a way the current 
grammar does not.

gist: https://gist.github.com/erica/1a5ce8a5157158c6400efb550778cead 
<https://gist.github.com/erica/1a5ce8a5157158c6400efb550778cead>

Simplifying guard case/if case syntax

Proposal: TBD
Author: Erica Sadun <https://github.com/erica>
Status: TBD
Review manager: TBD

 
<https://gist.github.com/erica/1a5ce8a5157158c6400efb550778cead#introduction>Introduction

This proposal simplifies guard case and if case grammar. It drops the case 
keyword and replaces the assignment sign with the pattern matching (~=) 
operator. The results are simpler, they reads better, and it transfers the 
responsibility of saying "this is pattern matching" from case to ~=.

Swift-evolution thread: [Pitch] ReimaginingĀ guard case/if case 
<https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20161024/tbd.html>
 
<https://gist.github.com/erica/1a5ce8a5157158c6400efb550778cead#motivation>Motivation

Swift's guard case and if case statements stand out for their unintuitive 
approach. They look like assignment statements but they are not assignment 
statements. They present difficulties for new language adopters because they 
combine several concepts in a confusing form. They are arguably underutilized 
by language experts.

Both guard case and `if case statements perform simultaneous pattern matching 
and conditional binding. Here are examples demonstrating their use in current 
Swift:

enum Result<T> { case success(T), error(Error) }

// valid Swift
guard case let .success(value) = result
    else { ... }

// valid Swift
guard case .success(let value) = result
    else { ... }
The status quo is iteratively built up in this fashion:

= performs assignment
let x = performs binding
if let x = performs conditional binding
if case .foo(let x) = performs conditional binding and pattern matching
When using if case/guard case in the absense of conditional binding, it 
duplicates basic pattern matching but uses less obvious semantics. These two 
statements are functionally identical:

if range ~= myValue { ... } // simpler
if case range = myValue { ... } // confusing
The problems with guard case and if case include:

The = operator looks like assignment and not like pattern matching (~=). 
The case layout is both too close to a switch's case but doesn't follow its 
syntax. In switch, a case is followed by a colon, not an equal sign.
Using the case syntax is unneccessarily wordy. It incorporates case, =, and 
optionally let/var assignments.

 
<https://gist.github.com/erica/1a5ce8a5157158c6400efb550778cead#detailed-design>Detailed
 Design

This proposal replaces the current syntax with a simpler grammar that 
prioritizes pattern matching but mirrors basic conditional binding. The new 
syntax drops the case keyword and replaces = with ~=. The results look like 
this:

guard let .success(value) ~= result { ... }
guard .success(let value) ~= result { ... }
if let .success(value) ~= result { ... }
if .success(let value) ~= result { ... }
guard let x? ~= anOptional { ... }
if let x? ~= anOptional { ... }
In this update:

The case keyword is subsumed into the (existing) pattern matching operator
The statements adopt the existing if-let and guard-let syntax, including 
Optional syntactic sugar.
if let x = anOptional { ... } // current
if case let x? = anOptional { ... } // current, would be removed

if let x? ~= anOptional { ... } // proposed replacement for `if case`
On adopting this syntax, the two identical range tests naturally unify to this 
single version:

if range ~= myValue { ... } // before
if case range = myValue { ... } // before

if range ~= myValue { ... } // after
Using pattern matching without conditional binding naturally simplifies to a 
standalone Boolean condition clause.


 
<https://gist.github.com/erica/1a5ce8a5157158c6400efb550778cead#impact-on-existing-code>Impact
 on Existing Code

This proposal is breaking and would require migration.


 
<https://gist.github.com/erica/1a5ce8a5157158c6400efb550778cead#alternatives-considered>Alternatives
 Considered

Leaving the grammar as-is, albeit confusing
Retaining case and replacing the equal sign with ~= (pattern matching) or : (to 
match the switch statement).
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to