I believe the core team has considered 99% of the ideas in the mailing list in 
the past, but it doesn’t mean we can’t discuss it, right?

Assuming we have the following declaration:

```
func foo(a: Int, b: Int?, c: Int, d: Int?) -> Int
```

For this:

```
let z = foo(a: f1(), b: f2()?, c: f3(), d: f4()?) // z becomes optional
```

We have a few different “possible solutions”:

1. Short-circuiting from left to right. This is equivalent to:

```
var z: Int? = nil
let a = f1()
guard let b = f2() else { return }
let c = f3()
guard let d = f4() else { return }
z = foo(a: a, b: b, c: c, d: d)
```

2. Short-circuiting from left to right for optionals. Then evaluate 
non-optional parameters. This is equivalent to:

```
var z: Int? = nil
guard let b = f2() else { return }
guard let d = f4() else { return }
let a = f1()
let c = f3()
z = foo(a: a, b: b, c: c, d: d)
```

3. Do not short-circuiting.

```
var z: Int? = nil
let a = f1()
let optionalB = f2()
let c = f3()
let optionalD = f4()
guard let b = optionalB else { return }
guard let d = optionalD else { return }
z = foo(a: a, b: b, c: c, d: d)
```

Like I said before, I agree that there is no intuitive solution to this 
problem. However, I'm still not convinced that this feature is *not important*.

Thank you for pointing out the problem to me. I didn't notice it at the time I 
wrote my first email. I really appreciate that. However, instead of saying I 
don't know which is the best solution so let's assume the core team made the 
right decision, we should discuss whether 1, 2, 3 is the best solution. Or you 
can convince me we don't *need* this feature.

Back to the original topic.

I spent some time thinking and changed my mind again. I think solution 1 is 
most reasonable. It is consistent with if statements. Instead of treating it as 
sugar for `if let`, we can treat it as sugar for `guard`, which is much easy to 
understand and remember.

-

Below is the reason why I think this feature is important (quoted from another 
email).

The problem with `if let` is you need to call the function inside { }.

```
/* code 1 */
if let x = x, let y = y {
    /* code 2, depends on x and y to be non-optional */
    let z = foo(x, y)
    if let z = z {
        bar(z)
    }
    /* code 3, depends on x and y to be non-optional */
}
/* code 4 */
```

I can't use `guard` for this situation because guard will force me to leave the 
entire function.

```
/* code 1 */
guard let x = x, y = y else { return }
/* code 2, depends on x and y to be non-optional */
guard let z = foo(x, y) else { return }
bar(z)
/* code 3, depends on x and y to be non-optional */ <- This won't execute if z 
is nil
/* code 4 */ <- This won't execute if x, y or z is nil
```

What I really want is some like this:

```
/ * code 1 */
let z = foo(x?, y?)
/* code 2, depends on x and y to be non-optional, use x? and y? */
bar(z?)
/* code 3, depends on x and y to be non-optional, use x? and y? */
/* code 4 */
```
This is much easier to read. Sometimes people choose to use `guard` to avoid `{ 
}`, which usually lead to code could easily get wrong (like the second example).

Sincerely,
Justin




> On Aug 15, 2016, at 11:41 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
> 
> What do you mean, limited to variables? What about a computed property? You 
> will have the same problem.
> 
> I'm not sure where you want to go with this, given that the core team has 
> considered the same idea in the past and found these issues to have no good 
> solution.
> 
> On Mon, Aug 15, 2016 at 04:56 Justin Jia <justin.jia.develo...@gmail.com 
> <mailto:justin.jia.develo...@gmail.com>> wrote:
> IMO I don't this bar should be evaluated unless we decide if let can accept 
> non-optional values. 
> 
> Actually, what if we allow if let to accept non-optional values?
> 
> I agree this is confusing at the beginning. But people who are not familiar 
> with the detail design can avoid this situation easily. People who are 
> familiar with the design can adopt it quickly. Sometimes, this is 
> unavoidable. 
> 
> Btw, do you think this is still something nice to have if we limit this 
> syntax to only variables?
> 
> On Aug 15, 2016, at 4:59 PM, Xiaodi Wu <xiaodi...@gmail.com 
> <mailto:xiaodi...@gmail.com>> wrote:
> 
>> On Mon, Aug 15, 2016 at 3:55 AM, Xiaodi Wu <xiaodi...@gmail.com 
>> <mailto:xiaodi...@gmail.com>> wrote:
>> On Mon, Aug 15, 2016 at 3:25 AM, Justin Jia via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>>> On Aug 15, 2016, at 4:09 PM, Charlie Monroe <char...@charliemonroe.net 
>>> <mailto:char...@charliemonroe.net>> wrote:
>>> 
>>> The example above was to better demonstrate the problem with *when* to 
>>> evaluate the latter argument. Why should both arguments be evaluated 
>>> *before* the if statement? If both calls return Optionals, 
>>> 
>>> if let x = bar(42), y = baz(42) { ... }
>>> 
>>> is how would I write it without the suggested syntax - baz(42) will *not* 
>>> be evaluated if bar(42) returns nil. Which bears a question why would 
>>> 
>>> foo(bar(42)?, baz(42)?) 
>>> 
>>> evaluate both arguments even if the first one is nil, making it incosistent 
>>> with the rest of the language?
>> 
>> I see your point. I understand that maybe 1/2 of the people think we should 
>> evaluate both arguments and 1/2 of the people think we should only evaluate 
>> the first argument.
>> 
>> I changed my idea a little bit. Now I think you are right. We should only 
>> evaluate the first argument in your example. It’s not only because of 
>> inconsistent, but also because the language should at least provide a way to 
>> “short-circuit” to rest of the arguments.
>> 
>> If they want to opt-out this behavior, they can always write:
>> 
>> ```
>> let x = bar(42)
>> let y = baz(42)
>> foo(x?, y?)
>> ```
>> 
>> Well, that was just the easy part. Now, suppose bar is the function that 
>> isn't optional.
>> 
>> ```
>> foo(bar(42), baz(42)?)
>> ```
>> 
>> Is bar evaluated if baz returns nil? If you want this syntax to be sugar for 
>> if let, then the answer is yes.
>> 
>> s/yes/no/
>>  
>> If short-circuiting works left-to-right, then the answer is no.
>> 
>> s/no/yes/ 
>> 
>> (See? Confusing.)
>>  
>> This is very confusing, and there is no good intuitive answer. 
>> 
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 
>> 
>> 

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

Reply via email to