On Wed, Feb 3, 2016 at 7:49 PM, Taras Zakharko via swift-evolution < swift-evolution@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@swift.org> wrote:
On Feb 3, 2016, at 3:47 PM, Jordan Rose via swift-evolution < > swift-evolution@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@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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution