[swift-evolution] guard let x = x

Charlie Monroe charlie at charliemonroe.net
Mon Oct 31 14:53:54 CDT 2016


It doesn't in a sense "it currently works like this", but it would be theoretically possible to have the compiler understand some static conditions, such as

/// x is Int
guard x > 0 else {
	return 
}

if x == -1 { // Warning
...

Then when you'd compare x == -1, you could get a warning that this condition is always false since you've previously stated that x is greater than zero.

In this sense, you could view this as 

/// x is Any?
guard x != nil else ...

which generally is a condition that guarantees that x is nonnil further down the scope. Of course, x mustn't be an instance variable that you're referencing without explicit self.

And it would break guard foo at all - guard nonnil x else ... would just guarantee that x is nonnil further down the scope, allowing automatic force-unwrapping of the variable - which is generally what is the desired effect.


> On Oct 31, 2016, at 8:16 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
> 
> Well, "guard x != nil" does not unwrap x. An additive proposal must make clear the difference between testing if an optional is nil and unwrapping it.
> 
> Meanwhile, "guard foo" tests if foo evaluates to true. An additive proposal cannot break this syntax.
> On Mon, Oct 31, 2016 at 14:11 Charlie Monroe <charlie at charliemonroe.net <mailto:charlie at charliemonroe.net>> wrote:
> To me, it makes more sense to use
> 
> guard nonnil x else ...
> 
> since guard is guarding a condition is true - or am I wrong? Generally, it would tell the compiler that
> 
> guard x != nil else ...
> 
> which to me reads like guard nonnil x...
> 
> Just a side-note... 
> 
>> On Oct 31, 2016, at 8:05 PM, Xiaodi Wu via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> 
>> The proposal is to create a new shorthand "guard unwrap x" for "guard let x = x". The "guard" statement serves purposes other than unwrapping variables and cannot be removed.
>> On Mon, Oct 31, 2016 at 14:03 Joshua Alvarado <alvaradojoshua0 at gmail.com <mailto:alvaradojoshua0 at gmail.com>> wrote:
>> Without going back through the history, is the proposal to keep replace guard or still keep guard keyword and create a new unwrap? If unwrap is added the guard keyword should just be removed. 
>> 
>> Alvarado, Joshua
>> 
>> On Oct 31, 2016, at 12:49 PM, Xiaodi Wu via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> 
>>> Because "guard" already means something...
>>> 
>>> 
>>> On Mon, Oct 31, 2016 at 13:45 Kenny Leung via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>> It seems to me that you would end up typing “guard unwrap” 99% of the time, so why not just let “guard” imply “guard unwrap” 100% of the time?
>>> 
>>> -Kenny
>>> 
>>> 
>>> > On Oct 31, 2016, at 11:34 AM, Erica Sadun <erica at ericasadun.com <mailto:erica at ericasadun.com>> wrote:
>>> >
>>> > Because there's an action taking place in addition to guarding
>>> >
>>> > -- E
>>> >
>>> >> On Oct 31, 2016, at 12:30 PM, Kenny Leung via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>> >>
>>> >> Why have the “unwrap” keyword at all? Isn’t “guard” the keyword?
>>> >>
>>> >> guard blah else {
>>> >> }
>>> >>
>>> >> -Kenny
>>> >>
>>> >>
>>> >>> On Oct 28, 2016, at 3:34 PM, Erica Sadun via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>> >>>
>>> >>>
>>> >>>> On Oct 26, 2016, at 11:39 AM, Chris Lattner via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>> >>>>
>>> >>>>
>>> >>>>> On Oct 26, 2016, at 10:23 AM, Joshua Alvarado <alvaradojoshua0 at gmail.com <mailto:alvaradojoshua0 at gmail.com>> wrote:
>>> >>>>>
>>> >>>>> In your example the keyword only makes sense if you are shadowing the optional variable. How would unwrap work with a different name?
>>> >>>>
>>> >>>> It wouldn’t: “unwrap” would never include an equal sign.  If you want to do that, use a standard "if let”.
>>> >>>>
>>> >>>> -Chris
>>> >>>
>>> >>> So I can stop thinking about this. Gist is here: https://gist.github.com/erica/db9ce92b3d23cb20799460f603c0ae7c <https://gist.github.com/erica/db9ce92b3d23cb20799460f603c0ae7c>
>>> >>>
>>> >>> -- E
>>> >>>
>>> >>>
>>> >>> Introducing unwrap
>>> >>>
>>> >>>     • Proposal: TBD
>>> >>>     • Author: Erica Sadun, Chris Lattner, David Goodine
>>> >>>     • Status: TBD
>>> >>>     • Review manager: TBD
>>> >>> Introduction
>>> >>>
>>> >>> This proposal introduces unwrap, simplifying common shadowing and allowing a unified syntax for one-item associated values such as Result types.
>>> >>>
>>> >>> Swift-evolution thread: guard let x = x
>>> >>>
>>> >>> Motivation
>>> >>>
>>> >>> Swift lacks a unified, safe way to bind an optional or single-value enumeration to a shadowed varaiable that is guaranteed to be the same name. Introducing unwrap ensures the conditionally bound item does not accidentally shadow any other item.
>>> >>>
>>> >>> Compare:
>>> >>>
>>> >>> guard let foobar = foobar else { …
>>> >>> }
>>> >>>
>>> >>> guard unwrap foobar else { … }
>>> >>> Using unwrap eliminates repetition ("foobar = foobar" fails DRY principles) and retains clarity. The keyword is common, simple to understand, and easy to search for if Swift users are unfamiliar with it.
>>> >>>
>>> >>> This syntax simplifies one-item associated value enumerations by offering a common syntax. Compare:
>>> >>>
>>> >>> enum Result<T> { case success(T), error(Error
>>> >>> ) }
>>> >>>
>>> >>>
>>> >>> guard case let .success(value) = result else { ...
>>> >>> }
>>> >>>
>>> >>> guard unwrap result else { ... }
>>> >>> In the latter case result is bound to the wrapped value. Again, it is simpler and clearer, even with non-Optional types.
>>> >>>
>>> >>> Detailed Design
>>> >>>
>>> >>> unwrap can be used with any one-value enumeration. The unwrapped value is bound to the same symbol as the associated type.
>>> >>>
>>> >>> enum TypeName<T, U> { case anycase(T), anothercase(U) }
>>> >>>
>>> >>> // First and second are type `TypeName`
>>> >>> let first = TypeName.anyCase(value1)
>>> >>> let second = TypeName. anothercase(value2)
>>> >>>
>>> >>> guard unwrap first else { ... }
>>> >>> // first is now shadowed as type T
>>> >>>
>>> >>> guard unwrap second else { ... }
>>> >>> // second is now shadowed as type U
>>> >>>
>>> >>> Impact on Existing Code
>>> >>>
>>> >>> This change is additive and has no impact on existing code other than intentional refactoring.
>>> >>>
>>> >>> Timeline
>>> >>>
>>> >>> This proposal is additive and not suited for consideration until Swift 4 phase 2
>>> >>>
>>> >>> Alternatives Considered
>>> >>>
>>> >>>     • Using a bind keyword. Past discussions were held in the first week of February 2016.
>>> >>>     • Fixing pattern matching grammar
>>> >>>     • Not using this approach
>>> >>>
>>> >>> _______________________________________________
>>> >>> 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 <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>
>>> _______________________________________________
>>> 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 <https://lists.swift.org/mailman/listinfo/swift-evolution>
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20161031/ffd60633/attachment.html>


More information about the swift-evolution mailing list