Re: [swift-evolution] guard let x = x

2016-11-14 Thread Nevin Brackett-Rozinsky via swift-evolution
On Mon, Nov 14, 2016 at 10:41 PM, Erica Sadun via swift-evolution <
swift-evolution@swift.org> wrote:

> I believe that covers all the major points of this discussion. If so, I'm
> going to table this until phase 2.


I seem to recall another possibility that was brought up in this thread,
which is currently absent from your document…

Nevin


On Mon, Nov 14, 2016 at 10:41 PM, Erica Sadun via swift-evolution <
swift-evolution@swift.org> wrote:

>
> On Nov 14, 2016, at 12:24 AM, Jonathan Hull via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>
> On Nov 11, 2016, at 2:48 PM, Chris Lattner  wrote:
>
> To summarize:
>
> 1. Swift needs to introduce a `Result` type.
>
>
> Yes, but this is almost certainly a Swift 5 thing.  We need to settle the
> following arguments:
>
> 1) Does Result include async capabilities (I’m assuming we’ll get
> something like async await + other higher level abstractions)?
>
> 2) Do we support typed error handling at some point (so you can write
> “throws SpecificEnum”)?
>
> Before we decide those, we can’t design Result.
>
>
> I wonder if Result will end up being a sub-protocol of Unwrappable (or
> perhaps Unwrappable will give us everything we need for Result, with
> Optional being an implementation which doesn’t allow an error state).
> Basically, in addition to everything that we talked about with Unwrappable
> there would be a sugared way to say “If you represent an error, throw it
> now”.
>
> This way, Result basically becomes a way to record an error which can be
> thrown at the time (and thread) of our choosing.  It would make sense to
> have symmetry here, so we would also want an easy way to take a throwing
> call/block and turn it into a Result.  In other words, most things can just
> be designed with the current error handling model, with the throws becoming
> Results for the transition across thread boundaries… and being turned back
> into throws when you actually ‘try’ to use them.
>
> As a throw-away syntax to illustrate the idea:
>
> let myResult = Result(of: try myThrowingCall()) //Any throwing call or
> block can become a Result
>
> //Later…
>
> try unwrap myResult //This could even be in a different thread
>
>
> The reason I think we should have a protocol instead of a single generic
> enum/struct is that there are complex cases which could still easily fit in
> (or even add onto) that model if allowed.
>
> For a concrete example, in my packrat parser, I have several different
> error states that can be handled differently.  Some just cause it to fall
> back to try the next rule, while others cause it to terminate parsing or
> enter into a debug mode.  I also have the concept of a semi-successful
> return with errors (i.e. It is fully parsed, but instead of a result, the
> parsed string is returned with a set of human-readable errors (+ locations
> in the string) explaining why a result could not be returned).
>
> It would be nice for Result to be able to support that sort of thing as
> well (at least as an add-on), and a protocol would give us the freedom to
> extend the model as needed.
>
> The reason I am bringing this up now is that it may also affect our design
> of Unwrappable.
>
> Thanks,
> Jon
>
>
> * Just so we have a record of this discussion for future refinement, I've
> put this together: https://gist.github.com/erica/
> 3daa8ec77aef2feaefca3a3a19aedee3
> It addresses `Unwrappable` and `Result` but not `unwrap`. It does not
> really touch on the async/threading aspects of `Result` and refers to the
> design of `Result` as a matter for future discussion.
>
> * My original `if case`/`guard case` is here: https://github.com/
> apple/swift-evolution/pull/559
>
> * I would write up the basic `unwrap` at some point, but it seems to me
> that it would be heavily biased towards supporting `Unwrappable` so maybe I
> should hold off until the ideas behind `Unwrappable` are better hashed out.
>
> I believe that covers all the major points of this discussion. If so, I'm
> going to table this until phase 2.
>
> -- E
>
>
>
> ___
> 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


Re: [swift-evolution] guard let x = x

2016-11-14 Thread Erica Sadun via swift-evolution

> On Nov 14, 2016, at 12:24 AM, Jonathan Hull via swift-evolution 
>  wrote:
> 
> 
>> On Nov 11, 2016, at 2:48 PM, Chris Lattner > > wrote:
>> 
>>> To summarize:
>>> 
>>> 1. Swift needs to introduce a `Result` type. 
>> 
>> Yes, but this is almost certainly a Swift 5 thing.  We need to settle the 
>> following arguments:
>> 
>> 1) Does Result include async capabilities (I’m assuming we’ll get something 
>> like async await + other higher level abstractions)?
>> 
>> 2) Do we support typed error handling at some point (so you can write 
>> “throws SpecificEnum”)?
>> 
>> Before we decide those, we can’t design Result.
> 
> I wonder if Result will end up being a sub-protocol of Unwrappable (or 
> perhaps Unwrappable will give us everything we need for Result, with Optional 
> being an implementation which doesn’t allow an error state).  Basically, in 
> addition to everything that we talked about with Unwrappable there would be a 
> sugared way to say “If you represent an error, throw it now”.  
> 
> This way, Result basically becomes a way to record an error which can be 
> thrown at the time (and thread) of our choosing.  It would make sense to have 
> symmetry here, so we would also want an easy way to take a throwing 
> call/block and turn it into a Result.  In other words, most things can just 
> be designed with the current error handling model, with the throws becoming 
> Results for the transition across thread boundaries… and being turned back 
> into throws when you actually ‘try’ to use them.
> 
> As a throw-away syntax to illustrate the idea:
> 
>   let myResult = Result(of: try myThrowingCall()) //Any throwing call or 
> block can become a Result
> 
>   //Later… 
> 
>   try unwrap myResult //This could even be in a different thread
> 
> 
> The reason I think we should have a protocol instead of a single generic 
> enum/struct is that there are complex cases which could still easily fit in 
> (or even add onto) that model if allowed.
> 
> For a concrete example, in my packrat parser, I have several different error 
> states that can be handled differently.  Some just cause it to fall back to 
> try the next rule, while others cause it to terminate parsing or enter into a 
> debug mode.  I also have the concept of a semi-successful return with errors 
> (i.e. It is fully parsed, but instead of a result, the parsed string is 
> returned with a set of human-readable errors (+ locations in the string) 
> explaining why a result could not be returned).
> 
> It would be nice for Result to be able to support that sort of thing as well 
> (at least as an add-on), and a protocol would give us the freedom to extend 
> the model as needed.
> 
> The reason I am bringing this up now is that it may also affect our design of 
> Unwrappable.
> 
> Thanks,
> Jon

* Just so we have a record of this discussion for future refinement, I've put 
this together: https://gist.github.com/erica/3daa8ec77aef2feaefca3a3a19aedee3 

It addresses `Unwrappable` and `Result` but not `unwrap`. It does not really 
touch on the async/threading aspects of `Result` and refers to the design of 
`Result` as a matter for future discussion.

* My original `if case`/`guard case` is here: 
https://github.com/apple/swift-evolution/pull/559 


* I would write up the basic `unwrap` at some point, but it seems to me that it 
would be heavily biased towards supporting `Unwrappable` so maybe I should hold 
off until the ideas behind `Unwrappable` are better hashed out.

I believe that covers all the major points of this discussion. If so, I'm going 
to table this until phase 2.

-- E


___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-11-13 Thread Jonathan Hull via swift-evolution

> On Nov 11, 2016, at 2:48 PM, Chris Lattner  wrote:
> 
>> To summarize:
>> 
>> 1. Swift needs to introduce a `Result` type. 
> 
> Yes, but this is almost certainly a Swift 5 thing.  We need to settle the 
> following arguments:
> 
> 1) Does Result include async capabilities (I’m assuming we’ll get something 
> like async await + other higher level abstractions)?
> 
> 2) Do we support typed error handling at some point (so you can write “throws 
> SpecificEnum”)?
> 
> Before we decide those, we can’t design Result.

I wonder if Result will end up being a sub-protocol of Unwrappable (or perhaps 
Unwrappable will give us everything we need for Result, with Optional being an 
implementation which doesn’t allow an error state).  Basically, in addition to 
everything that we talked about with Unwrappable there would be a sugared way 
to say “If you represent an error, throw it now”.  

This way, Result basically becomes a way to record an error which can be thrown 
at the time (and thread) of our choosing.  It would make sense to have symmetry 
here, so we would also want an easy way to take a throwing call/block and turn 
it into a Result.  In other words, most things can just be designed with the 
current error handling model, with the throws becoming Results for the 
transition across thread boundaries… and being turned back into throws when you 
actually ‘try’ to use them.

As a throw-away syntax to illustrate the idea:

let myResult = Result(of: try myThrowingCall()) //Any throwing call or 
block can become a Result

//Later… 

try unwrap myResult //This could even be in a different thread


The reason I think we should have a protocol instead of a single generic 
enum/struct is that there are complex cases which could still easily fit in (or 
even add onto) that model if allowed.

For a concrete example, in my packrat parser, I have several different error 
states that can be handled differently.  Some just cause it to fall back to try 
the next rule, while others cause it to terminate parsing or enter into a debug 
mode.  I also have the concept of a semi-successful return with errors (i.e. It 
is fully parsed, but instead of a result, the parsed string is returned with a 
set of human-readable errors (+ locations in the string) explaining why a 
result could not be returned).

It would be nice for Result to be able to support that sort of thing as well 
(at least as an add-on), and a protocol would give us the freedom to extend the 
model as needed.

The reason I am bringing this up now is that it may also affect our design of 
Unwrappable.

Thanks,
Jon

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-11-04 Thread Martin Waitz via swift-evolution

Am 2016-11-04 06:55, schrieb Thorsten Seitz:

vars cannot be type narrowed as soon as concurrency comes into play.
That's why Ceylon restricts type narrowing to immutables.


Are you afraid that your variable gets changed under your feet and 
afterwards does not conform to the narrowed type any more?


In this case, you have to resort to locks or local copies anyway, even 
without type narrowing.
But you are right, type narrowing could transform a simple data race 
into a fatalError.


--
Martin
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-11-03 Thread Thorsten Seitz via swift-evolution
vars cannot be type narrowed as soon as concurrency comes into play. That's why 
Ceylon restricts type narrowing to immutables.

-Thorsten 

> Am 03.11.2016 um 09:52 schrieb Martin Waitz via swift-evolution 
> :
> 
> Am 2016-11-03 09:17, schrieb Pyry Jahkola via swift-evolution:
>> As pleasing as it sounds*), the idea of type narrowing breaks down
>> badly if:
>> – the binding is implicit (without explicit extra syntax involved)
>> and
>> – what is bound happens to be mutable.
>> An example being:
>> // VAR message: String?
>> IF message != NIL { // magic turns 'message' into a non-optional
>> 'String' here
>> handleMessage(message)
>> message = NIL // 'String' is not 'ExpressibleByNilLiteral'
>> }
>> What magic would we require to still allow access to the Optional
>> interface of 'message' in that block? In other words, I'm afraid type
>> narrowing for Swift's enums (including Optional) isn't quite as simple
>> as that.
> 
> No magic would be required.
> Just don't turn into non-optional but into implicitly unwrapped optional.
> 
> And only do so while the compiler can prove that it is non-nil.
> I.e. after your `message = nil` line, it would be handled just like any other 
> optional again.
> 
> -- 
> Martin
> ___
> 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


Re: [swift-evolution] guard let x = x

2016-11-03 Thread Haravikk via swift-evolution

> On 3 Nov 2016, at 08:17, Pyry Jahkola  wrote:
> 
> As pleasing as it sounds*), the idea of type narrowing breaks down badly if:
> 
> – the binding is implicit (without explicit extra syntax involved) and
> – what is bound happens to be mutable.
> 
> An example being:
> 
> // var message: String?
> if message != nil { // magic turns 'message' into a non-optional 'String' 
> here
>   handleMessage(message)
>   message = nil // 'String' is not 'ExpressibleByNilLiteral'
> }
> 
> What magic would we require to still allow access to the Optional interface 
> of 'message' in that block?

Type widening 

Basically if you try to assign a value to `message` that is not valid for the 
narrowed type, but is fine for a wider type then it can simply be widened again 
at that point. You could think of the variable's type as being a stack of 
types, each narrower than the last; if you hit a road-block with the current 
type, you can try rolling back (widening) until you find one that works, at 
which point this is the new narrowest type, or return an error as normal.

In this specific example you may instead think of it as re-narrowing, as after 
that line message can only be `nil`. 

In fact in that example we can look at it like this:

// message is Optional
if message != nil { // Optional.some
handleMessage(message) // Optional.some
message = nil // Optional.none
} // Optional.none

As both branches ended with the same type, the type of message afterwards is 
Optional.none from that point on; allowing unwrapping operations to become 
invalid (as they cannot possibly succeed) and other useful behaviours. If 
message wasn't set to nil within the if statement then it would return to being 
the wider Optional (as it's the narrowest type that both branches have in 
common).___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-11-03 Thread Martin Waitz via swift-evolution

Am 2016-11-03 09:17, schrieb Pyry Jahkola via swift-evolution:

As pleasing as it sounds*), the idea of type narrowing breaks down
badly if:

– the binding is implicit (without explicit extra syntax involved)
and
– what is bound happens to be mutable.

An example being:

 // VAR message: String?
 IF message != NIL { // magic turns 'message' into a non-optional
'String' here
 handleMessage(message)
 message = NIL // 'String' is not 'ExpressibleByNilLiteral'
 }

What magic would we require to still allow access to the Optional
interface of 'message' in that block? In other words, I'm afraid type
narrowing for Swift's enums (including Optional) isn't quite as simple
as that.


No magic would be required.
Just don't turn into non-optional but into implicitly unwrapped 
optional.


And only do so while the compiler can prove that it is non-nil.
I.e. after your `message = nil` line, it would be handled just like any 
other optional again.


--
Martin
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-11-03 Thread Tino Heth via swift-evolution
> if x != nil {
>   // x is definitely not nil inside this block (implicitly 
> unwrapped)

Pyry already mentioned the problem that arise when x is a variable (is "x = 
nil" forbidden inside the block?).
Properties add complications as well (especially, but not only, computed ones), 
and everything beyond simple checks for nil would be a potential source of big 
confusion:
if (x == y) {
What if one of the values can change? Forbidding that would be odd, but if you 
don't oppose strict limits, there is no way to guarantee that the initial 
conditions are still valid throughout the block.

In general, I think Swifts approach is very good, because it saves us from the 
"magic" that has to be involved when the compiler infers traits based on checks 
done in the source.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-11-03 Thread Pyry Jahkola via swift-evolution
As pleasing as it sounds*), the idea of type narrowing breaks down badly if:

– the binding is implicit (without explicit extra syntax involved) and
– what is bound happens to be mutable.

An example being:

// var message: String?
if message != nil { // magic turns 'message' into a non-optional 'String' 
here
  handleMessage(message)
  message = nil // 'String' is not 'ExpressibleByNilLiteral'
}

What magic would we require to still allow access to the Optional interface of 
'message' in that block? In other words, I'm afraid type narrowing for Swift's 
enums (including Optional) isn't quite as simple as that.

— Pyry

*) OTOH, I could see much benefit from being able to narrow down enums of all 
kinds, e.g. `Result` such that in the `else` branch of a failing `guard case 
let .success(value) = result`, the `error` value of `case failure(error)` were 
guaranteed by the compiler to be readily available, something like:

enum Result { case success(T); case failure(Error) }
// ...
// let result: Result
guard case let .success(string) = result
else case let .failure(error) = result {
  // ^
  // Guaranteed to succeed because 'result' was proven to be of 'case 
failure(Error)'
  throw error
}
print(string)

> On 3 Nov 2016, at 6.37, Hooman Mehr via swift-evolution 
>  wrote:
> 
> 
>> On Nov 2, 2016, at 2:02 PM, Matthew Johnson via swift-evolution 
>> > wrote:
>>> On Nov 2, 2016, at 3:47 PM, Sean Heber via swift-evolution 
>>> > wrote:
>>> 
>>> For what it’s worth, I concur. I think type narrowing makes it feel more 
>>> like the language is actually doing some work *for* me rather than me 
>>> having to babysit the language with some new syntax or keyword.
>> 
>> I’ve been staying out of the discussion because it doesn’t seem particularly 
>> relevant to Swift 4 phase 1, but +1.  Type narrowing is by far the most 
>> general and scalable solution which could be applied in other ways in the 
>> future.
>> 
> 
> Same as me, I was staying out as well. 
> +1 for type narrowing instead of the original proposal. Thank you Haravikk 
> for bringing this up.
> 
>>> 
>>> l8r
>>> Sean
>>> 
 On Nov 2, 2016, at 3:25 PM, Haravikk via swift-evolution 
 > wrote:
 
 I still think that type narrowing is the right way to handle this like so:
 
if x != nil {
// x is definitely not nil inside this block (implicitly 
 unwrapped)
} // x remains optional outside of it
 
if (x != nil) || (x == y) {
// if y's type is non-optional, then x is definitely not nil 
 inside this block also
// i.e- if all conditions narrow to the same result, the type 
 is narrowed inside the block
}
 
if x is Foo {
x.someMethodSpecificToFoo()
}
 
 Personally I'm very much against the use of shadowing in the first place, 
 and never use it myself. I tend to precede unwrapped value with "this" 
 like so:
 
if let thisFoo = foo {
// Do something with thisFoo
}
 
 I know it's maybe down to personal preference but I'd prefer to discourage 
 shadowing entirely, and focus on type-narrowing, as it's a much more 
 natural, and more generally useful, way to handle this "problem", as it 
 doesn't actually require a specific syntax at all; if your condition 
 narrows the type, then you can use the variable as whatever it is known to 
 be.
> ___
> 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


Re: [swift-evolution] guard let x = x

2016-11-02 Thread Hooman Mehr via swift-evolution

> On Nov 2, 2016, at 2:02 PM, Matthew Johnson via swift-evolution 
>  wrote:
>> On Nov 2, 2016, at 3:47 PM, Sean Heber via swift-evolution 
>> > wrote:
>> 
>> For what it’s worth, I concur. I think type narrowing makes it feel more 
>> like the language is actually doing some work *for* me rather than me having 
>> to babysit the language with some new syntax or keyword.
> 
> I’ve been staying out of the discussion because it doesn’t seem particularly 
> relevant to Swift 4 phase 1, but +1.  Type narrowing is by far the most 
> general and scalable solution which could be applied in other ways in the 
> future.
> 

