Proposal: Add syntactic sugar for iterating over an Optional<SequenceType>

The syntax could be
for x in array? {

}

It wouldn't necessarily be consistent with

if let foo = foo {

}

But as I've mentioned in another thread regarding the if let syntax and variable shadowing, it would probably make more sense to new users if the if let syntax was the following.

if let foo = foo? {

}

The ? is always used to conditionally unwrap optionals. It strikes me as odd that they are not used to unwrap them in control flow statements.

i.e. Why should

array?.forEach

be any different than,

for x in array?

Tyler

···

On Dec 20, 2015, at 12:15 PM, Marco Masser via swift-evolution <swift-evolution@swift.org> wrote:

I have to admit that Radek’s comment about “for … in? …” meaning an iteration over a SequenceType containing Optional Values is valid.

But I think “for? … in …” is worse because it separates the “?” from the thing that is the Optional thing. Consider:

for? x in array { … }

vs.

for x in? array { … }

If any of these two is about iterating over an Optional<SequenceType>, it’s the second one – at least to me. The first one reads much more like the “x” could be optional.

Marco

On 2015-12-18, at 22:24, Radosław Pietruszewski via swift-evolution <swift-evolution@swift.org> wrote:

That’s… definitely an improvement as far as ambiguity is concerned, but I still don’t believe it passes the usefulness threshold, and I don’t really like the precedent of having a `for?`…

PS. FWIW, I like the spirit of the proposal, just not this solution. I’m all for “expressivity enhancements” — little things that helps me write cleaner code and express my intention better. But this doesn’t seem worth the trouble of extending the language.

— Radek

On 18 Dec 2015, at 22:20, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:

How about `for? object in array` instead?

On Fri, Dec 18, 2015 at 1:13 PM, Paul Cantrell via swift-evolution <swift-evolution@swift.org> wrote:

`for object in? array` … suggests that there’s something optional about checking for inclusion, not about the array itself. It could easily be interpreted as “iterate for all non-nil elements of array (where array: [T?])” — a use case arguably more common than this.

That’s a really good point.

P

On Dec 18, 2015, at 3:06 PM, Radosław Pietruszewski <radexpl@gmail.com> wrote:

Personally, I’m -1 for the proposal. I see this as a solution to a very minor, fairly rare, and not generalizable problem.

Perhaps more importantly: the syntax is confusing to my eyes. `for object in? array` doesn’t immediately convey its semantics to me. It suggests that there’s something optional about checking for inclusion, not about the array itself. It could easily be interpreted as “iterate for all non-nil elements of array (where array: [T?])” — a use case arguably more common than this.

In the vast majority of cases, arrays shouldn’t be optional in the first place. It’s rare that there’s a semantic difference between “empty array” and “no array”.

Sure, in that example it’s quite simple. It’s not the “?? ” syntax itself, which is perfectly clear; it’s having that dangling off the end of some longer expression. In real-world context, it does become additional noise.

That is a good point, albeit one that’s more broad than that — I dislike how `as?` often forces me to add additional parentheses — and not strong enough to warrant an introduction of a new `in?` construct IMHO.

— Radek

On 18 Dec 2015, at 21:56, Paul Cantrell via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 17, 2015, at 4:08 AM, Jeremy Pereira <jeremy.j.pereira@googlemail.com> wrote:

On 16 Dec 2015, at 19:52, Paul Cantrell via swift-evolution <swift-evolution@swift.org> wrote:

I do this a lot:

   for object in array ?? {

…and it does impair readability a bit at times.

Does it? It seems fairly understandable to me even though I have never seen it before.

Sure, in that example it’s quite simple. It’s not the “?? ” syntax itself, which is perfectly clear; it’s having that dangling off the end of some longer expression. In real-world context, it does become additional noise.

I think there is a good reason for keeping this construct a bit “clunky”. Generally APIs give you a nil array for one of two reasons:

- there was some sort of error in retrieving the elements
- there were no qualifying elements found.

You’re forgetting the third case, the most common one: things not populated / initialized yet. In that case, we often just want to leave a UI blank, for example, and doing nothing is the right behavior.

Doing nothing is the right behavior in a lot of cases, and since Swift provides optional sugar for “do nothing if nil” in other cases:

    foo?.bar = baz
    if let foo = bar { }

…it makes sense to provide it in for loops too.

True, “do nothing” is not the right behavior in all cases. Thus the `for…in` / `for … in?` distinction.

In the second case, the API is wrong.

Then a lot of APIs are wrong! NSURLComponents, for example:

        for item in urlComponents.queryItems ??
            { queryDict[item.name] = item.value }

But then I don’t think NSURLComponents is making a mistake: it distinguishes “no query string” from “empty query string”, but for the purposes of the loop here, there upshot in both cases is “no query items.”

True, ?? is minor noise — but given the clarity and low impact on existing code of a `for … in?` counterpart to `for … in`, it’s worth at least considering that option.

Cheers,

Paul

_______________________________________________
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