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