Same as me, I was staying out as well. 
+1 for type narrowing instead of the original proposal. Thank you Haravikk for 
bringing this up.

>> 
>> l8r
>> Sean
>> 
>>> On Nov 2, 2016, at 3:25 PM, Haravikk via swift-evolution 
>>>  wrote:
>>> 
>>> I still think that type narrowing is the right way to handle this like so:
>>> 
>>> if x != nil {
>>> // x is definitely not nil inside this block (implicitly 
>>> unwrapped)
>>> } // x remains optional outside of it
>>> 
>>> if (x != nil) || (x == y) {
>>> // if y's type is non-optional, then x is definitely not nil 
>>> inside this block also
>>> // i.e- if all conditions narrow to the same result, the type 
>>> is narrowed inside the block
>>> }
>>> 
>>> if x is Foo {
>>> x.someMethodSpecificToFoo()
>>> }
>>> 
>>> Personally I'm very much against the use of shadowing in the first place, 
>>> and never use it myself. I tend to precede unwrapped value with "this" like 
>>> so:
>>> 
>>> if let thisFoo = foo {
>>> // Do something with thisFoo
>>> }
>>> 
>>> I know it's maybe down to personal preference but I'd prefer to discourage 
>>> shadowing entirely, and focus on type-narrowing, as it's a much more 
>>> natural, and more generally useful, way to handle this "problem", as it 
>>> doesn't actually require a specific syntax at all; if your condition 
>>> narrows the type, then you can use the variable as whatever it is known to 
>>> be.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-11-02 Thread Matthew Johnson via swift-evolution

> On Nov 2, 2016, at 3:47 PM, Sean Heber via swift-evolution 
>  wrote:
> 
> For what it’s worth, I concur. I think type narrowing makes it feel more like 
> the language is actually doing some work *for* me rather than me having to 
> babysit the language with some new syntax or keyword.

I’ve been staying out of the discussion because it doesn’t seem particularly 
relevant to Swift 4 phase 1, but +1.  Type narrowing is by far the most general 
and scalable solution which could be applied in other ways in the future.

> 
> l8r
> Sean
> 
> 
>> On Nov 2, 2016, at 3:25 PM, Haravikk via swift-evolution 
>>  wrote:
>> 
>> I still think that type narrowing is the right way to handle this like so:
>> 
>>  if x != nil {
>>  // x is definitely not nil inside this block (implicitly 
>> unwrapped)
>>  } // x remains optional outside of it
>> 
>>  if (x != nil) || (x == y) {
>>  // if y's type is non-optional, then x is definitely not nil 
>> inside this block also
>>  // i.e- if all conditions narrow to the same result, the type 
>> is narrowed inside the block
>>  }
>> 
>>  if x is Foo {
>>  x.someMethodSpecificToFoo()
>>  }
>> 
>> Personally I'm very much against the use of shadowing in the first place, 
>> and never use it myself. I tend to precede unwrapped value with "this" like 
>> so:
>> 
>>  if let thisFoo = foo {
>>  // Do something with thisFoo
>>  }
>> 
>> I know it's maybe down to personal preference but I'd prefer to discourage 
>> shadowing entirely, and focus on type-narrowing, as it's a much more 
>> natural, and more generally useful, way to handle this "problem", as it 
>> doesn't actually require a specific syntax at all; if your condition narrows 
>> the type, then you can use the variable as whatever it is known to be.
>> ___
>> 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


Re: [swift-evolution] guard let x = x

2016-11-02 Thread Sean Heber via swift-evolution
For what it’s worth, I concur. I think type narrowing makes it feel more like 
the language is actually doing some work *for* me rather than me having to 
babysit the language with some new syntax or keyword.

l8r
Sean


> On Nov 2, 2016, at 3:25 PM, Haravikk via swift-evolution 
>  wrote:
> 
> I still think that type narrowing is the right way to handle this like so:
> 
>   if x != nil {
>   // x is definitely not nil inside this block (implicitly 
> unwrapped)
>   } // x remains optional outside of it
> 
>   if (x != nil) || (x == y) {
>   // if y's type is non-optional, then x is definitely not nil 
> inside this block also
>   // i.e- if all conditions narrow to the same result, the type 
> is narrowed inside the block
>   }
> 
>   if x is Foo {
>   x.someMethodSpecificToFoo()
>   }
> 
> Personally I'm very much against the use of shadowing in the first place, and 
> never use it myself. I tend to precede unwrapped value with "this" like so:
> 
>   if let thisFoo = foo {
>   // Do something with thisFoo
>   }
> 
> I know it's maybe down to personal preference but I'd prefer to discourage 
> shadowing entirely, and focus on type-narrowing, as it's a much more natural, 
> and more generally useful, way to handle this "problem", as it doesn't 
> actually require a specific syntax at all; if your condition narrows the 
> type, then you can use the variable as whatever it is known to be.
> ___
> 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


Re: [swift-evolution] guard let x = x

2016-11-02 Thread Haravikk via swift-evolution
I still think that type narrowing is the right way to handle this like so:

if x != nil {
// x is definitely not nil inside this block (implicitly 
unwrapped)
} // x remains optional outside of it

if (x != nil) || (x == y) {
// if y's type is non-optional, then x is definitely not nil 
inside this block also
// i.e- if all conditions narrow to the same result, the type 
is narrowed inside the block
}

if x is Foo {
x.someMethodSpecificToFoo()
}

Personally I'm very much against the use of shadowing in the first place, and 
never use it myself. I tend to precede unwrapped value with "this" like so:

if let thisFoo = foo {
// Do something with thisFoo
}

I know it's maybe down to personal preference but I'd prefer to discourage 
shadowing entirely, and focus on type-narrowing, as it's a much more natural, 
and more generally useful, way to handle this "problem", as it doesn't actually 
require a specific syntax at all; if your condition narrows the type, then you 
can use the variable as whatever it is known to be.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-11-02 Thread Nevin Brackett-Rozinsky via swift-evolution
I think I agree with Tino, the use-case of “unwrap” for shadowing is not
compelling enough to justify adding a keyword.

Moreover, regarding the generalized enum associated-value extraction
situation, the approach I described earlier is copacetic to both
destructuring tuples and leaving them intact. For example, with this enum
from Erica’s revised proposal:

enum Response {
case contact(code: Int, message: String)
case failure
}

We can extend it like so:

extension Response {
var contact: (code: Int, message: String)? {
if case let .contact(x) = self { return x }
return nil
}
}

And then access its associated values either as a tuple or as separate
variables:

let r = Response.contact(code: 6, message: "Seven")

if let t = r.contact {
print(t.code, t.message)
}

if let (c, m) = r.contact {
print(c, m)
}

To make this work without manually implementing the boilerplate extension,
I propose either a magic “Unwrappable” protocol which when conformed to by
an enum will automatically generate the equivalent of that boilerplate, or
else an “@unwrappable” attribute that can be applied to individual enum
cases (and perhaps to an enum declaration if every case with an associated
value should have it).

Furthermore, in the special case of an enum with only one unwrappable case,
we could add sugar to make it “act like” an Optional for conditional
binding, meaning eg. “.contact” could be elided and it would be usable as:

if let x = r { … }

I think this makes for better code and a simpler language than the proposed
alternatives involving an “unwrap” keyword, and it does not involve any
source-breaking changes. It also lifts conditional-binding from a niche
Optional-only feature, to a user-accessible tool for enums broadly.

Nevin


On Wed, Nov 2, 2016 at 12:53 PM, Tino Heth via swift-evolution <
swift-evolution@swift.org> wrote:

> Imho it would be better not to add "uwrap".
> Yes, it might be nicer in some situations, but it is also nice to have a
> simple (or at least less complicated) language.
> For me, the actual benefit is to low to justify a separate keyword which
> creates questions that don't exist with the current syntax.
> It is quite clear that "if let" declares a new value, whereas "unwrap"
> introduces ambiguity.
>
> Have a look at this line:
> if unwrap someObject.someFunction() { print("?") }
> Should the compiler accept it?
> If yes: Should it be possible to access the return value of someFunction?
> How?
> If no: What about "someObject.someComputedProperty"? What if you exchange
> "someObject" with "self"?
>
> What if I want to modify an unwrapped value? "if var" is quite intuitive,
> but unwrap… maybe it depends on the original value, or is there a second
> variant?
>
> There might be good answers for all those questions, but they aren't
> obvious.
>
> ___
> 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


Re: [swift-evolution] guard let x = x

2016-11-02 Thread Tino Heth via swift-evolution
Imho it would be better not to add "uwrap".
Yes, it might be nicer in some situations, but it is also nice to have a simple 
(or at least less complicated) language.
For me, the actual benefit is to low to justify a separate keyword which 
creates questions that don't exist with the current syntax.
It is quite clear that "if let" declares a new value, whereas "unwrap" 
introduces ambiguity.

Have a look at this line:
if unwrap someObject.someFunction() { print("?") }
Should the compiler accept it?
If yes: Should it be possible to access the return value of someFunction? How?
If no: What about "someObject.someComputedProperty"? What if you exchange 
"someObject" with "self"?

What if I want to modify an unwrapped value? "if var" is quite intuitive, but 
unwrap… maybe it depends on the original value, or is there a second variant?

There might be good answers for all those questions, but they aren't obvious.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-11-02 Thread Thorsten Seitz via swift-evolution

> Am 01.11.2016 um 19:42 schrieb Erica Sadun via swift-evolution 
> :
> 
> Here are a few varieties of how that call might look versus the proposed 
> update for normal pattern matching:
> 
> if unwrap .string(myString) ~= json { ... }
> if unwrap .contact(code, _) ~= response { ... }
> if unwrap .contact(code, var message) ~= response { ... }
> 
> // vs proposed
> 
> if let .string(myString) ~= json { ... }
> if var .string(myString) ~= json { ... }
> if .contact(let code, _) ~= response { ... }
> if .contact(let code, var message) ~= response { ... }
> Although slightly wordier than let and var, the unwrap solution offers 
> advantages:
> 
> It enhances readability. If the goal is to unwrap an embedded value, unwrap 
> uses a more appropriate term.
> It establishes one place for the keyword to live instead of the "does it go 
> inside or outside" status quo. A consistent place means prettier code.
The `unwrap` variant loses the ability to distinguish between binding a 
variable (which means the variable will be preceded by `let`) and matching 
against the value of a variable, e.g. the following are very different:

let code = 1
if case .contact(code, let msg) = response {...}

vs.

if case .contact(let code, let msg) = response {...}

Actually for that proposed use of `unwrap` I see no advantage over the existing 
`case` which I prefer over the ~= operator. The assignment operator does not 
look wrong in my eyes, either, because it is quite natural to have bindings 
happen on the left side of it.

Using `unwrap` solely as replacement for `let x = x`, i.e. as `unwrap x` is 
fine with me.

-Thorsten 


___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-11-02 Thread Dany St-Amant via swift-evolution

> Le 1 nov. 2016 à 14:42, Erica Sadun via swift-evolution 
>  a écrit :
> 
> With massive revisions. I've added Xiaodi Wu to author list. I've combined 
> all unwrapping together. I've added a much more sensible approach (plus a 
> bluesky one) for real world enumerations.
> 
> Gist with live updates here: 
> https://gist.github.com/erica/db9ce92b3d23cb20799460f603c0ae7c
> 
> Send feedback, I will continue to revise.
> 

The proposal should describe the behaviour with nested-optional and with enum 
case providing optionals.

let x:Int?? = 42
guard let y = x, let z = y else { return }
// no final shadowing form currently exist for double unwrap

enum sample { case data(Int?) }
let x = sample.data(42)
guard case .data(let x) = x, let y = x else { return }
// x shadowed x, but still optional, cannot currently unwrap that optional as 
shadowing x

Not sure if the design should fully handle these cases, but their behaviour 
should be shown as to how they interact with the proposed syntax.

Regards
Dany___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-11-02 Thread Rien via swift-evolution
Please ignore, the mail was sent in error.

> On 02 Nov 2016, at 07:13, Rien via swift-evolution 
>  wrote:
> 
> If using “unwrap” in itself, then it should be statement that only unwraps, 
> hence the
> 
> Regards,
> Rien
> 
> Site: http://balancingrock.nl
> Blog: http://swiftrien.blogspot.com
> Github: http://github.com/Swiftrien
> Project: http://swiftfire.nl
> 
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-11-02 Thread Rien via swift-evolution
If using “unwrap” in itself, then it should be statement that only unwraps, 
hence the

Regards,
Rien

Site: http://balancingrock.nl
Blog: http://swiftrien.blogspot.com
Github: http://github.com/Swiftrien
Project: http://swiftfire.nl




> On 02 Nov 2016, at 02:47, Dany St-Amant via swift-evolution 
>  wrote:
> 
> 
>> Le 31 oct. 2016 à 17:44, Erica Sadun via swift-evolution 
>>  a écrit :
>> 
>> 
>>> On Oct 31, 2016, at 1:51 PM, Xiaodi Wu via swift-evolution 
>>>  wrote:
>>> 
>>> An alternative that would seem to satisfy some objections is to have a 
>>> distinct "unwrap" statement--as in: "unwrap x else { ... }".
>> 
>> I'd be against this alternative as it is doing the work of a guard statement 
>> (including the "must exit scope" rule) with a new keyword and unneeded 
>> redundancy.
>> 
>> Adding "unwrap" is local. It performs one very common task with added safety 
>> (avoids unintended shadow effects) and introduces succinctness and clarity. 
>> In other words, it is a highly focused changed with a measurable benefit in 
>> use.
>> 
>> Compare:
>> 
>> * "Introduce the unwrap statement that acts like guard but is limited to 
>> optionals" creates unnecessary language verbosity.
>> 
>> * "guard x else ", meaning "treat optional values differently than all other 
>> items in a conditional list", fails because it obscures rather than adds 
>> intent. Worse, it would lead to issues with Boolean optionals whose wrapped 
>> value is later used within the same condition.
>> 
>> Xiaodi, you mentioned an alternative approach and I'd love a peek at what 
>> that is.
> 
> Also with the 'guard unwrap', the following code make sense:
> 
> guard unwrap x, x == 10 else { return }
> 
> With a lone unwrap it would not.
> 
> unwrap x, x == 10 else { return }
> 
> I personally do not like shadowing, but a standalone 'unwrap!' could be of 
> interest to those loving life in the shadows. Beside the shadowing itself, it 
> should not be any worst than any of the other '!' usage. The feasibility of 
> such depends of course on how the compiler manages its variable scoping.
> 
> On further thought, if we were to make the, sorry bad word coming, 
> code-breaking change to disallow legacy shadowing 'let x=x' and force the 
> shadowing to be done exclusively via this 'unwrap' keyword, it could make it 
> easier for projects/companies to ban shadowing.
> 
> Dany
> ___
> 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


Re: [swift-evolution] guard let x = x

2016-11-01 Thread Dennis Lysenko via swift-evolution
Gonna put in my 2 cents re shadowing being a source of bugs: I use explicit
self everywhere in my codebase and it pairs wonderfully with shadowing,
making the detailed example moot. As far as Dany's message, I think that's
the best way to go forward with an unwrap keyword--just make it work
exactly like if let x = x; not sure what other behavior was being
discussed. Another way to go, though, if we're really worried about
shadowing on mutable properties causing issues, would be to just have
nullity inference on constants, so if you said "let x = someNullableValue;
if x != nil { /* x would be inferred to be non-null here */ }". Kotlin does
this very, very successfully. (But my biggest reservation with such an
implementation in practice, in Kotlin, is that it only works for immutable
properties. Which is why I'm fully +1 on the unwrap statement. People are
going to shadow. Let them do it in a cleaner way.)

On Tue, Nov 1, 2016 at 9:47 PM Dany St-Amant via swift-evolution <
swift-evolution@swift.org> wrote:

>
> > Le 31 oct. 2016 à 17:44, Erica Sadun via swift-evolution <
> swift-evolution@swift.org> a écrit :
> >
> >
> >> On Oct 31, 2016, at 1:51 PM, Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
> >>
> >> An alternative that would seem to satisfy some objections is to have a
> distinct "unwrap" statement--as in: "unwrap x else { ... }".
> >
> > I'd be against this alternative as it is doing the work of a guard
> statement (including the "must exit scope" rule) with a new keyword and
> unneeded redundancy.
> >
> > Adding "unwrap" is local. It performs one very common task with added
> safety (avoids unintended shadow effects) and introduces succinctness and
> clarity. In other words, it is a highly focused changed with a measurable
> benefit in use.
> >
> > Compare:
> >
> > * "Introduce the unwrap statement that acts like guard but is limited to
> optionals" creates unnecessary language verbosity.
> >
> > * "guard x else ", meaning "treat optional values differently than all
> other items in a conditional list", fails because it obscures rather than
> adds intent. Worse, it would lead to issues with Boolean optionals whose
> wrapped value is later used within the same condition.
> >
> > Xiaodi, you mentioned an alternative approach and I'd love a peek at
> what that is.
>
> Also with the 'guard unwrap', the following code make sense:
>
> guard unwrap x, x == 10 else { return }
>
> With a lone unwrap it would not.
>
> unwrap x, x == 10 else { return }
>
> I personally do not like shadowing, but a standalone 'unwrap!' could be of
> interest to those loving life in the shadows. Beside the shadowing itself,
> it should not be any worst than any of the other '!' usage. The feasibility
> of such depends of course on how the compiler manages its variable scoping.
>
> On further thought, if we were to make the, sorry bad word coming,
> code-breaking change to disallow legacy shadowing 'let x=x' and force the
> shadowing to be done exclusively via this 'unwrap' keyword, it could make
> it easier for projects/companies to ban shadowing.
>
> Dany
> ___
> 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


Re: [swift-evolution] guard let x = x

2016-11-01 Thread Dany St-Amant via swift-evolution

