[swift-evolution] [swift-evolution-announce] [Review] SE-0105: Removing Where Clauses from For-In Loops

Kevin Ballard kevin at sb.org
Thu Jun 23 14:14:31 CDT 2016

>       * What is your evaluation of the proposal?
-1. I don't think this is really a big deal, but I find where clauses on
for loops to be very elegant, and I'm not convinced by any of the
arguments for why they should go away.
I'm especially not convinced by the argument over the behavior itself
being confusing, e.g. the fact that it's equivalent to a continue rather
than a break. You know what else is equivalent to a continue that this
proposal isn't modifying? `for case pattern in`. If the refutable
pattern does not match, the element is skipped and the for loop
continues to the next. This is precisely how the `where` clause works
(and it's no surprise that the two were introduced at the same time). So
the argument that says we should remove `where` in favor of explicit guard-
continues also implies that we should remove `for case pattern in`,
which I would strongly disagree with.
>       * Is the problem being addressed significant enough to warrant a
>         change to Swift?
I don't think so. As the proposal argues, this feature is not very widely-
used, at least within open-source code (though as others have pointed
out, there's no data on how much it's used in closed-source code, and
it's plausible that there is far more closed-source Swift code than open-
source). Since it's not widely-used in public, the arguments for
removing it aren't very significant. And the people who do use it tend
to like the feature. And I agree with the people who have pointed out
that it's not the Swift compiler's job to enforce a single coding style.
> * How much effort did you put into your review? A glance, a quick
>   reading, or an in-depth study?
Reading the proposal and this review thread.
On Thu, Jun 23, 2016, at 10:25 AM, Erica Sadun via swift-evolution wrote:
>> On Jun 23, 2016, at 7:42 AM, Ryan Lovelett via swift-evolution <swift-
>> evolution at swift.org> wrote:
>>> Is the problem being addressed significant enough to warrant a
>>> change to Swift?
>> No. In fact, I think that even the proposal itself says as much. The
>> proposal indicates it means to deprecate an available coding
>> style. It
>> seems to me, as much as is practicable, style changes should be
>> enforced
>> by something other than the Swift compiler.
> I in no way intended the proposal to "say as much".
> As syntactic sugar, the filtering syntax is
>  * rarely used in published deployed code,
With no info on how often it's used in closed-source code. Just
looking at a single closed-source project (the Postmates app), we use
the where clause on for loops 7 times, which is more than your
proposal says the stdlib and a random sampling of open source projects
uses combined. And this is just one project, so who knows how much
it's used in other projects.
>  * hard to discover (although I like others have taught it to promote
>    its visibility),
If there's an educational issue here, that should be addressed in the
documentation (i.e. the book), rather than by removing the feature.
>  * elevates one style (continue if false) above others (continue if
>    false, break if true, break if false), which are not expressible
>    using similar shorthand,
I completely disagree. Removing this feature is elevating one style (guard-
continue) over another. Keeping the feature is not making any judgement
call about style whatsoever. And as I said above, `for case pattern in`
already has the continue-if-unmatched behavior, so removing this feature
does not mean the for loop no longer has a way to assume continue.
>  * introduces a fluent style that discourages design comments at the
>    point of use,
You can comment where clauses. Just put it on a new line.
>  * can be difficult to breakpoint during debugging.
This can be said about a lot of things. If I want to breakpoint my where
clause, I can convert it to a guard-continue. Although first I'd try
putting the clause on its own line and seeing if lldb is smart enough to
then break just on the where clause.
> I think these are significant issues.
> The recommended alternative (using a separate guard) addresses all
> these points: better commenting, better breakpointing and debugging,
> and fully covers the domain of filtering and early exiting. If
> chaining is desired, using filter and prefix(while:) address all
> conditions, allow better commenting, etc, and are more self-
> documenting.
You can already use a separate guard. The existence of the where clause
on a for loop does not in any way detract from the ability to use a
separate guard.
>> On Jun 23, 2016, at 9:07 AM, Tony Allevato via swift-evolution <swift-
>> evolution at swift.org> wrote:
>> The fact that some users may be confused by this terminology is not a
>> reason to remove it from the language. Some users will be confused by
>> many concepts in programming languages. If that means this is
>> considered an "advanced" feature, so be it. We should be able to have
>> a language that has both basic features and advanced features, and
>> when a new developer comes across a feature they don't understand,
>> they learn it, and then they know it. This is not an insurmountable
>> problem.
> For the advanced user, filter and prefix are more customizable and
> provide greater coverage of cases involving fine control over
> sequences.
Then use them when appropriate. In many cases the where clause is
sufficient and more elegant. Using filter and prefix also introduce the
hazard of forgetting to add ".lazy", which means you're allocating a new
array when you don't need to.
>> On Jun 23, 2016, at 3:02 AM, Jonathan Hull via swift-evolution <swift-
>> evolution at swift.org> wrote:
>> I just taught this to a class of newbies last week and exactly zero
>> of them had trouble with it.  I told my TA that we were debating
>> removing it, and he was horrified.  “It is one of the best features
>> of Swift!” he said.  I agree.  It is one of the things which gives
>> Swift character and makes it fun.
> I have also taught this construct, which is always a counterpoint to
> discoverability issues.
> If you step back and ask: "If this feature were not in the language
> already, would it be added?", we would have to discuss why "positive
> filtering" should be prioritized as it is and if we include it, what
> syntax would least confuse users encountering it for the first time.
> Surrounded as I am by learner-developers, I recognize that this is a
> real stumbling block -- no matter how ubiquitous it is in SQL, for
> example -- and have provided examples of both new and experienced
> developers being confused.
The feature wasn't in the language, and it was added. The previous
examples of "if this feature were not in the language already" questions
were all about pre-1.0 features. This feature was added later (IIRC in
Swift 2). And as I said above, this feature complements the `for case
pattern in` behavior. `for case pattern in` lets you skip elements based
on a refutable pattern, and `where` lets you skip elements based on a
boolean condition.
-Kevin Ballard
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160623/872bffb2/attachment.html>

More information about the swift-evolution mailing list