[swift-evolution] Proposal Sketch: simplify optional unwrapping syntax

Marc Knaup marc at knaup.koeln
Fri Dec 11 10:52:01 CST 2015


So guard let x = x would become without x or guard with x else? :)

Seems weird to have two control statements which do almost the same thing:

   - if (for any conditions) + with (for a subset of things doable with if)
   - guard (for any conditions) + without (for a subset of
   things doable with guard)

Also with/without would have to carry over the where clause which basically
is a if too.

And with multiple assignments Erica's proposal would not work anymore.

As in my previous example (made a bit larger to showcase where):

with x = a?.b.c?.d where !x.isEmpty, y = something(x) {
   // the scope cannot reference to both (x and y) now
}


Btw. there was a rather short discussion
<https://forums.developer.apple.com/thread/5786> in Apple Developer Forums
some time ago too.

On Fri, Dec 11, 2015 at 5:40 PM, Sean Heber <sean at fifthace.com> wrote:

> This has come up a few times. I’ve thrown my 2cents into a variant of
> “with” to solve this rather than messing with the meaning of if-let:
>
> For example:
>
> var x: MyType?
>
> with x {
>   x.someFunction()              // okay - this entire block is skipped if
> “x” is nil anyway
> }
> x.someFunction()                // not okay as-is since x is optional
>
>
> Using the definition  of “with” from Erica’s Method Cascading proposal
> https://gist.github.com/erica/6794d48d917e2084d6ed, you could even drop
> the variable reference itself from inside the block body:
>
> with x {
>   someFunction()                // would call “someFunction()” on “x”
> }
>
>
> And I’d additionally propose that if you wanted to replace if-let-else,
> you could potentially do this:
>
> if with x {
>   // x is known non-nil
> } else {
>   // x is known to be nil
> }
> // x is optional and nil-ness is unknown
>
>
> l8r
> Sean
>
>
> > On Dec 11, 2015, at 10:28 AM, Marc Knaup via swift-evolution <
> swift-evolution at swift.org> wrote:
> >
> > One problem with dropping if/guard let is something like this:
> >
> > if let x = a?.b.c?.d, y = something(x) {
> >    …
> > }
> >
> > would then have to become this:
> >
> > let x = a?.b.c?.d
> > if x != nil {
> >    let y = something(x)
> >    if y != nil {
> >        …
> >    }
> > }
> >
> > I'm fine with
> >    if let x
> > as a shortcut for
> >    if let x = x
> >
> > It just reads a bit weird - like declaring an immutable variable with no
> type and no value.
> >
> >
> > On Fri, Dec 11, 2015 at 5:19 PM, Jeff Kelley via swift-evolution <
> swift-evolution at swift.org> wrote:
> > I’ve had similar ideas to this. Instead of ditching the if let syntax
> altogether, another approach would be to use the existing name if no new
> name is given, so that this code:
> >
> >       if let foo = foo { /* use foo */ }
> >
> > could become this code:
> >
> >       if let foo { /* use foo */ }
> >
> > In both cases, foo is non-optional inside the braces. If you gave it
> another name with the if let syntax, that would work as it does today.
> >
> >
> > Jeff Kelley
> >
> > SlaunchaMan at gmail.com | @SlaunchaMan | jeffkelley.org
> >
> >> On Dec 11, 2015, at 11:11 AM, Daniel Hooper via swift-evolution <
> swift-evolution at swift.org> wrote:
> >>
> >> A very common pattern in swift code is to "guard let" or "if let"
> optionals  - this works by creating a new non-optional variable to be used
> by future code. Often, the new variable is given the same name as the
> original optional variable, creating a shadow variable. This approach leads
> to odd looking code like this:
> >>
> >> if let nearestX = nearestX { closest = nearestX }
> >> guard let layer = layer else { continue }
> >> // use layer
> >>
> >> At a glance, and to Swift newcomers, this code looks completely
> non-sensical. It's also verbose for simply ensuring the variable is non-nil.
> >>
> >> The solution:
> >> Swift should generate unwrapped shadow variables after nil checking.
> The compiler would treat the below code as if it had created an unwrapped
> shadow variable.
> >>
> >> if nearestX != nil { closest = nearestX } // notice that nearestX isn't
> force unwrapped
> >> guard layer != nil else { continue }
> >> // use layer, without force unwrapping
> >>
> >> Why force unwrapping isn't a good alternative:
> >> You might suggest force unwrapping variables when they're inside an if
> or after a guard that checks for nil. While this does allow for the "layer
> = nil" syntax, it results in code that is less resilient to change. Imagine
> that this code was written:
> >>
> >> {code:java}
> >> if layer != nil {
> >> // lots of code before //
> >> layer!.backgroundColor = newColor
> >> // lots of code after //
> >> }
> >> {code}
> >>
> >> And much later, you need to use some of the the code in the if body
> elsewhere, so you copy and paste a huge chunk of it. You likely won't
> notice the force unwrap, and unless you're lucky, you probably didn't paste
> it into an if that checked layer for nil. So you get a crash. Because of
> this, it's important we make safe optional unwrapping as easy and sensical
> as possible, and minimize the situations that you would need to force
> unwrap.
> >>  _______________________________________________
> >> 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/20151211/85a6a271/attachment.html>


More information about the swift-evolution mailing list