> Le 31 oct. 2016 à 17:44, Erica Sadun via swift-evolution 
>  a écrit :
> 
> 
>> On Oct 31, 2016, at 1:51 PM, Xiaodi Wu via swift-evolution 
>>  wrote:
>> 
>> An alternative that would seem to satisfy some objections is to have a 
>> distinct "unwrap" statement--as in: "unwrap x else { ... }".
> 
> I'd be against this alternative as it is doing the work of a guard statement 
> (including the "must exit scope" rule) with a new keyword and unneeded 
> redundancy.
> 
> Adding "unwrap" is local. It performs one very common task with added safety 
> (avoids unintended shadow effects) and introduces succinctness and clarity. 
> In other words, it is a highly focused changed with a measurable benefit in 
> use.
> 
> Compare:
> 
> * "Introduce the unwrap statement that acts like guard but is limited to 
> optionals" creates unnecessary language verbosity.
> 
> * "guard x else ", meaning "treat optional values differently than all other 
> items in a conditional list", fails because it obscures rather than adds 
> intent. Worse, it would lead to issues with Boolean optionals whose wrapped 
> value is later used within the same condition.
> 
> Xiaodi, you mentioned an alternative approach and I'd love a peek at what 
> that is.

Also with the 'guard unwrap', the following code make sense:

guard unwrap x, x == 10 else { return }

With a lone unwrap it would not.

unwrap x, x == 10 else { return }

I personally do not like shadowing, but a standalone 'unwrap!' could be of 
interest to those loving life in the shadows. Beside the shadowing itself, it 
should not be any worst than any of the other '!' usage. The feasibility of 
such depends of course on how the compiler manages its variable scoping.

On further thought, if we were to make the, sorry bad word coming, 
code-breaking change to disallow legacy shadowing 'let x=x' and force the 
shadowing to be done exclusively via this 'unwrap' keyword, it could make it 
easier for projects/companies to ban shadowing.

Dany
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-11-01 Thread Jonathan Hull via swift-evolution
I am a little worried about shadowing as well (isn’t that why we don’t allow 
‘let x’… even though it seems a bit more obvious to me with that syntax that 
there is shadowing?)

Have we considered doing exactly what people naively expect?  That is, instead 
of creating a shadow constant/variable, we have unwrap cause the variable to be 
implicitly unwrapped within the scope of the if/guard statement?  In other 
words, it is still the same variable, but it has been safely implicitly 
unwrapped, so you don’t have to worry about the optional.  The compiler should 
be able to optimize well enough with the knowledge it has (that it is actually 
non-nil… especially if it isn’t modified in that scope) that it shouldn’t add a 
performance hit...

Thanks,
Jon

> -1 on
> 
> if unwrap myValue { ... }
> 
> 
> In my opinion, *shadowing names is an anti-pattern,* so making it easier
> isn't something we should encourage. Detailed examples, shall you wish, are
> below.
> 
> Consider a developer who is suddenly able to change all employment
> relationships in the company.
> He's happily coding a function that should guarantee him a boss-free
> lifestyle:
> 
> class Employee {
> var currentSupervisor: Employee?
> 
> // Precondition: you can do whatever you want :)
> // Requirements: currentSupervisor == nil at the end
> func fireYourBoss() {
> if unwrap currentSupervisor {
> company.goToMeeting() // <- anything can happen on a meeting
> company.fire(currentSupervisor) // <- firing a manager
> nullifies the supervisor relationship
> // Now I definitely have currentSupervisor == nil... or do I?
> }
> }
> }
> 
> This code contains a design problem: the local variable bound to
> currentSupervisor name shadows the instance property with the same name.
> The unwrap operator guarantees that the values bound to those names are
> equal in the beginning of the then-block; however, there is no reason to
> think that this will hold after company.goToMeeting().
> 
> Compare this to how this code will read without the shadowing:
> 
> if let bad_boss = currentSupervisor {
> company.goToMeeting()
> company.fire(bad_boss)
> }
> 
> It is much clearer in this case what happens – the person being fired is
> the old value of currentSupervisor. Since the problem is now clearly
> diagnozed, the code can now be improved to guarantee the blissful future,
> for example as follows
> 
> if let bad_boss = currentSupervisor {
> company.goToMeeting()
> if let another_boss = currentSupervisor {
> company.fire(another_boss)
> }
> }
> 
> Similarly, in general, shadowing is a big source of bugs and should be
> avoided in all cases where the shadowed and shadowing variable's values can
> be different.
> 
> In multithreaded programs it's basically only safe to shadow those names
> that are bound with let, so we could implement unwrap for those, but it's
> unclear what the big benefits of it are.
> 
> Thanks for reading up to here,
> Ilya.

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-11-01 Thread Florent Vilmart via swift-evolution
It seems that we settle on a relatively 'long' keyword 'unwrap', 
Did we consider a ? prefix operator?

As we use the ? postfix in order to safely unpack, we could as well introduce 
prefix ?

guard ?foo, ?bar else { return }

It is 'expressive', and makes me think 'do I have?'. 

It is less technically / semantically correct than unwrap, but also gives a 
playful twist, making those guard/if condition lines more concise.

it would play correctly decently with:

guard var ?foo, var ?bar else { return }


-- 
Florent Vilmart

Le 1 novembre 2016 à 19:08:11, ilya via swift-evolution 
(swift-evolution@swift.org) a écrit:

> a) guard let foobar = foobar else { … }
> b) guard unwrap foobar else { … }

I would argue for
c) guard let reallyFoobar = foobar else { … }

(or perhaps guard let foobar_ = foobar else { … } )

That way one can use both an optional foobar and non-optional "unwrapped value 
of foobar at the moment of guard" without any possibility of mixing those two 
(and without violating DRY).

Ilya.

On Wed, Oct 26, 2016 at 6:38 PM Chris Lattner via swift-evolution 
 wrote:
On Oct 26, 2016, at 8:58 AM, Erica Sadun via swift-evolution 
 wrote:
On Oct 26, 2016, at 5:40 AM, David Goodine via swift-evolution 
 wrote:

Hey all,

As usual, apologies if this horse was beaten ages ago before I joined the 
mailing list, but thought I would bring this up.

Yes, this has thoroughly been beaten to death.  It is also outside the scope of 
Swift 4 stage 1.  That said, it is such a glaring problem that we’ll have to 
deal with it at some point.

I was typing the above (for the hundredth time) the other day and I was 
wondering whether it might be worth considering offering a shorter syntax:

guard let x, y, z else {…}

This specific syntax is commonly requested.  The problem with this is that it 
provides no useful information about what is actually going on: it sacrifices 
clarity to get terseness, a specific non-goal of Swift.


Erica says:
Your initial suggestion doesn't work as overloading "let" confuses rather than 
clarifies this process. In February, I brought up `bind x` to mean 
"conditionally bind x to x, and produce a conditional fail if that's not 
possible", with the hope that "bind self" could be used in closures. Under that 
scheme your example would read:

guard bind x, bind y, bind z else { … }

To me, this is the most promising direction, but I’d suggest the use of 
“unwrap" as the keyword.  If you compare these two:

a) guard let foobar = foobar else { … }
b) guard unwrap foobar else { … }

I think that b) wins by virtue of eliminating repetition ("foobar = foobar" 
fails DRY principles), but retains clarity by introducing a word into the 
grammar that people already commonly know and use, and which is googlable if 
they don’t.

This also gives us the conceptual hook to make the “unwrapping an optional” 
behavior (which occurs with if let, optional chaining, etc) be something that 
could be extended to other similar user defined types, such as a Result type.

-Chris

___
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


signature.asc
Description: Message signed with OpenPGP using AMPGpg
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-11-01 Thread ilya via swift-evolution
> a) guard let foobar = foobar else { … }
> b) guard unwrap foobar else { … }

I would argue for
c) guard let reallyFoobar = foobar else { … }

(or perhaps guard let foobar_ = foobar else { … } )

That way one can use both an optional foobar and non-optional "unwrapped
value of foobar at the moment of guard" without any possibility of mixing
those two (and without violating DRY).

Ilya.

On Wed, Oct 26, 2016 at 6:38 PM Chris Lattner via swift-evolution <
swift-evolution@swift.org> wrote:

> On Oct 26, 2016, at 8:58 AM, Erica Sadun via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> On Oct 26, 2016, at 5:40 AM, David Goodine via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> Hey all,
>
> As usual, apologies if this horse was beaten ages ago before I joined the
> mailing list, but thought I would bring this up.
>
>
> Yes, this has thoroughly been beaten to death.  It is also outside the
> scope of Swift 4 stage 1.  That said, it is such a glaring problem that
> we’ll have to deal with it at some point.
>
> I was typing the above (for the hundredth time) the other day and I was
> wondering whether it might be worth considering offering a shorter syntax:
>
> guard let x, y, z else {…}
>
>
> This specific syntax is commonly requested.  The problem with this is that
> it provides no useful information about what is actually going on: it
> sacrifices clarity to get terseness, a specific non-goal of Swift.
>
>
> Erica says:
>
> Your initial suggestion doesn't work as overloading "let" confuses rather
> than clarifies this process. In February, I brought up `bind x` to mean
> "conditionally bind x to x, and produce a conditional fail if that's not
> possible", with the hope that "bind self" could be used in closures. Under
> that scheme your example would read:
>
> guard bind x, bind y, bind z else { … }
>
>
> To me, this is the most promising direction, but I’d suggest the use of
> “unwrap" as the keyword.  If you compare these two:
>
> a) guard let foobar = foobar else { … }
> b) guard unwrap foobar else { … }
>
> I think that b) wins by virtue of eliminating repetition ("foobar =
> foobar" fails DRY principles), but retains clarity by introducing a word
> into the grammar that people already commonly know and use, and which is
> googlable if they don’t.
>
> This also gives us the conceptual hook to make the “unwrapping an
> optional” behavior (which occurs with if let, optional chaining, etc) be
> something that could be extended to other similar user defined types, such
> as a Result type.
>
> -Chris
>
> ___
> 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


Re: [swift-evolution] guard let x = x

2016-11-01 Thread Nevin Brackett-Rozinsky via swift-evolution
I just realized something we can already do *now* (albeit with a lot of
boilerplate) that looks really sleek at the point of use. For example:

let json = JSON.number(4)

if let n = json.number {
// n is a Double here
}

guard let s = json.string else {
return
}

Making this work is actually quite straightforward, and simply requires
extending the enum with a property for each unwrappable case, which returns
an Optional of the associated value or nil if it is a different case.

If we had a way to eliminate the boilerplate, such as an “@unwrappable”
attribute or a magic “Unwrappable” protocol that would cause the complier
to generate the requisite properties, then it might entirely obviate the
need for an “unwrap” keyword, or any change to pattern matching at all.

Here is what it takes to make your JSON enum behave as I describe:

extension JSON {
var string: String? {
if case let .string(x) = self { return x }
return nil
}

var number: Double? {
if case let .number(x) = self { return x }
return nil
}

var boolean: Bool? {
if case let .boolean(x) = self { return x }
return nil
}

var array: [JSON]? {
if case let .array(x) = self { return x }
return nil
}

var dictionary: [String: JSON]? {
if case let .dictionary(x) = self { return x }
return nil
}
}

With compiler support this could probably avoid creating the intermediate
Optional altogether.

Nevin


On Tue, Nov 1, 2016 at 4:28 PM, Nevin Brackett-Rozinsky <
nevin.brackettrozin...@gmail.com> wrote:

> Bikeshedding here—is there any way we can make it look like this for enums?
>
> if let str = unwrap json.string {
> // str is the value from the .string enum case
> }
>
> Essentially, the “unwrap” keyword would treat the last “path component” of
> what follows as an enum case, and extract the associated value if it
> matches.
>
> This could even work with tuple destructuring, as in:
>
> guard let (theCode, someMessage) = unwrap myResponse.contact else {
> return
> }
>
> And of course we could add a sugared form for optionals to allow the
> simple, “if unwrap x { … }”.
>
> I’m not sure if this is where we want to take the idea, it’s just
> something I thought of.
>
> If we did go that route, then we might need to disallow enums from having
> properties with the same names as their cases (otherwise, eg. json.string
> would refer to a property not a case).
>
> On the other hand, a slightly different syntax would avoid that issue
> entirely—for instance,
>
> if let str = unwrap json(.string) { … }
> or
> if let str = unwrap(.string) json { … }
>
> That last one could even be sugared further when shadowing is desired:
>
> if unwrap(.string) json {
> // json is a String in here
> }
>
> Potentially worthwhile?
>
> Nevin
>
>
> On Tue, Nov 1, 2016 at 2:42 PM, Erica Sadun via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> With massive revisions. I've added Xiaodi Wu to author list. I've
>> combined all unwrapping together. I've added a much more sensible approach
>> (plus a bluesky one) for real world enumerations.
>>
>> Gist with live updates here: https://gist.github.com/
>> erica/db9ce92b3d23cb20799460f603c0ae7c
>>
>> Send feedback, I will continue to revise.
>>
>> -- E
>>
>>
>> Better Unwrapping
>>
>>- Proposal: TBD
>>- Author: Erica Sadun , Chris Lattner
>>, Xiaodi Wu  David
>>Goodine
>>- Status: TBD
>>- Review manager: TBD
>>
>>
>> 
>> Introduction
>>
>> This proposal redesigns common unwrapping tasks:
>>
>>- It introduces the unwrap keyword for optional values
>>- It re-architects guard case and if case grammar to support
>>unwrapping more complex enumerations by dropping the case keyword and
>>replacing = with ~=.
>>- It applies unwrap to non-optional values
>>
>> Swift Evolution threads:
>>
>>- guard let x = x
>>
>> 
>>- Using a bind keyword
>>
>> 
>>.
>>- Fixing pattern matching grammar
>>
>> 
>>
>>
>> 
>> Motivation
>>
>> Unwrapping values is one of the most common Swift tasks and it is
>> unnecessarily complex. This proposal simplifies this process and enhances
>> code safety and readability.
>> 
>> Optionals
>>
>> Swift lacks a safe way to bind an optional to a shadowed same-name
>> variable in condition clauses like those used in guard and if statements.
>>
>> Compare:
>>
>> guard let foo = 

Re: [swift-evolution] guard let x = x

2016-11-01 Thread Erica Sadun via swift-evolution

> On Oct 31, 2016, at 7:37 PM, Joe Groff  wrote:
> 
> Sorry for piling onto the bikeshed. We do already have a notation for testing 
> that an Optional isn't nil, `x != nil`. We could theoretically bless ` ref> != nil` as a statement condition to also unwrap the referenced 
> declaration in the scope guarded by the condition. (` is T` could 
> similarly rebind a declaration as the cast type.)
> 
> -Joe

Feels like too much magic. I'd like there to be a positive declaration of 
intent.

The tl;dr of what I posted today is:

guard unwrap anOptional else { ... } // basic optional
if unwrap .string(myString) ~= jsonObject { ... } // Non-optional object
if unwrap .contact(code, var message) ~= jsonObject { ... } // Multi-valued

if .some(let value) ~= anOptional { ... } // Pattern match operator instead of 
case
if let value? ~= anOptional { ... } // ditto

-- E


> 
>> On Oct 28, 2016, at 3:34 PM, Erica Sadun via swift-evolution 
>>  wrote:
>> 
>> 
>>> On Oct 26, 2016, at 11:39 AM, Chris Lattner via swift-evolution 
>>>  wrote:
>>> 
>>> 
 On Oct 26, 2016, at 10:23 AM, Joshua Alvarado  
 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

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-11-01 Thread ilya via swift-evolution
-1 on

if unwrap myValue { ... }


In my opinion, *shadowing names is an anti-pattern,* so making it easier
isn't something we should encourage. Detailed examples, shall you wish, are
below.

Consider a developer who is suddenly able to change all employment
relationships in the company.
He's happily coding a function that should guarantee him a boss-free
lifestyle:

class Employee {
var currentSupervisor: Employee?

// Precondition: you can do whatever you want :)
// Requirements: currentSupervisor == nil at the end
func fireYourBoss() {
if unwrap currentSupervisor {
company.goToMeeting() // <- anything can happen on a meeting
company.fire(currentSupervisor) // <- firing a manager
nullifies the supervisor relationship
// Now I definitely have currentSupervisor == nil... or do I?
}
}
}

This code contains a design problem: the local variable bound to
currentSupervisor name shadows the instance property with the same name.
The unwrap operator guarantees that the values bound to those names are
equal in the beginning of the then-block; however, there is no reason to
think that this will hold after company.goToMeeting().

Compare this to how this code will read without the shadowing:

if let bad_boss = currentSupervisor {
company.goToMeeting()
company.fire(bad_boss)
}

It is much clearer in this case what happens – the person being fired is
the old value of currentSupervisor. Since the problem is now clearly
diagnozed, the code can now be improved to guarantee the blissful future,
for example as follows

if let bad_boss = currentSupervisor {
company.goToMeeting()
if let another_boss = currentSupervisor {
company.fire(another_boss)
}
}

Similarly, in general, shadowing is a big source of bugs and should be
avoided in all cases where the shadowed and shadowing variable's values can
be different.

In multithreaded programs it's basically only safe to shadow those names
that are bound with let, so we could implement unwrap for those, but it's
unclear what the big benefits of it are.

Thanks for reading up to here,
Ilya.

On Tue, Nov 1, 2016 at 9:28 PM Nevin Brackett-Rozinsky via swift-evolution <
swift-evolution@swift.org> wrote:

> Bikeshedding here—is there any way we can make it look like this for enums?
>
> if let str = unwrap json.string {
> // str is the value from the .string enum case
> }
>
> Essentially, the “unwrap” keyword would treat the last “path component” of
> what follows as an enum case, and extract the associated value if it
> matches.
>
> This could even work with tuple destructuring, as in:
>
> guard let (theCode, someMessage) = unwrap myResponse.contact else {
> return
> }
>
> And of course we could add a sugared form for optionals to allow the
> simple, “if unwrap x { … }”.
>
> I’m not sure if this is where we want to take the idea, it’s just
> something I thought of.
>
> If we did go that route, then we might need to disallow enums from having
> properties with the same names as their cases (otherwise, eg. json.string
> would refer to a property not a case).
>
> On the other hand, a slightly different syntax would avoid that issue
> entirely—for instance,
>
> if let str = unwrap json(.string) { … }
> or
> if let str = unwrap(.string) json { … }
>
> That last one could even be sugared further when shadowing is desired:
>
> if unwrap(.string) json {
> // json is a String in here
> }
>
> Potentially worthwhile?
>
> Nevin
>
>
> On Tue, Nov 1, 2016 at 2:42 PM, Erica Sadun via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> With massive revisions. I've added Xiaodi Wu to author list. I've combined
> all unwrapping together. I've added a much more sensible approach (plus a
> bluesky one) for real world enumerations.
>
> Gist with live updates here:
> https://gist.github.com/erica/db9ce92b3d23cb20799460f603c0ae7c
>
> Send feedback, I will continue to revise.
>
> -- E
>
>
> Better Unwrapping
>
>- Proposal: TBD
>- Author: Erica Sadun , Chris Lattner
>, Xiaodi Wu  David
>Goodine
>- Status: TBD
>- Review manager: TBD
>
>
> 
> Introduction
>
> This proposal redesigns common unwrapping tasks:
>
>- It introduces the unwrap keyword for optional values
>- It re-architects guard case and if case grammar to support
>unwrapping more complex enumerations by dropping the case keyword and
>replacing = with ~=.
>- It applies unwrap to non-optional values
>
> Swift Evolution threads:
>
>- guard let x = x
>
> 
>- Using a bind keyword
>
> 
> 

