[swift-evolution] [Pitch] Retiring `where` from for-in loops

let var go letvargo at gmail.com
Mon Jun 13 13:42:16 CDT 2016


On Mon, Jun 13, 2016 at 8:54 AM Erica Sadun <erica at ericasadun.com> wrote:

>
> On Jun 13, 2016, at 9:44 AM, let var go via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> I think we must be reading different discussions.
>
> What I have seen in this discussion is the following:
>
> a) The need to filter a for-in loop doesn't arise that often; but,
> b) When it does arise, everyone who has chimed in on this thread (except
> the two people who are proposing the change) thinks that the "where" clause
> is the clearest, most expressive way to do it.
>
>
> As a point of order, may I request you stop singling out "the two people
> who are proposing the change" and discuss the merits of the pitch rather
> than the people involved in the discussion. Details of the Swift community
> code of conduct can be found here:
> https://swift.org/community/#code-of-conduct
>
> As syntactic sugar, the filtering syntax is rarely used, hard to discover,
> and elevates one style (continue if false) above others (continue if false,
> break if true, break if false), which are not expressible using similar
> shorthand. It introduces a fluent style that discourages design comments at
> the point of use and can be difficult to breakpoint during debugging. 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.
>
> In response, I'd like to hear why "continue if false" should be
> prioritized above the other options and should be retained, or
> alternatively why the suite should be completed (as in the original
> discussion with "while") in preference to the advantages accrued by guard.
>

The way you broke it down into the four different categories was helpful to
me - I hadn't thought of it that way before. Here's may take on it:


   - "continue if false"
   - This is the current 'where` keyword.
   - "continue if true"
      - This is the inverse of the current 'where' option. Because it is
      the inverse, it doesn't need a separate keyword. You just add the logical
      not '!' to the predicate, or just reverse the test, to obtain the inverse
      filtering operation.
      - So, for example, `for string in strings where
      string.hasPrefix("somePrefix")` becomes `for string in strings where
      !string.hasPrefix("somePrefix")`; or `for x in xs where x < 5`, becomes
      `for x in xs where x >= 5`
      - Using a single keyword but reversing the predicate isn't the only
      approach but it has the advantage of not polluting the language with
      unnecessary keywords where a single keyword can do the job.
   - "break if false"
      - In this scenario, you start looping through a collection, but exit
      early when some condition is no longer true. It combines a for...in loop
      with a 'while' loop.
      - This construct would allow you to set a condition for early exit
      from the loop. The problem I see with this is that when I need to exit a
      loop early, I usually need to do something else first, like
assign a value
      to a variable, or take some other action. So for example, I might do
      something like this:

var nextEvent: Event?
for event in events {
    if event.time >= now  {
        nextEvent = event
        break
    }
}

   - The point is that before I could use 'break', I had to take some
      action (assign a value to nextEvent). So just defining an early exit
      condition wouldn't really work. I'm trying to think of a use-case where I
      would want to exit early without doing anything first, and I can't. Given
      the appropriate use case, however, I could see a place for a keyword that
      did this like 'until', or 'while'. Until then, though, I
wouldn't create a
      keyword for something that doesn't have a common use. Filtering with
      'where' is at least used sometimes, even if it isn't the most common
      pattern on the planet.
   - "break if true"
      - I would apply the same arguments in "break if false"

So I would say that "continue if false" and "continue if true" are
accomplished using the same keyword, and "break if false" and "break if
true" don't have demonstrated use cases that can be solved with a
keyword/predicate combination - early exit usually requires some additional
action other than just exiting which couldn't be easily baked into the
keyword.


>
> Thank you,
>
> -- Erica
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160613/71f93d81/attachment.html>


More information about the swift-evolution mailing list