[swift-evolution] Optional Argument Chaining

Adrian Zubarev adrian.zubarev at devandartist.com
Tue Dec 12 05:11:54 CST 2017


I think it might be a good idea to reuse optional function syntax in this case. I don’t think it would even break existing code with the rule I described in my previous post. I mean, in the end the result of the whole function becomes optional (only if it was non-optional before, or it simply stays optional otherwise).

foo?(bar?(x)) +? y
Problematic are the operator functions because there is no way to really disambiguate those - at least right now, nor can we reference them like Int.+ and in the worse case it would require us to burn all operators with a trailing ?. Even more complicated is the ?? operator.

On the other hand we could simply say that an operator function is a special case, where we cannot make the function optional with this syntax. That would mean that operator functions (and subscripts?) still would require the old fashion way:

let result: FooResult?
if lhs = foo?(bar?(x)), let rhs = y {
    result = lhs + rhs
} else {
    result = nil
}
However here is my thinking in a different direction for operator functions and subscripts:

If we could explicitly reference operator functions like Int.+ or Swift.??, would it be possible to disambiguate the above case like this?

(Int.+)?(lhs: foo?(bar?(x)), rhs: y)
Here is the syntax as pitched that works today:

@objc protocol P : AnyObject {
    @objc optional static func functionName(label: Int)
    @objc optional func otherFunctionName(label: Int)
}

@objc class A : NSObject, P {}

let type: P.Type = A.self
(type.functionName)?(label: 42)

let instance: P = A()
(instance.otherFunctionName)?(label: 42)
We may need to fix optional subscripts first because the implicit behavior is really weird IMHO:

@objc protocol P : AnyObject {
    @objc optional subscript (label value: Int) -> Int { get }
}

@objc class A : NSObject, P {}

let instance: P = A()
instance[label: 42] // => compiles and returns nil
We definitely should require an infix ? here - instance?[label: 42].

Then even subscripts would work with the same syntax I pitched before. ;)


Am 11. Dezember 2017 um 23:42:58, Slava Pestov via swift-evolution (swift-evolution at swift.org) schrieb:



On Dec 11, 2017, at 2:41 PM, Jared Khan via swift-evolution <swift-evolution at swift.org> wrote:

I missed the previous threads! I’ve found one of the relevant threads here:
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160711/024201.html

Thanks for this important point.

If you were to write this logic out by hand then you would short-circuit it and this is analogous to current chaining behaviour so to me evaluating left to right (as Swift usually does) and stopping at the first failed unwrap would make sense. I wouldn’t necessarily say it’s intuitive but I don’t think it’s really less intuitive than the current chaining behaviour. 

I think it gets confusing when you have multiple levels of nested expressions, eg

foo(bar(x?)) + y?

Slava


Jared

On 11 Dec 2017, at 19:28, Xiaodi Wu via swift-evolution <swift-evolution at swift.org> wrote:

This topic has been discussed at least two and maybe more times in the past.. It’s hard for me to post links at the moment, but it should be possible to find on Google.

One major challenge to this idea, for which no satisfactory answer has been achieved after all these years, is the following issue:

f(g()?, h()?, i(), j()?)?

If g() evaluates to nil, is h() called or not? How about i(), which is not failable? Since any function or property access can have side effects, in what order are the arguments evaluated, and how does one reason about this code flow?

To my mind, in the absence of an intuitive answer to the above—which does not appear to be possible—this idea is not feasible.
On Mon, Dec 11, 2017 at 12:34 Magnus Ahltorp via swift-evolution <swift-evolution at swift.org> wrote:

> 12 Dec. 2017 02:58 Jared Khan <jaredkhan at me.com> wrote:
>
> 2. It felt natural to me. It’s analogous to the existing optional chaining scenarios and composes nicely. I think it’s about as understandable as existing chaining, a newbie would have to look it up to discover its meaning. What are your thoughts on this particular syntax (ignoring 3. momentarily)? Hopefully others in this thread can share their views too.

Chaining methods is linear, while nesting fills a similar purpose when we use function calls. This of course affects the way existing Swift code is written, but that is something we have to live with if we want to use familiar syntax patterns. However, I think we have to consider this difference in this case, since the syntax becomes more convoluted. Your suggestion is definitely not as easy to read as the optional chaining syntax, and maybe it can't be.

> As for how common I’d expect it to be, it’s something I’ve run into myself a few times. Again, I hope members of this list can give their view on if this would be useful to them.

I don't have any real examples, but I certainly think that I have run into it, so I'm quite open to solving the problem. For me, it is probably only a matter of finding a syntax that is acceptable.

> 3. I’m not entirely sure what the grammar situation is yet but afaik ‘?’ has never been available as a postfix operator. Perhaps I’m missing your point, could you demonstrate where it is allowed?

I did not expect that you would be able to answer that, it was more a question directed to people who are more connected to the inner workings of the parsing of Swift than I am. It is not allowed, but the error message is not the one I expect, something that gives me a hint that it does have some meaning early in the parsing.

/Magnus

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

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

_______________________________________________
swift-evolution mailing list
swift-evolution at swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20171212/5beaa66f/attachment.html>


More information about the swift-evolution mailing list