Re: [swift-evolution] guard let x = x

2016-11-01 Thread Nevin Brackett-Rozinsky via swift-evolution
Bikeshedding here—is there any way we can make it look like this for enums?

if let str = unwrap json.string {
// str is the value from the .string enum case
}

Essentially, the “unwrap” keyword would treat the last “path component” of
what follows as an enum case, and extract the associated value if it
matches.

This could even work with tuple destructuring, as in:

guard let (theCode, someMessage) = unwrap myResponse.contact else {
return
}

And of course we could add a sugared form for optionals to allow the
simple, “if unwrap x { … }”.

I’m not sure if this is where we want to take the idea, it’s just something
I thought of.

If we did go that route, then we might need to disallow enums from having
properties with the same names as their cases (otherwise, eg. json.string
would refer to a property not a case).

On the other hand, a slightly different syntax would avoid that issue
entirely—for instance,

if let str = unwrap json(.string) { … }
or
if let str = unwrap(.string) json { … }

That last one could even be sugared further when shadowing is desired:

if unwrap(.string) json {
// json is a String in here
}

Potentially worthwhile?

Nevin


On Tue, Nov 1, 2016 at 2:42 PM, Erica Sadun via swift-evolution <
swift-evolution@swift.org> wrote:

> With massive revisions. I've added Xiaodi Wu to author list. I've combined
> all unwrapping together. I've added a much more sensible approach (plus a
> bluesky one) for real world enumerations.
>
> Gist with live updates here: https://gist.github.com/erica/
> db9ce92b3d23cb20799460f603c0ae7c
>
> Send feedback, I will continue to revise.
>
> -- E
>
>
> Better Unwrapping
>
>- Proposal: TBD
>- Author: Erica Sadun , Chris Lattner
>, Xiaodi Wu  David
>Goodine
>- Status: TBD
>- Review manager: TBD
>
>
> 
> Introduction
>
> This proposal redesigns common unwrapping tasks:
>
>- It introduces the unwrap keyword for optional values
>- It re-architects guard case and if case grammar to support
>unwrapping more complex enumerations by dropping the case keyword and
>replacing = with ~=.
>- It applies unwrap to non-optional values
>
> Swift Evolution threads:
>
>- guard let x = x
>
> 
>- Using a bind keyword
>
> 
>.
>- Fixing pattern matching grammar
>
> 
>
> 
> Motivation
>
> Unwrapping values is one of the most common Swift tasks and it is
> unnecessarily complex. This proposal simplifies this process and enhances
> code safety and readability.
> 
> Optionals
>
> Swift lacks a safe way to bind an optional to a shadowed same-name
> variable in condition clauses like those used in guard and if statements.
>
> Compare:
>
> guard let foo = foo else { ... } // redundantguard case let .some(foo) = foo 
> else { ... } // overly complexguard unwrap foo else { ... } // simple
>
>
>- Using "foo = foo" fails DRY principles
>.
>- Using case let .some(foo) = foo or case .some(let foo) = foo fails KISS
>principles 
>
> unwrap guarantees that an unwrapped shadow uses the same name as the
> wrapped version. This ensures that a conditionally-bound item cannot
> accidentally shadow another symbol. It eliminates repetition and retains
> clarity. Further, the unwrap keyword is common, simple to understand, and
> easy to search for if Swift users are unfamiliar with it.
>
> In the rare case that the binding is variable, use the re-imagined var ~=
>  syntax
>
> General
> Enumerations
>
> Swift's guard case and if case statements stand out for their unintuitive
> approach. They look like assignment statements but they are *not* assignment
> statements. This violates the principle of least astonishment
> . This
> presents difficulties for new language adopters by combining several
> concepts in a confusing form. They are arguably underutilized by language
> experts.
>
> The status quo for the = operator is iteratively built up in this fashion:
>
>- = performs assignment
>- let x = performs binding
>- if let x = performs conditional binding on optionals
>- if case .foo(let x) = and if case let .foo(x) = performs conditional
>binding on enumerations *and* applies pattern matching
>
> Both 

Re: [swift-evolution] guard let x = x

2016-11-01 Thread Erica Sadun via swift-evolution
With massive revisions. I've added Xiaodi Wu to author list. I've combined all 
unwrapping together. I've added a much more sensible approach (plus a bluesky 
one) for real world enumerations.

Gist with live updates here: 
https://gist.github.com/erica/db9ce92b3d23cb20799460f603c0ae7c 


Send feedback, I will continue to revise.

-- E


Better Unwrapping

Proposal: TBD
Author: Erica Sadun , Chris Lattner 
, Xiaodi Wu  David Goodine
Status: TBD
Review manager: TBD
 
Introduction

This proposal redesigns common unwrapping tasks:

It introduces the unwrap keyword for optional values
It re-architects guard case and if case grammar to support unwrapping more 
complex enumerations by dropping the case keyword and replacing = with ~=.
It applies unwrap to non-optional values
Swift Evolution threads:

guard let x = x 

Using a bind keyword 
.
Fixing pattern matching grammar 

 
Motivation

Unwrapping values is one of the most common Swift tasks and it is unnecessarily 
complex. This proposal simplifies this process and enhances code safety and 
readability.

 
Optionals

Swift lacks a safe way to bind an optional to a shadowed same-name variable in 
condition clauses like those used in guard and if statements.

Compare:

guard let foo = foo else { ... } // redundant
guard case let .some(foo) = foo else { ... } // overly complex

guard unwrap foo else { ... } // simple
Using "foo = foo" fails DRY principles 
. 
Using case let .some(foo) = foo or case .some(let foo) = foo fails KISS 
principles 
unwrap guarantees that an unwrapped shadow uses the same name as the wrapped 
version. This ensures that a conditionally-bound item cannot accidentally 
shadow another symbol. It eliminates repetition and retains clarity. Further, 
the unwrap keyword is common, simple to understand, and easy to search for if 
Swift users are unfamiliar with it.

In the rare case that the binding is variable, use the re-imagined var ~= syntax

 
General
 Enumerations

Swift's guard case and if case statements stand out for their unintuitive 
approach. They look like assignment statements but they are not assignment 
statements. This violates the principle of least astonishment 
. This presents 
difficulties for new language adopters by combining several concepts in a 
confusing form. They are arguably underutilized by language experts.

The status quo for the = operator is iteratively built up in this fashion:

= performs assignment
let x = performs binding
if let x = performs conditional binding on optionals
if case .foo(let x) = and if case let .foo(x) = performs conditional binding on 
enumerations and applies pattern matching
Both guard case and if case statements perform simultaneous pattern matching 
and conditional binding. Here are examples demonstrating their use in current 
Swift:

enum Result { case success(T), error(Error) }

// valid Swift
guard case let .success(value) = result
else { ... }

// valid Swift
guard case .success(let value) = result
else { ... }
The problems with guard case and if case include:

The = operator looks like assignment and not like pattern matching (~=). 
The case layout is both too close to a switch's case but doesn't follow its 
syntax. In switch, a case is followed by a colon, not an equal sign.
Using the case syntax is unneccessarily wordy. It incorporates case, =, and 
optionally let/var assignments.
 
Indirect
 and Direct Pattern Matching

Swift uses two kinds of pattern matching.

Indirect pattern matching such as the kind you see in switch and for statements 
receives an argument in from the statement structure. The argument is not 
mentioned directly in the case:

switch value {
case .foo(let x): ... use x ...
...
}

for case .foo(let x) in collection { ... }
Direct pattern matching including guard/if statements and with the pattern 
matching operator place the argument to be matched to the right of an operator, 
either = or ~=. The argument is explicitly mentioned:

if case .foo(let x) = value { ... use x ... }
if 100...200 ~= value { 

Re: [swift-evolution] guard let x = x

2016-11-01 Thread Martin Waitz via swift-evolution
Hi,

> 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.

Of course, we could specify something like: „after checking that some Optional 
is not nil, it is treated as an implicitly unwrapped optional“.

— Martin
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-11-01 Thread Nicholas Maccharoli via swift-evolution
Sorry I wrote that last email off a little too fast, my head was still
stuck in legacy Swift land.

by `if let a = a, b = b, c = c { ... }` I meant to say `if let a = a, let b
= b, let c = c { ... }`

And here:

> something like `if given a, b, c, c { ... }` looks like it could be an
accidental typed repeat of `a` as much as it could mean `if given a, b, c,
c == true { ... }`

I meant to say

something like `if given a, b, c, c { ... }` looks like it could be an
accidental typed repeat of `c` as much as it could mean `if given a, b, c,
c == true { ... }`

Sorry!

On Tue, Nov 1, 2016 at 6:18 PM, Muse M via swift-evolution <
swift-evolution@swift.org> wrote:

> In Rust lang, it uses .unwrap and b can be a non-nil variable.
>
> guard a.unwrap, b, c.unwrap else {
> }
>
> On Tuesday, November 1, 2016, Nicholas Maccharoli via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> I like the idea of drying up something like `guard let x = x, let y = y,
>> let z = z else { return }`
>> Using `guard unwrap` would surely be an improvement but still maybe
>> something like `guard unwrap x, unwrap y, unwrap x else { return }`
>> although very clear in intent is a bit bulky.
>>
>> What about something like introducing a `given` / `given-where` clause
>> for `if` and `guard` ensuring an optional  is non-nil and shadowing the
>> variable with an unwrapped variable of the same name.
>>
>> one way might be:
>>
>> guard given a, b, c else { return }
>>
>> or with an attached conditional:
>>
>> guard given a, b, c where a > b else { return }
>>
>> for dealing with long if-lets you could do something like:
>>
>> if given a, b, c where a > b { ... }
>>
>> Instead of if let a = a, b = b, c = c, a > b { ... }
>>
>> The `where` clause does not need to be an actual keyword, it can just be
>> a trailing boolean expression but
>> maybe having it makes things like unwrapping and testing that a variable
>> evaluates to `true` more distinguishable.
>>
>> something like `if given a, b, c, c { ... }` looks like it could be an
>> accidental typed repeat of `a` as much as it could mean `if given a, b, c,
>> c == true { ... }`
>>
>> `if given a, b, c where c { ... }` might read a little easier.
>>
>> Just a thought.
>>
>> - Nick
>>
>>
>>
>>
>>
>> On Tue, Nov 1, 2016 at 4:26 PM, Goffredo Marocchi via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>> Agreed, a change like this would make sense :).
>>>
>>> Sent from my iPhone
>>>
>>> > On 1 Nov 2016, at 01:58, Joe Groff via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>> >
>>> >
>>> >> On Oct 31, 2016, at 6:46 PM, Xiaodi Wu  wrote:
>>> >>
>>> >> On Mon, Oct 31, 2016 at 8:37 PM, Joe Groff via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>> >> Sorry for piling onto the bikeshed. We do already have a notation for
>>> testing that an Optional isn't nil, `x != nil`. We could theoretically
>>> bless ` != nil` as a statement condition to also unwrap the
>>> referenced declaration in the scope guarded by the condition. (`
>>> is T` could similarly rebind a declaration as the cast type.)
>>> >>
>>> >> I think we'd have some weirdness. For instance:
>>> >>
>>> >> ```
>>> >> guard x != nil || x == y else { break }
>>> >> // oops, now x isn't unwrapped anymore because I added a condition
>>> >> ```
>>> >>
>>> >> Also, it'd be unexpected for it to be blessed for guard but not if:
>>> >>
>>> >> ```
>>> >> if x != nil {
>>> >>  // is x unwrapped here?
>>> >>  // if so, this would be source-breaking...
>>> >>  // if not, it would be surprisingly inconsistent
>>> >> }
>>> >> ```
>>> >
>>> > `if` and `guard` share the same condition behavior. It's true that
>>> there would be limitations on when the unwrapping behavior applies, but QoI
>>> could potentially help. Users seem to be able to work within similar
>>> constraints in gradually-typed languages like Typescript that work
>>> similarly, and there's quite a lot of Swift users who are surprised at
>>> first that Swift doesn't behave similarly.
>>> >
>>> > -Joe
>>> > ___
>>> > 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


Re: [swift-evolution] guard let x = x

2016-11-01 Thread Muse M via swift-evolution
In Rust lang, it uses .unwrap and b can be a non-nil variable.

guard a.unwrap, b, c.unwrap else {
}

On Tuesday, November 1, 2016, Nicholas Maccharoli via swift-evolution <
swift-evolution@swift.org> wrote:

> I like the idea of drying up something like `guard let x = x, let y = y,
> let z = z else { return }`
> Using `guard unwrap` would surely be an improvement but still maybe
> something like `guard unwrap x, unwrap y, unwrap x else { return }`
> although very clear in intent is a bit bulky.
>
> What about something like introducing a `given` / `given-where` clause for
> `if` and `guard` ensuring an optional  is non-nil and shadowing the
> variable with an unwrapped variable of the same name.
>
> one way might be:
>
> guard given a, b, c else { return }
>
> or with an attached conditional:
>
> guard given a, b, c where a > b else { return }
>
> for dealing with long if-lets you could do something like:
>
> if given a, b, c where a > b { ... }
>
> Instead of if let a = a, b = b, c = c, a > b { ... }
>
> The `where` clause does not need to be an actual keyword, it can just be a
> trailing boolean expression but
> maybe having it makes things like unwrapping and testing that a variable
> evaluates to `true` more distinguishable.
>
> something like `if given a, b, c, c { ... }` looks like it could be an
> accidental typed repeat of `a` as much as it could mean `if given a, b, c,
> c == true { ... }`
>
> `if given a, b, c where c { ... }` might read a little easier.
>
> Just a thought.
>
> - Nick
>
>
>
>
>
> On Tue, Nov 1, 2016 at 4:26 PM, Goffredo Marocchi via swift-evolution <
> swift-evolution@swift.org
> > wrote:
>
>> Agreed, a change like this would make sense :).
>>
>> Sent from my iPhone
>>
>> > On 1 Nov 2016, at 01:58, Joe Groff via swift-evolution <
>> swift-evolution@swift.org
>> > wrote:
>> >
>> >
>> >> On Oct 31, 2016, at 6:46 PM, Xiaodi Wu > > wrote:
>> >>
>> >> On Mon, Oct 31, 2016 at 8:37 PM, Joe Groff via swift-evolution <
>> swift-evolution@swift.org
>> > wrote:
>> >> Sorry for piling onto the bikeshed. We do already have a notation for
>> testing that an Optional isn't nil, `x != nil`. We could theoretically
>> bless ` != nil` as a statement condition to also unwrap the
>> referenced declaration in the scope guarded by the condition. (`
>> is T` could similarly rebind a declaration as the cast type.)
>> >>
>> >> I think we'd have some weirdness. For instance:
>> >>
>> >> ```
>> >> guard x != nil || x == y else { break }
>> >> // oops, now x isn't unwrapped anymore because I added a condition
>> >> ```
>> >>
>> >> Also, it'd be unexpected for it to be blessed for guard but not if:
>> >>
>> >> ```
>> >> if x != nil {
>> >>  // is x unwrapped here?
>> >>  // if so, this would be source-breaking...
>> >>  // if not, it would be surprisingly inconsistent
>> >> }
>> >> ```
>> >
>> > `if` and `guard` share the same condition behavior. It's true that
>> there would be limitations on when the unwrapping behavior applies, but QoI
>> could potentially help. Users seem to be able to work within similar
>> constraints in gradually-typed languages like Typescript that work
>> similarly, and there's quite a lot of Swift users who are surprised at
>> first that Swift doesn't behave similarly.
>> >
>> > -Joe
>> > ___
>> > 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


Re: [swift-evolution] guard let x = x

2016-11-01 Thread Haravikk via swift-evolution

> On 1 Nov 2016, at 01:37, Joe Groff via swift-evolution 
>  wrote:
> 
> Sorry for piling onto the bikeshed. We do already have a notation for testing 
> that an Optional isn't nil, `x != nil`. We could theoretically bless ` ref> != nil` as a statement condition to also unwrap the referenced 
> declaration in the scope guarded by the condition. (` is T` could 
> similarly rebind a declaration as the cast type.)
> 
> -Joe

Was about the say the same thing; this is basically the same idea as type 
narrowing, which is something I think that Swift still really needs, and can be 
used to solve this problem without the need for new syntax, enabling things 
like:

if (a is Foo) { a.someMethodSpecificToFoo() }
if (a != nil) { a.someMethodWithoutUnwrapping() }

While I've often suggested keywords to solve other problems, I'm not sure if we 
really need one to solve this use-case!___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-11-01 Thread Goffredo Marocchi via swift-evolution
Agreed, a change like this would make sense :).

Sent from my iPhone

