[swift-evolution] Obsoleting `if let`
Jonathan Tang
jonathan.d.tang at gmail.com
Wed Feb 3 22:03:38 CST 2016
FWIW, I don't see any problems with the current "if let x = ... " syntax or
behavior. I view it as a mainstream language finally implementing
anaphoric-if (as described in Paul Graham's _On Lisp_), and the unwrapping
seems like a natural consequence of the semantics, because what else
*could* it do? The if-statement needs to test on something; it seems
natural to me that the if tests for optional == nil, and then the let binds
the payload of the optional if it matches.
I wouldn't rule out there being something better, but I'm -1 on all the
proposals I've seen so far to change it.
On Wed, Feb 3, 2016 at 7:49 PM, Taras Zakharko via swift-evolution <
swift-evolution at swift.org> wrote:
> 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> 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> 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
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
> _______________________________________________
> 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/20160203/9fc99018/attachment.html>
More information about the swift-evolution
mailing list