[swift-evolution] Obsoleting `if let`

Taras Zakharko taras.zakharko at uzh.ch
Wed Feb 3 21:49:43 CST 2016


I already suggested this in the bind thread but I guess it was either not interesting or people missed it, so here it goes again :)

What about changing the syntax of optional binding such that the optional unwrapping becomes explicit? I.e. instead of 

  if let x = some_optional { }

one writes

  if let x = some_optional! { }

Essentially, the point of this suggestion is that the runtime error generated by unwrapping an empty Optional is instead treated as condition failure in a conditional statement. While there is some typing overhead over the current syntax, I see a number of potential benefits of this approach:

 1. It is in line with the current semantics and syntax of optional unwrapping (does not introduce any new syntagm)
 2. It makes the unwrapping operation explicit (thus addressing the basic criticism from the bind discussion)
 3. It frees variable declaration of the contextual polisemy (i.e. let and var have the same semantics as nowhere else, there is no ‘unwrapping’ magic)
 4. The change is minimal compare to what we have now and can be easily ported automatically

Potential issues:

 1. One character typing overhead — but I dot think that should matter. I always had the impression that Swift favours clarity over compactness (which is a good thing IMO)
 2. it allows syntactic ambiguity with optional chaining. E.g. if let x = a.b?.c! { } and if let x = a.b!.c would have the same meaning. Then again, this ambiguity already exits in the language to begin with. 

— Taras

> On 04 Feb 2016, at 01:25, Chris Lattner via swift-evolution <swift-evolution at swift.org> wrote:
> 
>> 
>> On Feb 3, 2016, at 3:47 PM, Jordan Rose via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> 
>> Data point (which Chris brought up already, I think?): We tried this* and got a lot of negative feedback. Optionals are unwrapped too often for people to be comfortable writing "if let name? = optionalCondition”.
> 
> Yes, I even implemented this and it was in the compiler for awhile, then later ripped it back out.  You can find the history in git.  I would guess that this all happened in ~March 2015.
> 
> -Chris
> 
>> 
>> It may be more uniform and even more pedantically correct, but our users hated it.
>> 
>> Jordan
>> 
>> * The actual thing we tried only allowed patterns that began with 'let', but that's close enough.
>> 
>> 
>>> On Feb 3, 2016, at 15:36, Brent Royal-Gordon via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>> 
>>> This is a continuation of and alternative proposal to "The bind thread", which seems to have petered out without consensus.
>>> 
>>> Currently there are three forms of `if` statement (and `guard` and `while`, but for simplicity I'll just say `if` throughout this discussion):
>>> 
>>> 	if booleanCondition
>>> 	if let name = optionalCondition
>>> 	if case pattern = expression
>>> 
>>> The boolean condition form is fine, but there are flaws in the other two. `if let` is unprincipled and doesn't really say what it does; `if case` is bulky and rarely used.* 
>>> 
>>> One very interesting thing about `if case`, too, is that it can actually do optional unwrapping:
>>> 
>>> 	if case let name? = optionalCondition
>>> 
>>> This avoids the problems with `if let`—it's principled (it comes from a larger language feature) and it explicitly says it's handling optionality—but it still runs up against `if case`'s rarity and wordiness.
>>> 
>>> So what I suggest is that we drop the `if let` form entirely and then drop the `case` keyword from `if case`. Pattern-matching conditions can still be distinguished from boolean conditions because boolean conditions can't contain an `=` operator. This, there would now only be two forms of if:
>>> 
>>> 	if booleanCondition
>>> 	if pattern = expression
>>> 
>>> And the current `if let` is handled elegantly and clearly by existing pattern-matching shorthand, with only one additional character needed:
>>> 
>>> 	if let name? = optionalCondition
>>> 
>>> I see two complications with this.
>>> 
>>> The first is that, naively, `if let foo = bar` would still be valid, but would have different and vacuous behavior, since the pattern cannot fail to match. The compiler should probably emit an error or at least a warning when this happens.
>>> 
>>> The second is our other weird use of the `case` keyword, `for case`, which is now an orphan in the language. I see several ways this could be handled:
>>> 
>>> 1. Drop the `for case` functionality entirely; if you want that behavior, use a pattern-matching `if`.
>>> 2. Replace the loop variable slot in the `for` statement with a pattern. This would force you to put `let` on all simple `for` statements.
>>> 3. Try to automatically distinguish between simple variables/tuples and patterns in this slot. What could possibly go wrong?
>>> 4. Require an equals sign before the `in`, like `for let foo? = in optionalFoos`. Looks a little gross, but it's unambiguous.
>>> 5. Replace `for case` with `for if`, like `for if let foo? in optionalFoos`. This helps flag the unusual conditional behavior of this form of `for`.
>>> 6. Just keep `for case` and don't worry about the fact that it's not parallel to the other statements anymore.
>>> 
>>> Thoughts on any of this?
>>> 
>>> 
>>> 
>>> * `if case` also has the problem that the `=` isn't appropriate unless you happen to bind some of the data matched by the pattern, but I don't know how to address that. A prior version of this proposal suggested saying `:=` instead of `=`, with the idea that `:=` could become a general pattern-matching operator, but the people I talked over this post with hated that.
>>> 
>>> -- 
>>> Brent Royal-Gordon
>>> Architechies
>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160204/6593902a/attachment.html>


More information about the swift-evolution mailing list