> On 1 Nov 2016, at 01:58, Joe Groff via swift-evolution 
>  wrote:
> 
> 
>> On Oct 31, 2016, at 6:46 PM, Xiaodi Wu  wrote:
>> 
>> On Mon, Oct 31, 2016 at 8:37 PM, Joe Groff via swift-evolution 
>>  wrote:
>> Sorry for piling onto the bikeshed. We do already have a notation for 
>> testing that an Optional isn't nil, `x != nil`. We could theoretically bless 
>> ` != nil` as a statement condition to also unwrap the referenced 
>> declaration in the scope guarded by the condition. (` is T` could 
>> similarly rebind a declaration as the cast type.)
>> 
>> I think we'd have some weirdness. For instance:
>> 
>> ```
>> guard x != nil || x == y else { break }
>> // oops, now x isn't unwrapped anymore because I added a condition
>> ```
>> 
>> Also, it'd be unexpected for it to be blessed for guard but not if:
>> 
>> ```
>> if x != nil {
>>  // is x unwrapped here?
>>  // if so, this would be source-breaking...
>>  // if not, it would be surprisingly inconsistent
>> }
>> ```
> 
> `if` and `guard` share the same condition behavior. It's true that there 
> would be limitations on when the unwrapping behavior applies, but QoI could 
> potentially help. Users seem to be able to work within similar constraints in 
> gradually-typed languages like Typescript that work similarly, and there's 
> quite a lot of Swift users who are surprised at first that Swift doesn't 
> behave similarly.
> 
> -Joe
> ___
> 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


Re: [swift-evolution] guard let x = x

2016-10-31 Thread Charlie Monroe via swift-evolution
Isn't this ambiguous in case x is Bool? (Optional)? Do you mean to 
force-unwrap the bool and use it as a condition, or should the x be unwrapped 
(in which case it can be false)?

Not a common case likely, but it is nevertheless something to think of.

> On Nov 1, 2016, at 6:52 AM, David Sweeris via swift-evolution 
>  wrote:
> 
> Between all the talk about unwrap and nonnill and whatnot, I've kinda lost 
> track of what we're actually talking about. I think it's still about not 
> having to type variables twice in guard statements, right? Has anyone 
> suggested
>guard x! else {...}
>// x means x! now
> yet?
> 
> - Dave Sweeris
> ___
> 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


Re: [swift-evolution] guard let x = x

2016-10-31 Thread David Sweeris via swift-evolution
Between all the talk about unwrap and nonnill and whatnot, I've kinda lost 
track of what we're actually talking about. I think it's still about not having 
to type variables twice in guard statements, right? Has anyone suggested
guard x! else {...}
// x means x! now
yet?

- Dave Sweeris
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-10-31 Thread Charlie Monroe via swift-evolution

> On Nov 1, 2016, at 2:46 AM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> On Mon, Oct 31, 2016 at 8:37 PM, Joe Groff via swift-evolution 
> > wrote:
> Sorry for piling onto the bikeshed. We do already have a notation for testing 
> that an Optional isn't nil, `x != nil`. We could theoretically bless ` ref> != nil` as a statement condition to also unwrap the referenced 
> declaration in the scope guarded by the condition. (` is T` could 
> similarly rebind a declaration as the cast type.)
> 
> I think we'd have some weirdness. For instance:
> 
> ```
> guard x != nil || x == y else { break }
> // oops, now x isn't unwrapped anymore because I added a condition
> ```

This is what I suggested a few emails back, but perhaps failed to explain 
myself that well - my suggestion, however, used the "nonnil" keyword instead, 
which would prevent you from adding || condition:

guard nonnil x, x == y else { break }

To me this reads more naturally than guard unwrap x, x == y else { break }

