[swift-evolution] [Idea] Use optionals for non-optional parameters

Justin Jia justin.jia.developer at gmail.com
Mon Aug 15 03:15:45 CDT 2016


Thanks for pointing this out! But I think `foo?.bar(baz(42))` should be equivalent to:

```
if let foo = foo {
    let x = baz(42)
    foo.bar(x)
}
```

IMHO, this is consistent with my example. Instead of worrying about "short-circuit", we can just treat ? as the syntax sugar of if let?

> On Aug 15, 2016, at 4:07 PM, Jean-Daniel Dupas <mailing at xenonium.com> wrote:
> 
>> 
>> Le 15 août 2016 à 10:01, Justin Jia via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> a écrit :
>> 
>> 
>>> On Aug 15, 2016, at 3:53 PM, Charlie Monroe <charlie at charliemonroe.net <mailto:charlie at charliemonroe.net>> wrote:
>>> 
>>>> 
>>>> On Aug 15, 2016, at 9:46 AM, Justin Jia via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>>> 
>>>> I think the `?` will make the return an optional. So your example should add another ? at the end.
>>>> 
>>>> ```
>>>> print(foo(bar(42)?, baz(42)?)?)
>>> 
>>> This reads terribly, IMHO.
>>> 
>> 
>> I agree that this reads terribly. But this is only an edge case. I would prefer `let output = foo(bar(42)?, baz(42)?); print(output?)`. However, I want to argue that for most cases “?” reads better than “if let”.
>> 
>>>> ```
>>>> 
>>>> The above example should be equivalent to:
>>>> 
>>>> ```
>>>> let x = bar(42) // X is optional
>>>> let y = baz(42) // Y is optional
>>>> 
>>>> let z = foo(x?, y?) // Z should be optional now
>>>> print(z?)
>>>> ```
>>>> 
>>>> which should be equivalent to;
>>>> 
>>>> ```
>>>> let x = bar(42)
>>>> let y = baz(42)
>>>> 
>>>> if let x = x, let y = y {
>>>>     z = foo(x, y)
>>>> }
>>> 
>>> What if baz doesn't return optional?
>>> 
>> 
>> If baz doesn’t return optional, then we don’t even need this syntax:
>> 
>> We can just write: `z(bar(42)?, baz(42)` and treat baz(42) like normal.
>> 
>> Which should be equivalent to:
>> 
>> ```
>> ```
>> let x = bar(42)
>> let y = baz(42)
>> 
>> if let x = x {
>>     z = foo(x, y)
>> }
>> ```
>> 
> 
> It is not consistent which what I expect when calling foo?.bar(baz(42))
> 
> In that case, if foo is nil, bad is never evaluated.
> 
> 
>>> if let x = bar(42) {
>>> 	let y = baz(42)
>>> 	z = foo(x, y)
>>> }
>>> 
>>> or 
>>> 
>>> let y = baz(42)
>>> if let x = bar(42) {
>>> 	z = foo(x, y)
>>> }
>>> 
>>> 
>>> If both are evaluated, this is really inconsistent with
>>> 
>>> if let x = bar(42), y = baz(42) { ... }
>>> 
>>> which will short-circuit and baz will not be evaluated if x is evaluated as nil.
>>> 
>>>> 
>>>> if let z = z {
>>>>     print(z)
>>>> }
>>>> ```
>>>> 
>>>> We don’t need to worry about “short-circuit” now because it should be equivalent to the above syntax.
>>>> 
>>>> > It has been mentioned before (more than once, perhaps, but not in its own thread I don't think, so good luck finding it). IIRC, one of the problems is that it's unclear what happens if your function takes multiple arguments. Does evaluation proceed from left to right? does it short-circuit? Put concretely:
>>>> > 
>>>> > ```
>>>> > func bar(_ x: Int) ->Int? { /* side effects */ }
>>>> > func baz(_ y: Int) ->Int? { /* side effects */ }
>>>> > func foo(_ z: Int, _ a: Int) ->Int { /* ... */ }
>>>> > 
>>>> > print(foo(bar(42)?, baz(42)?))
>>>> > ```
>>>> > 
>>>> > Does baz(42) get evaluated if bar returns nil? Does bar(42) get evaluated if baz returns nil?
>>>> > 
>>>> > 
>>>> > On Mon, Aug 15, 2016 at 2:02 AM, Justin Jia via swift-evolution<swift-evolution at swift.org <mailto:swift-evolution at swift.org>(mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>)>wrote:
>>>> > > Hi!
>>>> > > 
>>>> > > I don’t know if this has came up before. I tried to search though the mailing list but didn’t find any related threads.
>>>> > > 
>>>> > > This is purely a syntactic thing (which I know it’s the lowest priority for Swift 4), but I think it’s an important one.
>>>> > > 
>>>> > > Let’s say we have a struct with a function:
>>>> > > 
>>>> > > ```
>>>> > > struct Foo {
>>>> > > func bar(x: Int)
>>>> > > }
>>>> > > ```
>>>> > > 
>>>> > > We can use optionals:
>>>> > > 
>>>> > > ```
>>>> > > let foo: Foo? = nil
>>>> > > let x = 1
>>>> > > foo!.bar(x: x) // Able to compile, but will cause runtime error
>>>> > > foo?.bar(x: x) // Able to compile, and won't cause runtime error
>>>> > > ```
>>>> > > 
>>>> > > However:
>>>> > > 
>>>> > > ```
>>>> > > let foo = Foo()
>>>> > > let x: Int? = nil
>>>> > > foo.bar(x: x!) // Able to compile, but will cause runtime error
>>>> > > foo.bar(x: x?) // Won't compile
>>>> > > ```
>>>> > > 
>>>> > > I propose that we should allow `foo.bar(x: x?)`, which should be equivalent to:
>>>> > > 
>>>> > > ```
>>>> > > if let x = x {
>>>> > > foo.bar(x: x)
>>>> > > }
>>>> > > ```
>>>> > > 
>>>> > > What do you think?
>>>> > > 
>>>> > > Thanks,
>>>> > > Justin
>>>> > > 
>>>> > > _______________________________________________
>>>> > > swift-evolution mailing list
>>>> > > swift-evolution at swift.org <mailto:swift-evolution at swift.org>(mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>)
>>>> > > https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>> > 
>>>> > 
>>>> > 
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160815/992eafb5/attachment.html>


More information about the swift-evolution mailing list