> 
> Also, it'd be unexpected for it to be blessed for guard but not if:
> 
> ```
> if x != nil {
>   // is x unwrapped here?
>   // if so, this would be source-breaking...
>   // if not, it would be surprisingly inconsistent
> }
> ```
> 
> 
> 
> -Joe
> 
> > On Oct 28, 2016, at 3:34 PM, Erica Sadun via swift-evolution 
> > > wrote:
> >
> >
> >> On Oct 26, 2016, at 11:39 AM, Chris Lattner via swift-evolution 
> >> > wrote:
> >>
> >>
> >>> On Oct 26, 2016, at 10:23 AM, Joshua Alvarado  >>> > 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 
> > 
> >
> > -- 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 { 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 { 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@swift.org 
> > https://lists.swift.org/mailman/listinfo/swift-evolution 
> > 
> 
> 

Re: [swift-evolution] guard let x = x

2016-10-31 Thread Kenny Leung via swift-evolution
A big YES to this!

As long as "the scope guarded by the condition” means everything after the 
guard statement, and not everything inside an if statement.

-Kenny

> On Oct 31, 2016, at 6:37 PM, Joe Groff via swift-evolution 
>  wrote:
> 
> Sorry for piling onto the bikeshed. We do already have a notation for testing 
> that an Optional isn't nil, `x != nil`. We could theoretically bless ` ref> != nil` as a statement condition to also unwrap the referenced 
> declaration in the scope guarded by the condition. (` is T` could 
> similarly rebind a declaration as the cast type.)
> 
> -Joe
> 
>> On Oct 28, 2016, at 3:34 PM, Erica Sadun via swift-evolution 
>>  wrote:
>> 
>> 
>>> On Oct 26, 2016, at 11:39 AM, Chris Lattner via swift-evolution 
>>>  wrote:
>>> 
>>> 
 On Oct 26, 2016, at 10:23 AM, Joshua Alvarado  
 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
>> 
>> -- 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 { 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 { 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@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


Re: [swift-evolution] guard let x = x

2016-10-31 Thread Joe Groff via swift-evolution

> On Oct 31, 2016, at 6:46 PM, Xiaodi Wu  wrote:
> 
> On Mon, Oct 31, 2016 at 8:37 PM, Joe Groff via swift-evolution 
>  wrote:
> Sorry for piling onto the bikeshed. We do already have a notation for testing 
> that an Optional isn't nil, `x != nil`. We could theoretically bless ` ref> != nil` as a statement condition to also unwrap the referenced 
> declaration in the scope guarded by the condition. (` is T` could 
> similarly rebind a declaration as the cast type.)
> 
> I think we'd have some weirdness. For instance:
> 
> ```
> guard x != nil || x == y else { break }
> // oops, now x isn't unwrapped anymore because I added a condition
> ```
> 
> Also, it'd be unexpected for it to be blessed for guard but not if:
> 
> ```
> if x != nil {
>   // is x unwrapped here?
>   // if so, this would be source-breaking...
>   // if not, it would be surprisingly inconsistent
> }
> ```

`if` and `guard` share the same condition behavior. It's true that there would 
be limitations on when the unwrapping behavior applies, but QoI could 
potentially help. Users seem to be able to work within similar constraints in 
gradually-typed languages like Typescript that work similarly, and there's 
quite a lot of Swift users who are surprised at first that Swift doesn't behave 
similarly.

-Joe
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-10-31 Thread Xiaodi Wu via swift-evolution
On Mon, Oct 31, 2016 at 8:37 PM, Joe Groff via swift-evolution <
swift-evolution@swift.org> wrote:

> Sorry for piling onto the bikeshed. We do already have a notation for
> testing that an Optional isn't nil, `x != nil`. We could theoretically
> bless ` != nil` as a statement condition to also unwrap the
> referenced declaration in the scope guarded by the condition. (`
> is T` could similarly rebind a declaration as the cast type.)
>

I think we'd have some weirdness. For instance:

```
guard x != nil || x == y else { break }
// oops, now x isn't unwrapped anymore because I added a condition
```

Also, it'd be unexpected for it to be blessed for guard but not if:

```
if x != nil {
  // is x unwrapped here?
  // if so, this would be source-breaking...
  // if not, it would be surprisingly inconsistent
}
```



> -Joe
>
> > On Oct 28, 2016, at 3:34 PM, Erica Sadun via swift-evolution <
> swift-evolution@swift.org> wrote:
> >
> >
> >> On Oct 26, 2016, at 11:39 AM, Chris Lattner via swift-evolution <
> swift-evolution@swift.org> wrote:
> >>
> >>
> >>> On Oct 26, 2016, at 10:23 AM, Joshua Alvarado <
> alvaradojosh...@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
> >
> > -- 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 { 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 { 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@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


Re: [swift-evolution] guard let x = x

2016-10-31 Thread Joe Groff via swift-evolution
Sorry for piling onto the bikeshed. We do already have a notation for testing 
that an Optional isn't nil, `x != nil`. We could theoretically bless ` != nil` as a statement condition to also unwrap the referenced declaration 
in the scope guarded by the condition. (` is T` could similarly 
rebind a declaration as the cast type.)

-Joe

> On Oct 28, 2016, at 3:34 PM, Erica Sadun via swift-evolution 
>  wrote:
> 
> 
>> On Oct 26, 2016, at 11:39 AM, Chris Lattner via swift-evolution 
>>  wrote:
>> 
>> 
>>> On Oct 26, 2016, at 10:23 AM, Joshua Alvarado  
>>> 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
> 
> -- 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 { 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 { 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@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


Re: [swift-evolution] guard let x = x

2016-10-31 Thread David Goodine via swift-evolution
One thing I really like that Erica mentioned in the earlier discussion is the 
case of guard unwrapping [weak self] in closures. I've taken to creating an 
alternate self (guard let ss = self else { return }) constant and using that. 
But it always felt inelegant. The proposed case works without falling prey to 
the protection against redefining self that the compiler still needs to enforce 
and does it in a way that's clear and concise.  

Sent from my iPhone

> On Oct 31, 2016, at 6:46 PM, William Sumner via swift-evolution 
>  wrote:
> 
> 
>> On Oct 31, 2016, at 3:44 PM, Erica Sadun via swift-evolution 
>>  wrote:
>> 
>> 
>>> On Oct 31, 2016, at 1:51 PM, Xiaodi Wu via swift-evolution 
>>>  wrote:
>>> 
>>> An alternative that would seem to satisfy some objections is to have a 
>>> distinct "unwrap" statement--as in: "unwrap x else { ... }".
>> 
>> I'd be against this alternative as it is doing the work of a guard statement 
>> (including the "must exit scope" rule) with a new keyword and unneeded 
>> redundancy.
>> 
>> Adding "unwrap" is local. It performs one very common task with added safety 
>> (avoids unintended shadow effects) and introduces succinctness and clarity. 
>> In other words, it is a highly focused changed with a measurable benefit in 
>> use.
>> 
>> Compare:
>> 
>> * "Introduce the unwrap statement that acts like guard but is limited to 
>> optionals" creates unnecessary language verbosity.
>> 
>> * "guard x else ", meaning "treat optional values differently than all other 
>> items in a conditional list", fails because it obscures rather than adds 
>> intent. Worse, it would lead to issues with Boolean optionals whose wrapped 
>> value is later used within the same condition.
>> 
>> Xiaodi, you mentioned an alternative approach and I'd love a peek at what 
>> that is.
>> 
>> — Erica
> 
> Your proposed form of unwrap naturally works in multiple places with clear 
> readability:
> 
> var foo: Any?
> if unwrap foo {}
> 
> while unwrap foo {}
> 
> guard unwrap foo else { return }
> 
> Preston
> ___
> 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


Re: [swift-evolution] guard let x = x

2016-10-31 Thread William Sumner via swift-evolution

> On Oct 31, 2016, at 3:44 PM, Erica Sadun via swift-evolution 
>  wrote:
> 
> 
>> On Oct 31, 2016, at 1:51 PM, Xiaodi Wu via swift-evolution 
>>  wrote:
>> 
>> An alternative that would seem to satisfy some objections is to have a 
>> distinct "unwrap" statement--as in: "unwrap x else { ... }".
> 
> I'd be against this alternative as it is doing the work of a guard statement 
> (including the "must exit scope" rule) with a new keyword and unneeded 
> redundancy.
> 
> Adding "unwrap" is local. It performs one very common task with added safety 
> (avoids unintended shadow effects) and introduces succinctness and clarity. 
> In other words, it is a highly focused changed with a measurable benefit in 
> use.
> 
> Compare:
> 
> * "Introduce the unwrap statement that acts like guard but is limited to 
> optionals" creates unnecessary language verbosity.
> 
> * "guard x else ", meaning "treat optional values differently than all other 
> items in a conditional list", fails because it obscures rather than adds 
> intent. Worse, it would lead to issues with Boolean optionals whose wrapped 
> value is later used within the same condition.
> 
> Xiaodi, you mentioned an alternative approach and I'd love a peek at what 
> that is.
> 
> — Erica

Your proposed form of unwrap naturally works in multiple places with clear 
readability:

var foo: Any?
if unwrap foo {}

while unwrap foo {}

guard unwrap foo else { return }

Preston
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-10-31 Thread Xiaodi Wu via swift-evolution
On Mon, Oct 31, 2016 at 4:44 PM, Erica Sadun  wrote:

>
> > On Oct 31, 2016, at 1:51 PM, Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
> >
> > An alternative that would seem to satisfy some objections is to have a
> distinct "unwrap" statement--as in: "unwrap x else { ... }".
>
> I'd be against this alternative as it is doing the work of a guard
> statement (including the "must exit scope" rule) with a new keyword and
> unneeded redundancy.
>
> Adding "unwrap" is local. It performs one very common task with added
> safety (avoids unintended shadow effects) and introduces succinctness and
> clarity. In other words, it is a highly focused changed with a measurable
> benefit in use.
>

Sure, I have no beef with `guard unwrap`. My point was that, if there's a
push for a more succinct statement, it must be `unwrap x` and not `guard x`
or `guard let x` for the same reasons we've discussed above.


> Compare:
>
> * "Introduce the unwrap statement that acts like guard but is limited to
> optionals" creates unnecessary language verbosity.
>
> * "guard x else ", meaning "treat optional values differently than all
> other items in a conditional list", fails because it obscures rather than
> adds intent. Worse, it would lead to issues with Boolean optionals whose
> wrapped value is later used within the same condition.
>
> Xiaodi, you mentioned an alternative approach and I'd love a peek at what
> that is.
>

Not for unwrapping; for enums. I'll write you offlist :)


> -- Erica
>
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-10-31 Thread Erica Sadun via swift-evolution

> On Oct 31, 2016, at 1:51 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> An alternative that would seem to satisfy some objections is to have a 
> distinct "unwrap" statement--as in: "unwrap x else { ... }".

I'd be against this alternative as it is doing the work of a guard statement 
(including the "must exit scope" rule) with a new keyword and unneeded 
redundancy.

Adding "unwrap" is local. It performs one very common task with added safety 
(avoids unintended shadow effects) and introduces succinctness and clarity. In 
other words, it is a highly focused changed with a measurable benefit in use.

Compare:

* "Introduce the unwrap statement that acts like guard but is limited to 
optionals" creates unnecessary language verbosity.

* "guard x else ", meaning "treat optional values differently than all other 
items in a conditional list", fails because it obscures rather than adds 
intent. Worse, it would lead to issues with Boolean optionals whose wrapped 
value is later used within the same condition.

Xiaodi, you mentioned an alternative approach and I'd love a peek at what that 
is.

-- Erica


___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-10-31 Thread Pyry Jahkola via swift-evolution

> On 31 Oct 2016, Xiaodi Wu wrote:
> 
> Don't we currently have "for x in y" and "for var x in y"? So, we could have 
> "unwrap x" and "unwrap var x".
> 
> And since unwrap wouldn't allow arbitrary Boolean expressions at the front 
> like if and guard statements do, it could use the where clause like for loops 
> do.

You're right. I'd forgotten about that. I found out you can even place the 
`var` keyword inside a tuple pattern where only one variable is going to be 
modified locally:

for (var i, c) in "foobar".characters.enumerated() {
  i += 1  // pretty contrived example
  print(i, c)
}

— Pyry

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-10-31 Thread Xiaodi Wu via swift-evolution
Don't we currently have "for x in y" and "for var x in y"? So, we could
have "unwrap x" and "unwrap var x".

And since unwrap wouldn't allow arbitrary Boolean expressions at the front
like if and guard statements do, it could use the where clause like for
loops do.

On Mon, Oct 31, 2016 at 14:58 Pyry Jahkola  wrote:

>
> On 31 Oct 2016, Xiaodi Wu wrote:
>
> An alternative that would seem to satisfy some objections is to have a
> distinct "unwrap" statement--as in: "unwrap x else { ... }".
>
>
> True. The `*let*`, on the other hand, has the minor upside that it's
> naturally substituted with `*var*` where in-place mutation is needed:
>
> *guard let* value, *var* collection *else* { ... }
> collection.append(value)
> // ...
>
> Disclaimer: I don't know if this is a realistic usage scenario but it
> seems more natural to Swift, in my view.
>
> — Pyry
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-10-31 Thread Pyry Jahkola via swift-evolution

> On 31 Oct 2016, Xiaodi Wu wrote:
> 
> An alternative that would seem to satisfy some objections is to have a 
> distinct "unwrap" statement--as in: "unwrap x else { ... }".

True. The `let`, on the other hand, has the minor upside that it's naturally 
substituted with `var` where in-place mutation is needed:

guard let value, var collection else { ... }
collection.append(value)
// ...

Disclaimer: I don't know if this is a realistic usage scenario but it seems 
more natural to Swift, in my view.

— Pyry

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-10-31 Thread Charlie Monroe via swift-evolution
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  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  > 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 
>> > 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 > > 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 
>> > wrote:
>> 
>>> Because "guard" already means something...
>>> 
>>> 
>>> On Mon, Oct 31, 2016 at 13:45 Kenny Leung via swift-evolution 
>>> > 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 >> > > 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 
>>> >> > 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 
>>> >>> > wrote:
>>> >>>
>>> >>>
>>>  On Oct 26, 2016, at 11:39 AM, Chris Lattner via swift-evolution 
>>>  > wrote:
>>> 
>>> 
>>> > On Oct 26, 2016, at 10:23 AM, Joshua Alvarado 
>>> > > 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 
>>> >>> 
>>> >>>
>>> >>> -- 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 

Re: [swift-evolution] guard let x = x

2016-10-31 Thread Xiaodi Wu via swift-evolution
An alternative that would seem to satisfy some objections is to have a
distinct "unwrap" statement--as in: "unwrap x else { ... }".
On Mon, Oct 31, 2016 at 14:49 Pyry Jahkola via swift-evolution <
swift-evolution@swift.org> wrote:

> Going back to the originating message of this thread. This idea (or a
> variant thereof) has been mentioned in the list of Commonly Rejected
> Proposals (2nd last bullet under Control Flow, Closures, Optional
> Binding, and Error Handling
> 
> ):
>
> Syntactic sugar for if let self-assignment
> :
> An alternative syntax (such as if let foo? { ... } or if let foo=? { ... })
> to serve as a shorthand for if let foo = foo { ... } is often proposed and
> rejected because it is favoring terseness over clarity by introducing new
> magic syntactic sugar.
>
>
> So any discussion on this topic would have to target these concerns first.
>
> On 26 Oct 2016, David Goodine wrote:
>
> I was typing the above (for the hundredth time) the other day and I was
> wondering whether it might be worth considering offering a shorter syntax:
>
> guard let x, y, z else {…}
>
>
> That said, while I don't mind having to repeat the variable name myself, I
> think David Goodine's syntax would have to repeat the `let` to align with
> SE-0099
> ,
> like so:
>
> *guard let* x, *let* y, *let* z *else* { ... }
>
> Personally, I wouldn't mind if this syntax existed. I think it explains
> itself rather well. And today, unlike when it was first discussed a long
> time before SE-0099, it's no longer confusable with Boolean conditions.
>
> But it's certainly out of scope for Swift 4 phase 1.
>
> — Pyry
>
> ___
> 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


Re: [swift-evolution] guard let x = x

2016-10-31 Thread Xiaodi Wu via swift-evolution
The hidden bugs arise when, instead of pill, you invoke pill(), and the
return value of pill() changes from Bool to Bool? or vice versa between one
version of a library and another.

Point is, a second keyword is needed precisely because unwrapping should
never be implicit. That much has been made clear in previous conversations
where "guard let x" has been repeatedly rejected as a sugar for "guard let
x = x". It stands to reason that "guard x" is even less acceptable.

On Mon, Oct 31, 2016 at 14:43 Kenny Leung via swift-evolution <
swift-evolution@swift.org> wrote:

> Now that I think about it some more, I think my proposal does not hurt the
> guard boolean case, and is still backward compatible.
>
> Current Universe:
>
> // This is the case Xiaodi mentions
> var pill :Boolean
> guard pill else {}
>
> // If pill was an optional-boolean, you would have to write it this way:
> var pill :Boolean?
> guard let pill = pill, pill else {}
>
> Kenny’s Universe:
>
> // This is the case Xiaodi mentions - nothing changes
> var pill :Boolean
> guard pill else{}
>
> // If pill was an optional-boolean, you might write this, but it only
> checks if pill is nil or not, and NOT true or false. This would be illegal
> in the Current Universe, so we know there is no backward incompatibility or
> hidden bugs.
> var pill :Boolean?
> guard pill else {}
>
> -Kenny
>
>
> > On Oct 31, 2016, at 12:33 PM, Kenny Leung via swift-evolution <
> swift-evolution@swift.org> wrote:
> >
> > I use guard pretty much exclusively in the “guard let x = x” context. I
> still think it’s a bad idea to sacrifice the 99% case for the 1% case.
> >
> > -Kenny
> >
> >
> >> On Oct 31, 2016, at 12:16 PM, Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> 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 
> 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@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 <
> alvaradojosh...@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@swift.org> wrote:
> >>>
>  Because "guard" already means something...
> 
> 
>  On Mon, Oct 31, 2016 at 13:45 Kenny Leung via swift-evolution <
> swift-evolution@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 
> 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@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@swift.org> wrote:
> >>>
> >>>
>  On Oct 26, 2016, at 11:39 AM, Chris Lattner via swift-evolution <
> swift-evolution@swift.org> wrote:
> 
> 
> > On Oct 26, 2016, at 10:23 AM, Joshua Alvarado <
> alvaradojosh...@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
> >>>
> >>> -- E
> >>>
> >>>
> >>> Introducing unwrap
> >>>
> >>>• Proposal: TBD
> >>>• Author: Erica Sadun, Chris Lattner, David Goodine
> >>>• 

Re: [swift-evolution] guard let x = x

2016-10-31 Thread Pyry Jahkola via swift-evolution
Going back to the originating message of this thread. This idea (or a variant 
thereof) has been mentioned in the list of Commonly Rejected Proposals (2nd 
last bullet under Control Flow, Closures, Optional Binding, and Error Handling 
):

> Syntactic sugar for if let self-assignment 
> :
>  An alternative syntax (such as if let foo? { ... } or if let foo=? { ... }) 
> to serve as a shorthand for if let foo = foo { ... } is often proposed and 
> rejected because it is favoring terseness over clarity by introducing new 
> magic syntactic sugar.

So any discussion on this topic would have to target these concerns first.

> On 26 Oct 2016, David Goodine wrote:
> 
> I was typing the above (for the hundredth time) the other day and I was 
> wondering whether it might be worth considering offering a shorter syntax:
> 
> guard let x, y, z else {…}


That said, while I don't mind having to repeat the variable name myself, I 
think David Goodine's syntax would have to repeat the `let` to align with 
SE-0099 
,
 like so:

guard let x, let y, let z else { ... }

Personally, I wouldn't mind if this syntax existed. I think it explains itself 
rather well. And today, unlike when it was first discussed a long time before 
SE-0099, it's no longer confusable with Boolean conditions.

But it's certainly out of scope for Swift 4 phase 1.

— Pyry

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-10-31 Thread Kenny Leung via swift-evolution
I use guard pretty much exclusively in the “guard let x = x” context. I still 
think it’s a bad idea to sacrifice the 99% case for the 1% case.

-Kenny


> On Oct 31, 2016, at 12:16 PM, Xiaodi Wu via swift-evolution 
>  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  
> 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 
>>  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  
>> 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 
>>  wrote:
>> 
>>> Because "guard" already means something...
>>> 
>>> 
>>> On Mon, Oct 31, 2016 at 13:45 Kenny Leung via swift-evolution 
>>>  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  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 
>>> >>  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 
>>> >>>  wrote:
>>> >>>
>>> >>>
>>>  On Oct 26, 2016, at 11:39 AM, Chris Lattner via swift-evolution 
>>>   wrote:
>>> 
>>> 
>>> > On Oct 26, 2016, at 10:23 AM, Joshua Alvarado 
>>> >  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
>>> >>>
>>> >>> -- 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 { 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 

Re: [swift-evolution] guard let x = x

2016-10-31 Thread William Sumner via swift-evolution


> On Oct 31, 2016, at 1:22 PM, William Sumner via swift-evolution 
>  wrote:
> 
> 
>> On Oct 31, 2016, at 1:11 PM, Kenny Leung via swift-evolution 
>>  wrote:
>> 
>> OK then, how about an extension to the proposal that says “guard variable 
>> always implies guard unwrap variable when the only thing present in the 
>> guard clause is an optional or list of optionals”?
>> 
>> So you could write
>> 
>> guard foo else {
>> }
>> 
>> guard foo, bar else {
>> }
>> 
>> -Kenny
> 
> 
> That would enable some strange-looking code:
> 
> var foo: Bool?
> guard foo, foo else {}
> 
> Preston
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

I missed the part where you require only optionals in the clause. However, I 
still don’t like the visual ambiguity between testing boolean expressions and 
unwrapping optionals.

Preston
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-10-31 Thread William Sumner via swift-evolution

> On Oct 31, 2016, at 1:11 PM, Kenny Leung via swift-evolution 
>  wrote:
> 
> OK then, how about an extension to the proposal that says “guard variable 
> always implies guard unwrap variable when the only thing present in the guard 
> clause is an optional or list of optionals”?
> 
> So you could write
> 
> guard foo else {
> }
> 
> guard foo, bar else {
> }
> 
> -Kenny


That would enable some strange-looking code:

var foo: Bool?
guard foo, foo else {}

Preston
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-10-31 Thread Xiaodi Wu via swift-evolution
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 
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@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 
> 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@swift.org> wrote:
>
> Because "guard" already means something...
>
>
> On Mon, Oct 31, 2016 at 13:45 Kenny Leung via swift-evolution <
> swift-evolution@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  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@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@swift.org> wrote:
> >>>
> >>>
>  On Oct 26, 2016, at 11:39 AM, Chris Lattner via swift-evolution <
> swift-evolution@swift.org> wrote:
> 
> 
> > On Oct 26, 2016, at 10:23 AM, Joshua Alvarado <
> alvaradojosh...@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
> >>>
> >>> -- 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 { 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 { 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 

Re: [swift-evolution] guard let x = x

2016-10-31 Thread Kenny Leung via swift-evolution
OK then, how about an extension to the proposal that says “guard variable 
always implies guard unwrap variable when the only thing present in the guard 
clause is an optional or list of optionals”?

So you could write

guard foo else {
}

guard foo, bar else {
}

-Kenny

> On Oct 31, 2016, at 12:05 PM, Xiaodi Wu  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  
> 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 
>  wrote:
> 
>> Because "guard" already means something...
>> 
>> 
>> On Mon, Oct 31, 2016 at 13:45 Kenny Leung via swift-evolution 
>>  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  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 
>> >>  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 
>> >>>  wrote:
>> >>>
>> >>>
>>  On Oct 26, 2016, at 11:39 AM, Chris Lattner via swift-evolution 
>>   wrote:
>> 
>> 
>> > On Oct 26, 2016, at 10:23 AM, Joshua Alvarado 
>> >  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
>> >>>
>> >>> -- 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 { 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 { 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
>> >>>
>> >>> • 

Re: [swift-evolution] guard let x = x

2016-10-31 Thread Charlie Monroe via swift-evolution
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 
>  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  > 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 
> > wrote:
> 
>> Because "guard" already means something...
>> 
>> 
>> On Mon, Oct 31, 2016 at 13:45 Kenny Leung via swift-evolution 
>> > 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 > > > 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 
>> >> > 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 
>> >>> > wrote:
>> >>>
>> >>>
>>  On Oct 26, 2016, at 11:39 AM, Chris Lattner via swift-evolution 
>>  > wrote:
>> 
>> 
>> > On Oct 26, 2016, at 10:23 AM, Joshua Alvarado 
>> > > 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 
>> >>> 
>> >>>
>> >>> -- 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 { 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 { 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 

Re: [swift-evolution] guard let x = x

2016-10-31 Thread Xiaodi Wu via swift-evolution
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 
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@swift.org> wrote:
>
> Because "guard" already means something...
>
>
> On Mon, Oct 31, 2016 at 13:45 Kenny Leung via swift-evolution <
> swift-evolution@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  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@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@swift.org> wrote:
> >>>
> >>>
>  On Oct 26, 2016, at 11:39 AM, Chris Lattner via swift-evolution <
> swift-evolution@swift.org> wrote:
> 
> 
> > On Oct 26, 2016, at 10:23 AM, Joshua Alvarado <
> alvaradojosh...@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
> >>>
> >>> -- 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 { 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 { 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@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
> >
>
> 

Re: [swift-evolution] guard let x = x

2016-10-31 Thread Joshua Alvarado via swift-evolution
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 
>  wrote:
> 
> Because "guard" already means something...
> 
> 
>> On Mon, Oct 31, 2016 at 13:45 Kenny Leung via swift-evolution 
>>  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  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 
>> >>  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 
>> >>>  wrote:
>> >>>
>> >>>
>>  On Oct 26, 2016, at 11:39 AM, Chris Lattner via swift-evolution 
>>   wrote:
>> 
>> 
>> > On Oct 26, 2016, at 10:23 AM, Joshua Alvarado 
>> >  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
>> >>>
>> >>> -- 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 { 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 { 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@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
>> >
>> 
>> ___
>> 

Re: [swift-evolution] guard let x = x

2016-10-31 Thread Xiaodi Wu via swift-evolution
Because "guard" already means something...


On Mon, Oct 31, 2016 at 13:45 Kenny Leung via swift-evolution <
swift-evolution@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  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@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@swift.org> wrote:
> >>>
> >>>
>  On Oct 26, 2016, at 11:39 AM, Chris Lattner via swift-evolution <
> swift-evolution@swift.org> wrote:
> 
> 
> > On Oct 26, 2016, at 10:23 AM, Joshua Alvarado <
> alvaradojosh...@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
> >>>
> >>> -- 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 { 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 { 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@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


Re: [swift-evolution] guard let x = x

2016-10-31 Thread Kenny Leung via swift-evolution
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  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 
>>  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 
>>>  wrote:
>>> 
>>> 
 On Oct 26, 2016, at 11:39 AM, Chris Lattner via swift-evolution 
  wrote:
 
 
> On Oct 26, 2016, at 10:23 AM, Joshua Alvarado  
> 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
>>> 
>>> -- 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 { 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 { 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@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


Re: [swift-evolution] guard let x = x

2016-10-31 Thread Erica Sadun via swift-evolution
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 
>  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 
>>  wrote:
>> 
>> 
>>> On Oct 26, 2016, at 11:39 AM, Chris Lattner via swift-evolution 
>>>  wrote:
>>> 
>>> 
 On Oct 26, 2016, at 10:23 AM, Joshua Alvarado  
 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
>> 
>> -- 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 { 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 { 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@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


Re: [swift-evolution] guard let x = x

2016-10-31 Thread Kenny Leung via swift-evolution
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 
>  wrote:
> 
> 
>> On Oct 26, 2016, at 11:39 AM, Chris Lattner via swift-evolution 
>>  wrote:
>> 
>> 
>>> On Oct 26, 2016, at 10:23 AM, Joshua Alvarado  
>>> 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
> 
> -- 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 { 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 { 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@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


Re: [swift-evolution] guard let x = x

2016-10-31 Thread Julian Dunskus via swift-evolution
I hate keeping this going even though we decided to put it off for phase 2, but 
I just had to add something:
Why not just put @unwrappable on the actual unwrappable case instead of the 
enum itself? You could even make multiple cases @unwrappable to specify (given 
that they have the same type) that any of them could be unwrapped.

–Julian Dunskus

> On 31 Oct 2016, at 14:18, Jeremy Pereira via swift-evolution 
>  wrote:
> 
> 
>> On 29 Oct 2016, at 02:10, Erica Sadun via swift-evolution 
>>  wrote:
>> 
>> Sounds good to me. Leaving the gist in its updated state (a little further 
>> from the last time) for the record.
> 
> I like the first part, even though I disagree that `if let foo = foo` 
> conflicts with DRY principles. However, I think you should drop the part 
> about unwrapping enums for now. That looks like a whole can of worms with a 
> zillion edge cases and could be dangerous in the wrong hands:
> 
> @unwrappable(type: String)
> public enum Result
> {
>case success(String) // String is the data requested
>case error(String) // String is an error message
> }
> 
> func getTheResult() -> Result { … }
> ….
> 
> if unwrap getTheResult() 
> {
>// Here we put the code for the success case - or do we?
> }
> 
> In the above, the code that uses unwrap would be broken simply by reordering 
> the cases in the enum declaration and not in a good way. There would be no 
> compilation or runtime error, an error message would simply be treated as 
> normal data. 
> 
> Having code depend on the order of something somewhere else - not necessarily 
> even in the same module doesn’t seem very Swifty to me. 
> 
> 
> ___
> 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


Re: [swift-evolution] guard let x = x

2016-10-31 Thread Jeremy Pereira via swift-evolution

> On 29 Oct 2016, at 02:10, Erica Sadun via swift-evolution 
>  wrote:
> 
> Sounds good to me. Leaving the gist in its updated state (a little further 
> from the last time) for the record.

I like the first part, even though I disagree that `if let foo = foo` conflicts 
with DRY principles. However, I think you should drop the part about unwrapping 
enums for now. That looks like a whole can of worms with a zillion edge cases 
and could be dangerous in the wrong hands:

@unwrappable(type: String)
public enum Result
{
case success(String) // String is the data requested
case error(String) // String is an error message
}

func getTheResult() -> Result { … }
….

if unwrap getTheResult() 
{
// Here we put the code for the success case - or do we?
}

In the above, the code that uses unwrap would be broken simply by reordering 
the cases in the enum declaration and not in a good way. There would be no 
compilation or runtime error, an error message would simply be treated as 
normal data. 

Having code depend on the order of something somewhere else - not necessarily 
even in the same module doesn’t seem very Swifty to me. 


___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-10-30 Thread Warren Gavin via swift-evolution
I like the simplicity of 'unwrap' solving the issue of repetition, but it
assumes 'let' in each example I've seen. 'guard var x = x' may not be
written as frequently, but it is still valid. I can't imagine the intention
would be that 'unwrap' is only for 'let'



On Sun, Oct 30, 2016 at 5:18 AM Jay Abbott via swift-evolution <
swift-evolution@swift.org> wrote:

> @unwrappable(type: Int)
> public enum Count {
> case none // not unwrappable
> case many // not unwrappable
> case some(Int)
> case owed(Int)
> case something(String) // not unwrappable
> case multiple(Int, Int) // not unwrappable
> }
>
> Instead of requiring the @unwrappable attribute, why not have unwrap work
> normally when the type can be inferred, or require hints when it can’t:
>
> // For an optional (or any other enum with only one wrapped type)
> guard unwrap x else { return }// For an enum of type Count as defined above
> guard unwrap myCount else { return } // compiler error - type can't be 
> determined
> guard unwrap(myCount: Int) else { return } // Success for 'some' or 'owed' 
> (implicit shadowing)
> guard unwrap(let someOrOwed: Int) myCount else { return } // Success for 
> 'some' or 'owed' (no shadowing)
> guard unwrap(let x: Int, let y: Int) myCount else { return } // Success for 
> 'multiple' (no shadowing)
>
> Notes:
>
>- unwrap x is equivalent to unwrap(x: T) where there is a single
>unambiguous type.
>- The let keyword probably could be implicit for the non-shadowing
>forms, like it is for the shadowing form, but makes it clear what’s going
>on.
>- unwrap fails for none or many from the Count type, just as it does
>for none from Optional
>- I *think* that this assumes Swift is not allowed to try to infer the
>most restrictive type for reference types. Haven’t really thought about
>this much.
>
> ​
> ___
> 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


Re: [swift-evolution] guard let x = x

2016-10-30 Thread Jay Abbott via swift-evolution
@unwrappable(type: Int)
> public enum Count {
> case none // not unwrappable
> case many // not unwrappable
> case some(Int)
> case owed(Int)
> case something(String) // not unwrappable
> case multiple(Int, Int) // not unwrappable
> }
>
> Instead of requiring the @unwrappable attribute, why not have unwrap work
normally when the type can be inferred, or require hints when it can’t:

// For an optional (or any other enum with only one wrapped type)
guard unwrap x else { return }// For an enum of type Count as defined above
guard unwrap myCount else { return } // compiler error - type can't be
determined
guard unwrap(myCount: Int) else { return } // Success for 'some' or
'owed' (implicit shadowing)
guard unwrap(let someOrOwed: Int) myCount else { return } // Success
for 'some' or 'owed' (no shadowing)
guard unwrap(let x: Int, let y: Int) myCount else { return } //
Success for 'multiple' (no shadowing)

Notes:

   - unwrap x is equivalent to unwrap(x: T) where there is a single
   unambiguous type.
   - The let keyword probably could be implicit for the non-shadowing
   forms, like it is for the shadowing form, but makes it clear what’s going
   on.
   - unwrap fails for none or many from the Count type, just as it does for
   none from Optional
   - I *think* that this assumes Swift is not allowed to try to infer the
   most restrictive type for reference types. Haven’t really thought about
   this much.

​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-10-29 Thread David Waite via swift-evolution

> On Oct 26, 2016, at 10:37 AM, Chris Lattner via swift-evolution 
>  wrote:
> 
> To me, this is the most promising direction, but I’d suggest the use of 
> “unwrap" as the keyword.  If you compare these two:
> 
> a) guard let foobar = foobar else { … }
> b) guard unwrap foobar else { … }
> 
> I think that b) wins by virtue of eliminating repetition ("foobar = foobar" 
> fails DRY principles), but retains clarity by introducing a word into the 
> grammar that people already commonly know and use, and which is googlable if 
> they don’t.
> 
> This also gives us the conceptual hook to make the “unwrapping an optional” 
> behavior (which occurs with if let, optional chaining, etc) be something that 
> could be extended to other similar user defined types, such as a Result type.

This might need a bit more fleshing out of the details. Given a result of T or 
Error, I would expect the unwrap operation’s flow control to not be a 
conditional but a throw - aka "try unwrap result” (or no need for a keyword - 
try result.unwrap()). That is, unless I specifically request a projection.

For an async/await system based on promises, I would expect to use an “await” 
keyword, not an “unwrap” keyword. 

> 
> -Chris
> 
> ___
> 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


Re: [swift-evolution] guard let x = x

2016-10-29 Thread Rien via swift-evolution
+1

Can “unwrap” be used anywhere else?
If not, why not remove the “guard” altogether?
I.e.

unwrap foobar else { … }

Regards,
Rien

Site: http://balancingrock.nl
Blog: http://swiftrien.blogspot.com
Github: http://github.com/Swiftrien
Project: http://swiftfire.nl




> On 29 Oct 2016, at 00:34, Erica Sadun via swift-evolution 
>  wrote:
> 
> 
>> On Oct 26, 2016, at 11:39 AM, Chris Lattner via swift-evolution 
>>  wrote:
>> 
>> 
>>> On Oct 26, 2016, at 10:23 AM, Joshua Alvarado  
>>> 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
> 
> -- 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 { 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 { 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@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


Re: [swift-evolution] guard let x = x

2016-10-28 Thread Jonathan Hull via swift-evolution
I think we should just have an “Unwrappable” protocol with a function/property 
that gets called by the statement.  Then types can just define it for 
themselves based on whatever makes sense.

That, or Xiaodi’s idea for union types (since I really want union types)

Thanks,
Jon 

> > On Oct 28, 2016, at 5:55 PM, Kevin Nattinger  > > wrote:
> > 
> >> 
> >> On Oct 28, 2016, at 4:45 PM, Erica Sadun via swift-evolution 
> >>  >>  
> >>  >> >> wrote:
> >> 
> >> 
> >>> On Oct 28, 2016, at 5:00 PM, Huon Wilson  >>>   >>> at apple.com >> 
> >>> wrote:
> >>> 
> >>> 
>  On Oct 28, 2016, at 15:34, Erica Sadun via swift-evolution 
>     
>    >> wrote:
>   
>     
>  >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 { 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
>   
>     
>  >
> >>> How does the compiler decide whether to succeed on anycase or succeed on 
> >>> anothercase respectively? In general, the compiler only statically knows 
> >>> that first & second are of type TypeName, not anything about which case 
> >>> (they could be passed in as function parameters, or returned by an opaque 
> >>> function e.g. `let x = OtherLibrary.returnsTypeName(); guard unwrap x 
> >>> else { … }`), and thus the variant to unwrap has to be chosen based only 
> >>> on that piece of information.
> >>> 
> >>> It seems to me that doing this either has to be restricted to enums with 
> >>> an “obvious” choice for unwrapping, like Optional, or rely on a sort of 
> >>> forward-looking type inference that Swift doesn’t currently use to deduce 
> >>> the unwrapped type based on how the value is used later (and I’m not sure 
> >>> that works in all cases, e.g. what if T == U for the TypeName example).
> >> 
> >> It succeeds on any one-item case and fails on any non-item case.
> > 
> > I think he meant this:
> > 
> > enum TypeName { case anycase(T), anothercase(U) }
> > 
> > func foo(instance: TypeName) {
> > guard unwrap instance else { ... }
> > }
> > 
> > What type does instance have? 
> 
> Fair enough. How about: An unwrappable enumeration must have at most one 
> generic type so the compiler can guarantee at compile time that the type is 
> unambiguous if the unwrapping succeeds

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-10-28 Thread Erica Sadun via swift-evolution
Sounds good to me. Leaving the gist in its updated state (a little further from 
the last time) for the record.

-- E

> On Oct 28, 2016, at 7:02 PM, Xiaodi Wu  wrote:
> 
> Granted that this whole topic is out of scope currently, I think the enum 
> unwrapping facility is its own subject entirely, separable from the `if let x 
> = x` sugar.
> 
> Approaching this issue from another perspective--namely, improving enums to 
> better enable some use cases prompted by requests for union types--I've 
> developed some ideas for unwrapping that I've been keeping under wraps (hehe) 
> until the next phase of Swift evolution, and it'd be nice to have a dedicated 
> conversation about such ideas when the time is right rather than rolling it 
> into the topic of `if let x = x` sugaring.
> 
> On Fri, Oct 28, 2016 at 7:42 PM Erica Sadun via swift-evolution 
> > wrote:
>> On Oct 28, 2016, at 6:22 PM, Erica Sadun via swift-evolution 
>> > wrote:
> 
>>> On Oct 28, 2016, at 5:55 PM, Kevin Nattinger >> > wrote:
> 
 On Oct 28, 2016, at 4:45 PM, Erica Sadun via swift-evolution 
 > wrote:
> 
> On Oct 28, 2016, at 5:00 PM, Huon Wilson  > wrote:
> 
>> On Oct 28, 2016, at 15:34, Erica Sadun via swift-evolution 
>> > wrote:
> 
> How does the compiler decide whether to succeed on anycase or succeed on 
> anothercase respectively? In general, the compiler only statically knows 
> that first & second are of type TypeName, not anything about which case 
> (they could be passed in as function parameters, or returned by an opaque 
> function e.g. `let x = OtherLibrary.returnsTypeName(); guard unwrap x 
> else { … }`), and thus the variant to unwrap has to be chosen based only 
> on that piece of information.
> 
> 
> It seems to me that doing this either has to be restricted to enums with 
> an “obvious” choice for unwrapping, like Optional, or rely on a sort of 
> forward-looking type inference that Swift doesn’t currently use to deduce 
> the unwrapped type based on how the value is used later (and I’m not sure 
> that works in all cases, e.g. what if T == U for the TypeName example).
> 
 It succeeds on any one-item case and fails on any non-item case.
> 
>>> 
>>> I think he meant this:
>>> 
>>> enum TypeName { case anycase(T), anothercase(U) }
>>> 
>>> func foo(instance: TypeName) {
>>> guard unwrap instance else { ... }
>>> }
>>> 
>>> What type does instance have? 
> 
>> 
>> Fair enough. How about: An unwrappable enumeration must have at most one 
>> generic type so the compiler can guarantee at compile time that the type is 
>> unambiguous if the unwrapping succeeds
> 
> 
> And updated gist:
> 
> Detailed Design
> 
> The unwrap statement shadows an enumeration variable to an unwrapped version 
> of the same type. Using unwrap is limited to enumerations that satisfy the 
> following conditions:
> 
> An unwrappable enumeration must specify the unwrap type, probably through an 
> @unwrappable attribute.
> Unwrapping is limited to one-item cases with that type.
> No-item or multi-item cases cannot unwrap.
> Cases using a different associated value type cannot unwrap.
> @unwrappable(type: Wrapped)
> public enum Optional {
> case none
> case some(Wrapped)
> }
> 
> @unwrappable(type: ValueType)
> public enum Result {
> case value(ValueType)
> case error(Error)
> }
> 
> @unwrappable(type: Int)
> public enum Count {
> case none // not unwrappable
> case many // not unwrappable
> case some(Int)
> case owed(Int)
> case something(String) // not unwrappable
> case multiple(Int, Int) // not unwrappable
> }
>  
> 
> ___
> 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


Re: [swift-evolution] guard let x = x

2016-10-28 Thread Xiaodi Wu via swift-evolution
Granted that this whole topic is out of scope currently, I think the enum
unwrapping facility is its own subject entirely, separable from the `if let
x = x` sugar.

Approaching this issue from another perspective--namely, improving enums to
better enable some use cases prompted by requests for union types--I've
developed some ideas for unwrapping that I've been keeping under wraps
(hehe) until the next phase of Swift evolution, and it'd be nice to have a
dedicated conversation about such ideas when the time is right rather than
rolling it into the topic of `if let x = x` sugaring.

On Fri, Oct 28, 2016 at 7:42 PM Erica Sadun via swift-evolution <
swift-evolution@swift.org> wrote:

> On Oct 28, 2016, at 6:22 PM, Erica Sadun via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> On Oct 28, 2016, at 5:55 PM, Kevin Nattinger  wrote:
>
> On Oct 28, 2016, at 4:45 PM, Erica Sadun via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> On Oct 28, 2016, at 5:00 PM, Huon Wilson  wrote:
>
> On Oct 28, 2016, at 15:34, Erica Sadun via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> How does the compiler decide whether to succeed on anycase or succeed on
> anothercase respectively? In general, the compiler only statically knows
> that first & second are of type TypeName, not anything about which case
> (they could be passed in as function parameters, or returned by an opaque
> function e.g. `let x = OtherLibrary.returnsTypeName(); guard unwrap x else
> { … }`), and thus the variant to unwrap has to be chosen based only on that
> piece of information.
>
> It seems to me that doing this either has to be restricted to enums with
> an “obvious” choice for unwrapping, like Optional, or rely on a sort of
> forward-looking type inference that Swift doesn’t currently use to deduce
> the unwrapped type based on how the value is used later (and I’m not sure
> that works in all cases, e.g. what if T == U for the TypeName example).
>
> It succeeds on any one-item case and fails on any non-item case.
>
>
> I think he meant this:
>
> enum TypeName { case anycase(T), anothercase(U) }
>
> func foo(instance: TypeName) {
> guard unwrap instance else { ... }
> }
>
> What type does instance have?
>
>
> Fair enough. How about: An unwrappable enumeration must have at most one
> generic type so the compiler can guarantee at compile time that the type is
> unambiguous if the unwrapping succeeds
>
>
> And updated gist:
>
> Detailed Design
>
> The unwrap statement shadows an enumeration variable to an unwrapped
> version of the same type. Using unwrap is limited to enumerations that
> satisfy the following conditions:
>
>- An unwrappable enumeration must specify the unwrap type, probably
>through an @unwrappable attribute.
>- Unwrapping is limited to one-item cases with that type.
>- No-item or multi-item cases cannot unwrap.
>- Cases using a different associated value type cannot unwrap.
>
> @unwrappable(type: Wrapped)
> public enum Optional {
> case none
> case some(Wrapped)
> }
>
> @unwrappable(type: ValueType)
> public enum Result {
> case value(ValueType)
> case error(Error)
> }
>
> @unwrappable(type: Int)
> public enum Count {
> case none // not unwrappable
> case many // not unwrappable
> case some(Int)
> case owed(Int)
> case something(String) // not unwrappable
> case multiple(Int, Int) // not unwrappable
> }
>
>
> 
>
> ___
> 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


Re: [swift-evolution] guard let x = x

2016-10-28 Thread Erica Sadun via swift-evolution

> On Oct 28, 2016, at 6:22 PM, Erica Sadun via swift-evolution 
>  wrote:
>> On Oct 28, 2016, at 5:55 PM, Kevin Nattinger > > wrote:
>>> On Oct 28, 2016, at 4:45 PM, Erica Sadun via swift-evolution 
>>> > wrote:
 On Oct 28, 2016, at 5:00 PM, Huon Wilson > wrote:
> On Oct 28, 2016, at 15:34, Erica Sadun via swift-evolution 
> > wrote:
 How does the compiler decide whether to succeed on anycase or succeed on 
 anothercase respectively? In general, the compiler only statically knows 
 that first & second are of type TypeName, not anything about which case 
 (they could be passed in as function parameters, or returned by an opaque 
 function e.g. `let x = OtherLibrary.returnsTypeName(); guard unwrap x else 
 { … }`), and thus the variant to unwrap has to be chosen based only on 
 that piece of information.
 
 It seems to me that doing this either has to be restricted to enums with 
 an “obvious” choice for unwrapping, like Optional, or rely on a sort of 
 forward-looking type inference that Swift doesn’t currently use to deduce 
 the unwrapped type based on how the value is used later (and I’m not sure 
 that works in all cases, e.g. what if T == U for the TypeName example).
>>> 
>>> It succeeds on any one-item case and fails on any non-item case.
>> 
>> I think he meant this:
>> 
>> enum TypeName { case anycase(T), anothercase(U) }
>> 
>> func foo(instance: TypeName) {
>>  guard unwrap instance else { ... }
>> }
>> 
>> What type does instance have? 
> 
> Fair enough. How about: An unwrappable enumeration must have at most one 
> generic type so the compiler can guarantee at compile time that the type is 
> unambiguous if the unwrapping succeeds

And updated gist:

Detailed Design

The unwrap statement shadows an enumeration variable to an unwrapped version of 
the same type. Using unwrap is limited to enumerations that satisfy the 
following conditions:

An unwrappable enumeration must specify the unwrap type, probably through an 
@unwrappable attribute.
Unwrapping is limited to one-item cases with that type.
No-item or multi-item cases cannot unwrap.
Cases using a different associated value type cannot unwrap.
@unwrappable(type: Wrapped)
public enum Optional {
case none
case some(Wrapped)
}

@unwrappable(type: ValueType)
public enum Result {
case value(ValueType)
case error(Error)
}

@unwrappable(type: Int)
public enum Count {
case none // not unwrappable
case many // not unwrappable
case some(Int)
case owed(Int)
case something(String) // not unwrappable
case multiple(Int, Int) // not unwrappable
}
 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-10-28 Thread Huon Wilson via swift-evolution

> On Oct 28, 2016, at 16:45, Erica Sadun  wrote:
> 
> 
>> On Oct 28, 2016, at 5:00 PM, Huon Wilson > > wrote:
>> 
>> 
>>> On Oct 28, 2016, at 15:34, Erica Sadun via swift-evolution 
>>> > wrote:
>>>  
>>> 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 { 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
>>>  
>>> 
>> How does the compiler decide whether to succeed on anycase or succeed on 
>> anothercase respectively? In general, the compiler only statically knows 
>> that first & second are of type TypeName, not anything about which case 
>> (they could be passed in as function parameters, or returned by an opaque 
>> function e.g. `let x = OtherLibrary.returnsTypeName(); guard unwrap x else { 
>> … }`), and thus the variant to unwrap has to be chosen based only on that 
>> piece of information.
>> 
>> It seems to me that doing this either has to be restricted to enums with an 
>> “obvious” choice for unwrapping, like Optional, or rely on a sort of 
>> forward-looking type inference that Swift doesn’t currently use to deduce 
>> the unwrapped type based on how the value is used later (and I’m not sure 
>> that works in all cases, e.g. what if T == U for the TypeName example).
> 
> It succeeds on any one-item case and fails on any non-item case.
> 
> -- E
> 
> 

I think I obscured my point: `guard unwrap`ing two values of the same type 
should result in two values that also have identical types, because the type of 
the binding can only be determined from the type of the thing being unwrapped.

In particular, I was thinking that you’re proposing that the first example 
becomes:

guard case .anycase(let first) = first { ... }

(Which will fail if first is anothercase, of course.)

While the second example becomes:

guard case .anothercase(let second) = second { ... }

(Which will similarly fail if second is anycase.)

Somehow the compiler needs to have a rule that chooses to use anycase for the 
first one and anothercase for the second. If it doesn’t do this, the shadowed 
variables can’t be given types T and U. Unfortunately, I don’t see any cues 
that the compiler can use to make the decision about when to use each version, 
and so I don’t think such a rule can exist in Swift.


All that said, based on your clarification, it sounds like you might actually 
be actually envisioning a different desugaring. Consider the following:

enum Enum { case a(Int), b(String), c }
let x: Enum = returnsEnum();
guard unwrap x else { ... }

Maybe it could be equivalent to the following (using x_shadow instead of the 
new x for clarity):

let x_shadow: /* ??? */

switch x {
case let .a(t): x_shadow = t
case let .b(u): x_shadow = u
default: /* else clause */
}

However, this also doesn’t work: what type fills in ???. Any and things like it 
are the only choice, but erasing the type seems somewhat backwards for an 
unwrapping feature.


Huon

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-10-28 Thread Erica Sadun via swift-evolution
> 
> On Oct 28, 2016, at 5:55 PM, Kevin Nattinger  wrote:
> 
>> 
>> On Oct 28, 2016, at 4:45 PM, Erica Sadun via swift-evolution 
>> > wrote:
>> 
>> 
>>> On Oct 28, 2016, at 5:00 PM, Huon Wilson >> > wrote:
>>> 
>>> 
 On Oct 28, 2016, at 15:34, Erica Sadun via swift-evolution 
 > wrote:
  
 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 { 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
  
 
>>> How does the compiler decide whether to succeed on anycase or succeed on 
>>> anothercase respectively? In general, the compiler only statically knows 
>>> that first & second are of type TypeName, not anything about which case 
>>> (they could be passed in as function parameters, or returned by an opaque 
>>> function e.g. `let x = OtherLibrary.returnsTypeName(); guard unwrap x else 
>>> { … }`), and thus the variant to unwrap has to be chosen based only on that 
>>> piece of information.
>>> 
>>> It seems to me that doing this either has to be restricted to enums with an 
>>> “obvious” choice for unwrapping, like Optional, or rely on a sort of 
>>> forward-looking type inference that Swift doesn’t currently use to deduce 
>>> the unwrapped type based on how the value is used later (and I’m not sure 
>>> that works in all cases, e.g. what if T == U for the TypeName example).
>> 
>> It succeeds on any one-item case and fails on any non-item case.
> 
> I think he meant this:
> 
> enum TypeName { case anycase(T), anothercase(U) }
> 
> func foo(instance: TypeName) {
>   guard unwrap instance else { ... }
> }
> 
> What type does instance have? 

Fair enough. How about: An unwrappable enumeration must have at most one 
generic type so the compiler can guarantee at compile time that the type is 
unambiguous if the unwrapping succeeds

-- E

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-10-28 Thread Kevin Nattinger via swift-evolution

> On Oct 28, 2016, at 4:45 PM, Erica Sadun via swift-evolution 
>  wrote:
> 
> 
>> On Oct 28, 2016, at 5:00 PM, Huon Wilson > > wrote:
>> 
>> 
>>> On Oct 28, 2016, at 15:34, Erica Sadun via swift-evolution 
>>> > wrote:
>>>  
>>> 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 { 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
>>>  
>>> 
>> How does the compiler decide whether to succeed on anycase or succeed on 
>> anothercase respectively? In general, the compiler only statically knows 
>> that first & second are of type TypeName, not anything about which case 
>> (they could be passed in as function parameters, or returned by an opaque 
>> function e.g. `let x = OtherLibrary.returnsTypeName(); guard unwrap x else { 
>> … }`), and thus the variant to unwrap has to be chosen based only on that 
>> piece of information.
>> 
>> It seems to me that doing this either has to be restricted to enums with an 
>> “obvious” choice for unwrapping, like Optional, or rely on a sort of 
>> forward-looking type inference that Swift doesn’t currently use to deduce 
>> the unwrapped type based on how the value is used later (and I’m not sure 
>> that works in all cases, e.g. what if T == U for the TypeName example).
> 
> It succeeds on any one-item case and fails on any non-item case.

I think he meant this:

enum TypeName { case anycase(T), anothercase(U) }

func foo(instance: TypeName) {
guard unwrap instance else { ... }
}

What type does instance have? 

> 
> -- E
> 
> 
> ___
> 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


Re: [swift-evolution] guard let x = x

2016-10-28 Thread Erica Sadun via swift-evolution

> On Oct 28, 2016, at 5:00 PM, Huon Wilson  wrote:
> 
> 
>> On Oct 28, 2016, at 15:34, Erica Sadun via swift-evolution 
>> > wrote:
>>  
>> 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 { 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
>>  
>> 
> How does the compiler decide whether to succeed on anycase or succeed on 
> anothercase respectively? In general, the compiler only statically knows that 
> first & second are of type TypeName, not anything about which case (they 
> could be passed in as function parameters, or returned by an opaque function 
> e.g. `let x = OtherLibrary.returnsTypeName(); guard unwrap x else { … }`), 
> and thus the variant to unwrap has to be chosen based only on that piece of 
> information.
> 
> It seems to me that doing this either has to be restricted to enums with an 
> “obvious” choice for unwrapping, like Optional, or rely on a sort of 
> forward-looking type inference that Swift doesn’t currently use to deduce the 
> unwrapped type based on how the value is used later (and I’m not sure that 
> works in all cases, e.g. what if T == U for the TypeName example).

It succeeds on any one-item case and fails on any non-item case.

-- E


___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-10-28 Thread Huon Wilson via swift-evolution

> On Oct 28, 2016, at 15:34, Erica Sadun via swift-evolution 
>  wrote:
>  
> 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 { 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
>  
> 
How does the compiler decide whether to succeed on anycase or succeed on 
anothercase respectively? In general, the compiler only statically knows that 
first & second are of type TypeName, not anything about which case (they could 
be passed in as function parameters, or returned by an opaque function e.g. 
`let x = OtherLibrary.returnsTypeName(); guard unwrap x else { … }`), and thus 
the variant to unwrap has to be chosen based only on that piece of information.

It seems to me that doing this either has to be restricted to enums with an 
“obvious” choice for unwrapping, like Optional, or rely on a sort of 
forward-looking type inference that Swift doesn’t currently use to deduce the 
unwrapped type based on how the value is used later (and I’m not sure that 
works in all cases, e.g. what if T == U for the TypeName example).


Huon

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-10-28 Thread Erica Sadun via swift-evolution

> On Oct 26, 2016, at 11:39 AM, Chris Lattner via swift-evolution 
>  wrote:
> 
> 
>> On Oct 26, 2016, at 10:23 AM, Joshua Alvarado  
>> 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 


-- 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 { 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 { 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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-10-28 Thread David Waite via swift-evolution

> On Oct 26, 2016, at 9:37 AM, Chris Lattner via swift-evolution 
>  wrote:

> To me, this is the most promising direction, but I’d suggest the use of 
> “unwrap" as the keyword.  If you compare these two:
> 
> a) guard let foobar = foobar else { … }
> b) guard unwrap foobar else { … }
> 
> I think that b) wins by virtue of eliminating repetition ("foobar = foobar" 
> fails DRY principles), but retains clarity by introducing a word into the 
> grammar that people already commonly know and use, and which is googlable if 
> they don’t.
> 
> This also gives us the conceptual hook to make the “unwrapping an optional” 
> behavior (which occurs with if let, optional chaining, etc) be something that 
> could be extended to other similar user defined types, such as a Result type.

I know that there has been many conversations about a cleaner syntax for 
conditional unwrapping of optionals on this list. My concern in the past has 
been whether this makes it confusing for new developers to understand whether 
“foobar” is a shadowed variable within the block (or for guard, after the 
block) or if it is an alias.

-DW
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-10-26 Thread David Goodine via swift-evolution
First off, Chris made it clear dealing with this isn't a priority for Swift 4 
so take my comments (inline below) with a grain of salt. At least for the time 
being this horse should Rest In Peace. 

> On Oct 26, 2016, at 11:58 AM, Erica Sadun  wrote:
> 
> 
>> On Oct 26, 2016, at 5:40 AM, David Goodine via swift-evolution 
>>  wrote:
>> 
>> Hey all,
>> 
>> As usual, apologies if this horse was beaten ages ago before I joined the 
>> mailing list, but thought I would bring this up.
>> 
>> I was typing the above (for the hundredth time) the other day and I was 
>> wondering whether it might be worth considering offering a shorter syntax:
>> 
>> guard let x, y, z else {…}
>> 
>> I was never convinced why implicit nil checks (i.e. if x {…}) were such a 
>> bad thing.  But now in Swift it seems that it would be much more convenient 
>> to be able to simply skip the assignment part of the expression and define 
>> the above as guaranteeing and unwrapping x, y and z in the appropriate scope.
>> 
>> I think with such powerful and already compact expressions now wanting to 
>> get on the same line,adding this would make the language even more compact 
>> and elegant.  It could be added as a non-source-breaking change, still 
>> allowing x = x for those who prefer it, but could significantly tighten up 
>> such uses, which I’m finding are ubiquitous in my code.
>> 
>> Any thoughts?
>> 
>> -d
> 
> There are safety arguments to be made for introducing a way to bind an 
> optional to a shadowed variable that is guaranteed to be the same name 
> ensuring the conditionally bound item does not accidentally shadow any other 
> item. 
> 

Chris also raised this in a comment in this thread, and I agree with Swift's 
philosophy that terseness shouldn't compromise clarity of intent. 

What I don't get is why 'let x = x' is any clearer than the alternative I 
suggested. It's intent is only clear because the language defines it as such. 
In fact, I would argue that to programmers familiar with most other popular 
languages, it's intuitively unclear, even meaningless (except for being a rare 
reference to a 1980s Laurie Anderson song). 

I was simply suggesting that since neither is a familiar syntax, Swift could 
simple "define it as such" in a more compact (and as Chris pointed out, more 
DRY form).

That said, I do like your earlier proposal to introduce the 'bind' form (and 
agree with Chris that 'unwrap' would be clearer). Perhaps that's the way to go 
when it's time to tackle the issue. 

-d

(p.s. I'm still secretly trying to work a reference to the Dead Parrot sketch 
to issues like these. Perhaps one day...)

> Your initial suggestion doesn't work as overloading "let" confuses rather 
> than clarifies this process. In February, I brought up `bind x` to mean 
> "conditionally bind x to x, and produce a conditional fail if that's not 
> possible", with the hope that "bind self" could be used in closures. Under 
> that scheme your example would read:
> 
> guard bind x, bind y, bind z else { ... }
> 
> "The bind thread" was discussed during the first week of February 2016. Joe 
> Groff had said: "If you all are serious about this, I think you should start 
> a new thread about it."  I thought it was worth a serious discussion just so 
> it could be evaluated and either adopted or discarded and dropped forever. 
> The arguments for:
> 
> * Simplifying an mildly complex and potentially misleading statement 
> * Creating a deliberate and controlled rather than accidental shadowing style
> 
> The discussion petered out, with Kevin Ballard making the strongest case 
> against: "If your goal here is to just avoid having to write the `= foo`, 
> then I disagree with the whole motive. If your goal here is to just use a 
> keyword `bind` instead of `let` (e.g. if you want to use `if bind foo = foo { 
> ... }`), I still disagree, because this new keyword serves no purpose. `if 
> let foo = bar { ... }` is not "fundamentally different" than `let foo = bar`, 
> it's still binding a new identifier to a value, the only difference is it 
> binds it to an optional value. And it's really just a specialization of `if 
> case let foo? = bar { ... }`. I've asked in the past about whether it's worth 
> keeping the special case around now that we have `if case let` (or more 
> specifically, if we should just turn `if let` into the generalized version, 
> so you'd say `if let foo? = bar {... }`) and the answer from the core team 
> was that they already tried it internally and found that the usage of 
> optionals was so prevalent that the special-case optional-specific form of 
> `if let` was worth keeping."
> 
> There was not sufficient support to push forward with this, and reasonable 
> arguments against. I'd suggest the long since beaten horse has moved on to a 
> better world.
> 
> -- E
> 
> 
___
swift-evolution mailing list
swift-evolution@swift.org

Re: [swift-evolution] guard let x = x

2016-10-26 Thread Chris Lattner via swift-evolution

> On Oct 26, 2016, at 10:23 AM, Joshua Alvarado  
> 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

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-10-26 Thread Joshua Alvarado via swift-evolution
In your example the keyword only makes sense if you are shadowing the
optional variable. How would unwrap work with a different name?

Ex:
guard let bar = foo else {...}
guard unwrap bar else {...} -> There is no context to what the guard is
unwrapping
This could end up leading to:
guard unwrap bar = foo else {...} which is essentially the same as the
current guard

Alvarado, Joshua

On Wed, Oct 26, 2016 at 11:09 AM, Josh Parmenter via swift-evolution <
swift-evolution@swift.org> wrote:

>
> On Oct 26, 2016, at 9:37 AM, Chris Lattner via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> To me, this is the most promising direction, but I’d suggest the use of
> “unwrap" as the keyword.  If you compare these two:
>
> a) guard let foobar = foobar else { … }
> b) guard unwrap foobar else { … }
>
> I think that b) wins by virtue of eliminating repetition ("foobar =
> foobar" fails DRY principles), but retains clarity by introducing a word
> into the grammar that people already commonly know and use, and which is
> googlable if they don’t.
>
> I find b) to be quite convincing.
>
> Best,
>
> Josh
>
>
>
> Joshua Parmenter | Engineering Lead, Apple Technologies
>
> T 248 777 
> C 206 437 1551
> F 248 616 1980
> www.vectorform.com
>
> Vectorform
> 2107 Elliott Ave Suite 303
> Seattle, WA  98121 USA
>
> Think Tank. Lab. Studio.
> We invent digital products and experiences.
>
> SEATTLE | DETROIT | NEW YORK | MUNICH | HYDERABAD
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>



-- 
Joshua Alvarado
alvaradojosh...@gmail.com
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-10-26 Thread Josh Parmenter via swift-evolution

On Oct 26, 2016, at 9:37 AM, Chris Lattner via swift-evolution 
> wrote:

To me, this is the most promising direction, but I’d suggest the use of 
“unwrap" as the keyword.  If you compare these two:

a) guard let foobar = foobar else { … }
b) guard unwrap foobar else { … }

I think that b) wins by virtue of eliminating repetition ("foobar = foobar" 
fails DRY principles), but retains clarity by introducing a word into the 
grammar that people already commonly know and use, and which is googlable if 
they don’t.

I find b) to be quite convincing.

Best,

Josh



Joshua Parmenter | Engineering Lead, Apple Technologies

T 248 777 
C 206 437 1551
F 248 616 1980
www.vectorform.com

Vectorform
2107 Elliott Ave Suite 303
Seattle, WA  98121 USA

Think Tank. Lab. Studio.
We invent digital products and experiences.

SEATTLE | DETROIT | NEW YORK | MUNICH | HYDERABAD

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-10-26 Thread Chris Lattner via swift-evolution
> On Oct 26, 2016, at 8:58 AM, Erica Sadun via swift-evolution 
>  wrote:
>> On Oct 26, 2016, at 5:40 AM, David Goodine via swift-evolution 
>> > wrote:
>> 
>> Hey all,
>> 
>> As usual, apologies if this horse was beaten ages ago before I joined the 
>> mailing list, but thought I would bring this up.

Yes, this has thoroughly been beaten to death.  It is also outside the scope of 
Swift 4 stage 1.  That said, it is such a glaring problem that we’ll have to 
deal with it at some point.

>> I was typing the above (for the hundredth time) the other day and I was 
>> wondering whether it might be worth considering offering a shorter syntax:
>> 
>> guard let x, y, z else {…}

This specific syntax is commonly requested.  The problem with this is that it 
provides no useful information about what is actually going on: it sacrifices 
clarity to get terseness, a specific non-goal of Swift.


Erica says:
> Your initial suggestion doesn't work as overloading "let" confuses rather 
> than clarifies this process. In February, I brought up `bind x` to mean 
> "conditionally bind x to x, and produce a conditional fail if that's not 
> possible", with the hope that "bind self" could be used in closures. Under 
> that scheme your example would read:
> 
> guard bind x, bind y, bind z else { … }

To me, this is the most promising direction, but I’d suggest the use of 
“unwrap" as the keyword.  If you compare these two:

a) guard let foobar = foobar else { … }
b) guard unwrap foobar else { … }

I think that b) wins by virtue of eliminating repetition ("foobar = foobar" 
fails DRY principles), but retains clarity by introducing a word into the 
grammar that people already commonly know and use, and which is googlable if 
they don’t.

This also gives us the conceptual hook to make the “unwrapping an optional” 
behavior (which occurs with if let, optional chaining, etc) be something that 
could be extended to other similar user defined types, such as a Result type.

-Chris

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] guard let x = x

2016-10-26 Thread Erica Sadun via swift-evolution

> On Oct 26, 2016, at 5:40 AM, David Goodine via swift-evolution 
>  wrote:
> 
> Hey all,
> 
> As usual, apologies if this horse was beaten ages ago before I joined the 
> mailing list, but thought I would bring this up.
> 
> I was typing the above (for the hundredth time) the other day and I was 
> wondering whether it might be worth considering offering a shorter syntax:
> 
> guard let x, y, z else {…}
> 
> I was never convinced why implicit nil checks (i.e. if x {…}) were such a bad 
> thing.  But now in Swift it seems that it would be much more convenient to be 
> able to simply skip the assignment part of the expression and define the 
> above as guaranteeing and unwrapping x, y and z in the appropriate scope.
> 
> I think with such powerful and already compact expressions now wanting to get 
> on the same line,adding this would make the language even more compact and 
> elegant.  It could be added as a non-source-breaking change, still allowing x 
> = x for those who prefer it, but could significantly tighten up such uses, 
> which I’m finding are ubiquitous in my code.
> 
> Any thoughts?
> 
> -d

There are safety arguments to be made for introducing a way to bind an optional 
to a shadowed variable that is guaranteed to be the same name ensuring the 
conditionally bound item does not accidentally shadow any other item. 

Your initial suggestion doesn't work as overloading "let" confuses rather than 
clarifies this process. In February, I brought up `bind x` to mean 
"conditionally bind x to x, and produce a conditional fail if that's not 
possible", with the hope that "bind self" could be used in closures. Under that 
scheme your example would read:

guard bind x, bind y, bind z else { ... }

"The bind thread" was discussed during the first week of February 2016. Joe 
Groff had said: "If you all are serious about this, I think you should start a 
new thread about it."  I thought it was worth a serious discussion just so it 
could be evaluated and either adopted or discarded and dropped forever. The 
arguments for:

* Simplifying an mildly complex and potentially misleading statement 
* Creating a deliberate and controlled rather than accidental shadowing style

The discussion petered out, with Kevin Ballard making the strongest case 
against: "If your goal here is to just avoid having to write the `= foo`, then 
I disagree with the whole motive. If your goal here is to just use a keyword 
`bind` instead of `let` (e.g. if you want to use `if bind foo = foo { ... }`), 
I still disagree, because this new keyword serves no purpose. `if let foo = bar 
{ ... }` is not "fundamentally different" than `let foo = bar`, it's still 
binding a new identifier to a value, the only difference is it binds it to an 
optional value. And it's really just a specialization of `if case let foo? = 
bar { ... }`. I've asked in the past about whether it's worth keeping the 
special case around now that we have `if case let` (or more specifically, if we 
should just turn `if let` into the generalized version, so you'd say `if let 
foo? = bar {... }`) and the answer from the core team was that they already 
tried it internally and found that the usage of optionals was so prevalent that 
the special-case optional-specific form of `if let` was worth keeping."

There was not sufficient support to push forward with this, and reasonable 
arguments against. I'd suggest the long since beaten horse has moved on to a 
better world.

-- E


___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution