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


(Chris Lattner) #1

Hello Swift community,

The review of "SE-0105: Removing Where Clauses from For-In Loops" begins now and runs through June 29. The proposal is available here:

  https://github.com/apple/swift-evolution/blob/master/proposals/0105-remove-where-from-forin-loops.md

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

  https://lists.swift.org/mailman/listinfo/swift-evolution

or, if you would like to keep your feedback private, directly to the review manager.

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and contribute to the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  * What is your evaluation of the proposal?
  * Is the problem being addressed significant enough to warrant a change to Swift?
  * Does this proposal fit well with the feel and direction of Swift?
  * If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  * How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at

  https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

-Chris Lattner
Review Manager


(Chéyo Jiménez) #2

  * What is your evaluation of the proposal?

-1. It removes a feature that I love about Swift.
When `for;;;` was removed, I thought to my self , we have `where` to help on tricky situations.
Removing `where` would make working with for loops more terse.
I do not like using guards in my for loops; I would rather use the old for;; than to use guards.
Guards are just not the way I think about loops in general. (Plus I think they are ugly)

It makes sense why SE-0099 removed `where`. We got a whole lot more functionality by giving up `where`.
This proposal SE-0105 is taking away functionality by forcing guards continues and breaks.
There is not additional functionality being suggested other than forcing one way of doing things.

I don’t think renaming where to `if` helps any. I don’t like the idea even though I love the way python uses it.
Using `if` instead of `where` will overload yet another pattern on top of `if`. (if case, if let, if var, if if if)

I want more features to be added to 'for in whee’ loops, not them being taken way.

  * Is the problem being addressed significant enough to warrant a change to Swift?

nope.

  * Does this proposal fit well with the feel and direction of Swift?

don’t think so.

  * If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

python.

  * How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

I followed the proposal and discussions.


(Charlie Monroe) #3

  * What is your evaluation of the proposal?

-1. As I was all along during the discussion here, I find the ability to automatically filter the sequence using where as useful and a nice language feature. I do not find the syntax confusing, on the other hand the alternatively suggested replacement with "if" is confusing to me.

IMHO the frequency of use is not a very good point since as I've mentioned during the discussion, the fact that it's not very used in popular Swift repositories may be partially given that this feature isn't documented well - the Swift Programming Language book on Swift.org doesn't mention this and neither does any material on developer.apple.com.

It was pointed out that neither does the stdlib use it frequently, but that's quite a specific piece of work, not reflecting the common use cases.

  * Is the problem being addressed significant enough to warrant a change to Swift?

No.

  * Does this proposal fit well with the feel and direction of Swift?
  * If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  * How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Read + discussion.

···

More information about the Swift evolution process is available at

  https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

-Chris Lattner
Review Manager

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


(Ryan Lovelett) #4

What is your evaluation of the proposal?

Negative.

The “Motivation” logic seems incongruent possibly even contradictory.
The where syntax is cited as “… rarely used, [and] hard to discover ….”
while simultaneously a source of confusion to new developers. Taking
both statements together this proposal seems to be aimed at a sub-set of
a sub-set of developers. That alone would tell me this is a problem that
is not significant enough to warrant a change to Swift.

Unfortunately the statistics provided in the proposal heavily weigh
open-source Swift code and discount code written in closed-source
applications. My intuition, based on the volume of feedback provided on
the swift-evolution mailing list, tells me there is likely to be some
practical Swift code written in closed-source and enterprise
applications that is not being equally counted by the proposal
statistics. While the intent of the argument, that the syntax is not
widely used, is warranted I question these statistics and methods.

Additionally in the “confusion of use” example the `while` loop would
seem to be a moot point. It is my understanding that SE-0099 has already
removed the inconsistent `while` condition. Assuming that is true, it is
hard to believe that future new developers are going to be confused by a
syntax that they are unable to experience or use. If this assumption is
incorrect than I'd argue the correct course of action is to remove the
`while` loop behavior rather than for-in behavior.

Moving to more concrete code based examples. The introduction
effectively states that the proposal means to enforce a coding style or
convention by removal of another. This seems like something that should
be enforced by a linting tool, not the Swift compiler. To put a point on
this, I looked at one snippet of code cited in the “Frequency of Use”
section as a concrete example of what code would look like before and
after accepting the proposal [1].

Before:

/// Returns the greatest argument passed.
///
/// If there are multiple equal greatest arguments, returns the last
one.
public func max<T : Comparable>(_ x: T, _ y: T, _ z: T, _ rest: T...) ->
T {
  var maxValue = max(max(x, y), z)
  // In case `value == maxValue`, we pick `value`. See min(_:_:).
  for value in rest where value >= maxValue {
    maxValue = value
  }
  return maxValue
}

After:

/// Returns the greatest argument passed.
///
/// If there are multiple equal greatest arguments, returns the last
one.
public func max<T : Comparable>(_ x: T, _ y: T, _ z: T, _ rest: T...) ->
T {
  var maxValue = max(max(x, y), z)
  // In case `value == maxValue`, we pick `value`. See min(_:_:).
  for value in rest {
    guard value >= maxValue else { continue }
    maxValue = value
  }
  return maxValue
}

It is not obvious to me how removing the `where` and adding the `guard`
“reduce[d] cognitive burden when interpreting intent”. Frankly in my
estimation it increased it. Now the for-in loop declaration has to be
read along with the trailing `guard` to interpret the intent of the
loop. I concede it is possible I just do not understand what is meant by
cognitive burden when interpreting intent. But I cannot shake the
feeling the argument is specious.

At this point I would like to draw attention to the fact that both the
“Before” and “After” syntax are fully supported in Swift right now. If
one is preferred by a developer as clearer both options are available.
And as I pointed out earlier could be enforced by a linting tool.

The motivation provided for the removal of the feature would seem to be
applicable to any number of existing Swift features. Not least of which
is the pattern matching for-in loop.

enum Thing { case One; case Two; case Three; case Four }
let foo: [Thing] = [.One, .Two, .One, .Three, .Four, .One]
for case .One in foo { print("Found a .One") }

I feel confident that most (all?) of the motivations applied by this
proposal would be equally applicable to the example pattern matching
for-in loop above. Especially the strongest of those arguments,
specifically that it elevates one style, the `continue` on condition,
above other related styles.

[1]
https://github.com/apple/swift/blob/a51aa91032ff7ba13bdc883122f4e8868aee6413/stdlib/public/core/Algorithm.swift#L47-54

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.

The proposed `guard` syntax is complete today and is available as a
“work-around” for any of the conditions not elevated by this existing
Swift syntactic sugar feature.

Of course, other alternatives could be considered, such as expanding
this behavior to include `while`, `unless` and `until`. Though that
change seems pre-mature. A more pragmatic approach, since the change
would be additive, would be to defer until after Swift 3.

Does this proposal fit well with the feel and direction of Swift?

No. Swift.org [1] lists as one of the “additional” features of the
language “Fast and concise iteration over a range or collection”.
Removing this feature does little to positively augment that feature.

Swift is opinionated. This is a good thing. It should have strong
opinions about safe, fast and expressive code. I do not believe the
existing for-in where clause syntax violates any of those features.
Furthermore it does nothing to increase the joy of writing Swift code
(an explicitly stated goal of Swift [1]).

[1] https://swift.org/about/

If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

I’ve never experienced this syntax in other languages. Though, coming
from C, it is a welcome improvement over that language’s syntax and
provides a lot of practical value.

How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

A fairly in-depth study. I looked at code that I have access to inside
of my work environment (as well as refactoring some for-in loops). I
also actively participated in the discussion on the swift-evolution
mailing lists.

Additionally, I discussed with co-workers and spouse. These discussions
were especially illuminating to me. Because many of my co-workers, as
well as my spouse, while being professional software developers, have
never worked with Swift. Not a single person I was able to discuss the
topic with was confused by the existing syntax regardless of their
experience level with Swift. Most shared confusion as to why the
proposed `guard` syntax was considered better at all. Most found `guard`
in and of itself to be more confusing than `where` combined with for-in.
Though it does strongly color my opinion of these changes it is, of
course, purely anecdotal.


(Matthew Johnson) #5

  * What is your evaluation of the proposal?

-1. It removes a useful feature. Swift 3 has already removed enough and the argument in this case feels pretty weak to me.

I have no doubt that *some* people are confused by this feature, but that will be the case for any feature. This feature is very similar to features in many other languages. The potential for confusion here seems pretty low for anyone familiar with SQL, list comprehensions, etc. Those who aren’t familiar with this construct may be delighted once they learn how it works. If this was an entirely novel programming language feature I might be more sympathetic to the learnability / potential for confusion argument, but it isn’t and the argument in this case is weak IMO.

The style argument is also weak. The Swift compiler is *not* the right place to enforce style. Other proposals attempting to enforce style rules have been rejected and this one should as well.

The argument that `guard` is a more complete replacement is true, but it also completely disregards the fact that filtering is by far the most commonly desired behavior. Swift embraces syntactic sugar for common cases in many places. In that respect this feature fits the language very well. Moving the condition into the loop and requiring explicit control flow is significantly *less* clear and readable IMO.

The argument that this feature is not commonly used only considers a relatively small amount of code in very specific domains. It does not provide any analysis of *why* this might be the case. The findings could be due to the domains in question or stylistic preferences of the authors of the code in question. I’ll concede that the authors of the standard library and Carthage are probably familiar with this feature, but outside of this context the feature may still be relatively unknown. Removing a feature on grounds that it is not commonly used without an analysis of *why* is a bad idea, especially in a relatively new language like Swift where many programmers it is targeting are just starting to learn the language.

Finally, I think “breakage fatigue” in Swift 3 is a valid concern. We are making major changes and removing several conveniences. We should not do this more than necessary. This change does not feel necessary.

It may be possible to improve this feature or replace it with something more powerful down the road, but we should not speculatively remove it now on grounds that we might do that later.

  * Is the problem being addressed significant enough to warrant a change to Swift?

No.

  * Does this proposal fit well with the feel and direction of Swift?

No. It removes a very Swifty (IMO) convenience feature without a compelling reason to do so.

  * If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

I have used languages both with and without features similar to `for in where`. This is a very nice feature in languages that have it. I would be disappointed to see Swift remove it without replacing it with something more powerful.

  * How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

I followed the discussion thread, read the proposal, read the reviews, etc.


(Sean Heber) #6

The review of "SE-0105: Removing Where Clauses from For-In Loops" begins now and runs through June 29. The proposal is available here:

  https://github.com/apple/swift-evolution/blob/master/proposals/0105-remove-where-from-forin-loops.md

  * What is your evaluation of the proposal?

Huge -1.

In my opinion, structuring for-loops to take advantage of “where” can turn a confusing or difficult filtering rule into a SQL-like declarative statement that’s easier to read and easier to reason about.

The proposal seems to make an assumption that using where conditions makes the logic impenetrable since I believe there’s an underlying assumption that it is common to chain 3 or 4 or 5 conditions there. In my experience, that is very much NOT the case. In fact I would argue that the syntax of “where” and the way it is structured encourages brevity and clarification of intent in ways that a list of guards and ifs cannot because a bunch of guard/if statements has no syntactic pressure limiting their proliferation in the loop’s body whereas the “where” construct does.

Usage metrics are not a strong argument to me. I know that argument was also partially used to support removal of C-style for-loops (a decision with which I strongly support), but in that case I feel there were many other good supporting arguments in play. In the case of removing “where”, it seems the primary argument is usage stats pulled from a few open source projects (some of which may even have code predating the introduction of “where” on for loops) and some anecdotal suggestions that it might be confusing the very first time someone encounters it without having read the documentation beforehand. The latter argument is very weak, IMO, because as far as I can tell, there is zero evidence (not even anecdotal) that once a person learns how “for-where” works that there is ever confusion about it again or that it is ever a source of bugs as a result of confusion.

If this proposal was for replacing for-where with a full fledged Python-ish list comprehension kind of construct, then I might have a different opinion. As it is, it’s in favor of removing the closest thing we have to them and replacing it with nothing.

I could imagine supporting an *adjustment* to for-where’s syntax to this, for example:

for x where x < 42 in sequence {
}

However it seemed the discussion was centered almost exclusively around the idea of just getting rid of it rather than trying to fix any of the perceived flaws it may have.

  * Is the problem being addressed significant enough to warrant a change to Swift?

I don’t even agree there’s a problem to solve here.

  * Does this proposal fit well with the feel and direction of Swift?

No.

  * If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

I’ve used many languages without for-where. After using Swift and for-where, I no longer like those languages as much.

  * How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

I was a reasonably active participant in the discussion for a time.

l8r
Sean


(Scott James Remnant) #7

-1

An important goal in Swift is “clarity at the point of use,” it appears in the API Design Guidelines as one of the fundamentals, but also pervades the design of the Swift language itself.

I think that removing the `where` clause from Swift’s `for` loops will reduce clarity of intent for many programmers.

It may be that `for`/`where` and `for`/`guard`/`continue` express the same result for the compiler, but an identical compiled output does not necessarily equate to an identical intent on behalf of the programmer. I do not believe that it has ever been a Swift goal that “there is only way one way to do it.”

Please consider the following example code:

  for line in lines where !line.isEmpty() {
    …
  }

The intent of this code is clear to the reader. A set of lines from a line is being iterated, and filtered such that the code within the loop is only operating on those that are not empty. This is a fairly common pattern when working with files, for example. It may be that the code within the loop would work perfectly well even in the case of empty lines, the programmer simply does not wish to consider them.

Filtered iteration is a common pattern throughout programming, other uses include things like iterating the set of “updated objects” in Core Data, etc.

Now consider the equivalent avoiding a `where` clause, and replacing it with `guard`:

  for line in lines {
    guard !line.isEmpty() else { continue }
    …
  }

To the compiler it is the same code, but to the programmer this may have a very different intent.

`guard` in Swift is _not_ simply a generic `unless` statement, the name was chosen very specifically and less harsh names rejected. `guard` belongs closer to the family of `assert` and `precondition` than it does to `if`. `guard` is used to provide an expression of pattern that *must* be true for the code following it to operate without error or other unintended side-effects. This is why the `else` block must, in some way, exit the containing scope of the `guard`.

In first example the code makes it clear, to me, that it is normal for the set of lines to contain non-empty, and empty lines. But in the second example, to me, the code makes it clear that non-empty lines are not expected in the set, and would cause the code to error if they were present; the code guards against this by stepping over them—following Postel’s Law.

My opinion would be that the correct way of preserving the intent of the first example would be either:

  for line in lines {
    if !line.isEmpty() {
      …
    }
  }

or:

  for line in lines.lazy.filter({ !$0.isEmpty() }) {
    …
  }

The second case is particularly troubling here because it’s “hard to get right” from a performance point of view. The clarity of `for`/`where` wins over all of these.

Scott


(Scott James Remnant) #8

A separate point I would make, aside from my previous long-winded comment about clarity, is that the “confusion of use” in this proposal has already been corrected by SE-0099 which has removed `where` clauses from optional-binding and case-conditions.

Scott


(Patrick Smith) #9

Yes, I’m all for removing this syntax which seems to confuse people with what it actually does. Having to write more explicit code with a `guard` or `.filter` is better than people unexpectedly creating bugs.

I’d say remove it for Swift 3, allowing a potential replacement for this functionality to be an addition and not a breaking change. It’s kind of like pruning a tree back to prepare it for new growth.

(I like Xiaodi’s suggestion of replacing `where` with `if`, but I imagine that would be a separate proposal, but interested in hear other’s thoughts on it, although I’ve probably missed some in the discussion.)

Patrick

···

On 23 Jun 2016, at 2:12 PM, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

Hello Swift community,

The review of "SE-0105: Removing Where Clauses from For-In Loops" begins now and runs through June 29. The proposal is available here:

  https://github.com/apple/swift-evolution/blob/master/proposals/0105-remove-where-from-forin-loops.md

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

  https://lists.swift.org/mailman/listinfo/swift-evolution

or, if you would like to keep your feedback private, directly to the review manager.

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and contribute to the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  * What is your evaluation of the proposal?
  * Is the problem being addressed significant enough to warrant a change to Swift?
  * Does this proposal fit well with the feel and direction of Swift?
  * If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  * How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at

  https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

-Chris Lattner
Review Manager

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


(Tony Allevato) #10

Hello Swift community,

The review of "SE-0105: Removing Where Clauses from For-In Loops" begins
now and runs through June 29. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0105-remove-where-from-forin-loops.md

Reviews are an important part of the Swift evolution process. All reviews
should be sent to the swift-evolution mailing list at

        https://lists.swift.org/mailman/listinfo/swift-evolution

or, if you would like to keep your feedback private, directly to the
review manager.

What goes into a review?

The goal of the review process is to improve the proposal under review
through constructive criticism and contribute to the direction of Swift.
When writing your review, here are some questions you might want to answer
in your review:

        * What is your evaluation of the proposal?

-1000. This is one of the features of Swift that I feel is incredibly
elegant and unique, providing a way to do basic filtering and iteration
without having to worry about lazy filtering or control flow statements.

        * Is the problem being addressed significant enough to warrant a
change to Swift?

No—in fact, there is no problem. The "where" notation is perfectly grounded
in mathematics and set theory and its meaning is clear. "for x in y where
z" reads almost exactly like the set notation "{x ∈ y | z}" does aloud.

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.

IIRC, this proposal was a follow-up to the removal of "where" in "if"
statements, but the two uses of the term are unrelated. In "if" statements,
"where" was used to separate let-bindings from other parts of the
conditional—it was not a filter over a collection and did not correspond to
existing mathematical terms of art. That's not the case here, and it feels
like surface-level consistency for consistency's sake.

        * Does this proposal fit well with the feel and direction of Swift?

No. The alternatives are worse, IMO:

* Putting if/guard and continue at the front of the loop is more clutter
and expresses the concept in terms of control flow instead of sequence
filtration, when the latter is closer to expressing the semantics of what
the loop is doing. I would argue that it increases the mental load because
now I have to parse an "if" or a "guard", the condition, and the "continue"
to make sure that it's doing exactly what it's doing (and the fact that
"guard" could be used here means there is implicit negation that I have to
parse on top of that), whereas "where foo" is right there and immediately
unambiguous.

* Using .filter() many times requires that .lazy also be used in order to
be performant. In many cases, writing the naïve .filter() line will return
a new copied collection and users are likely to accidentally write code
that is slower than it should be.

The fact that it only elevates one particular control flow construct ("if x
else continue") doesn't seem relevant. It's a common case and the language
should simplify common cases when possible. As a matter of fact, I would
also be supportive of the "for x in y while z" that some other people have
offered for the same reason. While it's less based on set theory than
"where", it optimizes another common case.

        * If you have used other languages or libraries with a similar
feature, how do you feel that this proposal compares to those?

        * How much effort did you put into your review? A glance, a quick

reading, or an in-depth study?

Read the proposal and followed the earlier discussion threads.

···

On Wed, Jun 22, 2016 at 9:12 PM Chris Lattner <clattner@apple.com> wrote:

More information about the Swift evolution process is available at

        https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

-Chris Lattner
Review Manager

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


(Fabian Ehrentraud) #11

* What is your evaluation of the proposal?
+1

   * Is the problem being addressed significant enough to warrant a change to Swift?
It's a small change, but it would improve readability a little.

   * Does this proposal fit well with the feel and direction of Swift?
Yes, e.g. when using .filter on the sequence being iterated over as an alternative, the code reads a bit more functional.

   * If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
No

   * How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
A few minutes for reading the proposal.


(Shawn Erickson) #12

I am -0.5 on removing the where clause. I will note that removing it now -
given the appearing limited usage - shouldn't cause a large disruption to
most users. It may allow us time to think more about it and things related
to it since it can be added back at a later point without breaking swift 3
users.

I personally was bitten by misusing where with a for-in, I had the mental
model that it would abort the loop. To be honest I am not sure why I had
that mental model given long history with SQL where clause and using where
heavily in switch case statements (e.g. acts as a filter). I think for some
uses I had an assumption that the optimizer could prove that the where
would in fact always filter past a certain loop point and that may have
screwed up my mental model in the general case.

If you make such a mistake with where you may never know because from a
line debugging perspective your loop content never gets executed if the
where is violated yet you may still be looping (possibly causing
destructive consumption or a performance issue).

With that said I do find the syntax fairly clean and helpful when using
for-in (if not abused by chaining many together). I don't have a better
name for it, if it stays around I think it should stay named where to align
with where in other constructs in the language.

I do think for completeness we should consider adding 'until' for abort
looping case. We should also consider moving the location of the where (and
potential until) on the other side of 'in'.

One negative to this syntax (assuming not abused) is not being able to
probe things with a line based debugger. Of course many compact constructs
in the language are that way. ...maybe someday lldb and Xcode could allow
for statement scoped breakpoints

-Shawn

···

On Wed, Jun 22, 2016 at 9:12 PM Chris Lattner <clattner@apple.com> wrote:

Hello Swift community,

The review of "SE-0105: Removing Where Clauses from For-In Loops" begins
now and runs through June 29. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0105-remove-where-from-forin-loops.md

Reviews are an important part of the Swift evolution process. All reviews
should be sent to the swift-evolution mailing list at

        https://lists.swift.org/mailman/listinfo/swift-evolution

or, if you would like to keep your feedback private, directly to the
review manager.

What goes into a review?

The goal of the review process is to improve the proposal under review
through constructive criticism and contribute to the direction of Swift.
When writing your review, here are some questions you might want to answer
in your review:

        * What is your evaluation of the proposal?
        * Is the problem being addressed significant enough to warrant a
change to Swift?
        * Does this proposal fit well with the feel and direction of Swift?
        * If you have used other languages or libraries with a similar
feature, how do you feel that this proposal compares to those?
        * How much effort did you put into your review? A glance, a quick
reading, or an in-depth study?

More information about the Swift evolution process is available at

        https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

-Chris Lattner
Review Manager

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


(Vladimir) #13

  * What is your evaluation of the proposal?

-1. 'where' in 'for-in' loop is very handy and clear construction, it is similar to well-known 'WHERE' clause in SQL which acts the same way : it filters records, not returning just first found record.
'where'/'Where()' in LINQ in C# works the same way(filter),
'where' in Ruby on Rails "result of filtering the current relation according to the conditions in the arguments."

  * Is the problem being addressed significant enough to warrant a change to Swift?

No. The proposal removes very handy feature without strong reason for this and without suggesting good alternative (I think using of guard-continue is not a good alternative).

IMO to remove where in 'for-in' loop we need to suggest new construction to handy iterate sequences/collections with filtering and probably other handy features.
I probably could understand the proposal in case we (and core team) are planing such new construction (for example like LINQ in C#) and for this we need to remove 'where' in 'for-in'. But for this moment, I don't hear if there is such plans and when probably such construction could be implemented. (And in any case I don't think 'where' in 'for-in' will be any kind of stopper for new construction where 'where' will be also used).

  * Does this proposal fit well with the feel and direction of Swift?

I think no. I feel this like step back to C.

  * How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Read all the discussion thread and proposal, participated in discussions.


(Anton Zhilin) #14

I must note that this `where` does not belong to `case`.
Compare:

for case x? where x < 10 in y { ... }
for x in y where x < 10 { ... }

First syntax is standard and won't go away. Second syntax is for-in
specific, and is considered inconsistent.

* What is your evaluation of the proposal?

+1, because it removes piece of grammar that is unprecedented in other
languages and that few people use.

* Is the problem being addressed significant enough to warrant a
change to Swift?

Yes.

* Does this proposal fit well with the feel and direction of
Swift?

Yes, especially with Swift 3!

* If you have used other languages or libraries with a similar
feature, how do you feel that this proposal compares to those?

N/A

* How much effort did you put into your review? A glance, a
quick reading, or an in-depth study?

Followed the thread.


#15

Hello Swift community,

The review of "SE-0105: Removing Where Clauses from For-In Loops" begins now and runs through June 29. The proposal is available here:

   https://github.com/apple/swift-evolution/blob/master/proposals/0105-remove-where-from-forin-loops.md

   * What is your evaluation of the proposal?

+0.5

The 'where' is a nice sugar for people familiar with SQL but doesn't seem to hold its ground. Without 'where' nor 'guard', something like:

for element in collection where condition(element) { doSomething(element) }

is/could be

for element in collection { if condition(element) { doSomething(element) } }

Beside the extra curly brace there isn't much difference in the clarity of the message, rendering the sugar not as sweet as it sound.

Also the 'where' is not available to the other loop structure: 'while', 'repeat', 'do'. For these one have to rely on 'if' and 'guard'. "Forcing" the use of 'if' and 'guard' in all loop structure would provide uniformity.

The fix-it should probably used the nested 'for { if { } }' as its the syntax matching more closely what was written, at the cost of one ident level, and missing an opportunity to advertise a usage of 'guard'

   * Is the problem being addressed significant enough to warrant a change to Swift?

No, 'where' is not confusing; it's the 'while binding where' and the 'for .. In infiniteSequence where ..' which are.
Yes, 'where' (in 'for .. in') is pointless and if it did not currently exist would likely never be approved as an addition to the language due to its narrow field of operation.

   * Does this proposal fit well with the feel and direction of Swift?

'for .. in .. where'
Has a Swift like syntax
Is a sugar with limited scope which doesn't pull its weight, so is not Swift like

   * If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

Never used 'where' attached to directly to a loop.
Extensive use of SQL-like queries.

   * How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Closely followed the thread as I originally feared the disappearance of this nice construct. Tried and failed to understand how the syntax can be seen as confusing.

Dany

···

Le 23 juin 2016 à 00:12, Chris Lattner via swift-evolution <swift-evolution@swift.org> a écrit :


(Haravikk) #16

  * What is your evaluation of the proposal?

I'm against it. While I sympathise with some of the reasons behind it, I feel there are better solutions than removing this feature, and that at the very least doing so now would be premature as we have yet to see how removing where from conditionals will impact people's grasp of it on for loops. (currently confusion stems from the ambiguity compared to while where).

  * Is the problem being addressed significant enough to warrant a change to Swift?

I don't believe so; I think that the justification for removing the feature needs to be stronger than it is, and that other solutions may have better merit.

  * Does this proposal fit well with the feel and direction of Swift?

I feel not; personally I find where more Swift-y than using .filter() or if/guard continue, but this appears to be highly subjective.

  * How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Participated quite a bit in the discussion.

···

On 23 Jun 2016, at 05:12, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:


(plx) #17

-1 for the reasons already brought up.

I would also point out that half the biasing argument is extremely questionable: yes, for-in-where is “biased” in favor of “visit-if” and not "visit-unless”, but this form of “bias” is inevitable unless you start multiplying keywords (to have one for each “polarity”).

Note that, e.g., `guard` is also biased in a particular direction — we have `guard $conditionThatMustBeTrue` but not `unless $conditionThatShouldNotBeFalse` — and although this choice *does* make sense (due to let-binding being a success-case), it *is* otherwise backwards from traditional guard clauses (which were usually `if $exitCondition { $exit }`, which is the opposite polarity from how `guard` works).

So unless you want to have 2 of every control-flow keyword, whenever you have just one of each you just have to learn the “polarity" of each…this seems inevitable. Also note that even if you *did* go for 2-of-each, picking names that are sufficiently self-evident is harder than it looks, so in practice you’d almost certainly still have to wind up learning at least one of them, if not both.

Additionally, I would point `for-in-where` has some unique aspects that would complicate taking the “remove today to improve tomorrow” approach (as has been done with some other features like splatting).

Specifically, using for-in-where is a stylistic decision, and although translating its uses *to* `guard-continue` form can be done mechanically, translating `guard-continue` *back* to the (successor of) `for-in-where` in a stylistically-appropriate way seems much harder to mechanize…so if it was dropped for later, improved reinstatement, the temporary dropping might result in losing a lot of the original human stylistic choice, which IMHO is useful evidence of the original human intent.

···

On Jun 22, 2016, at 11:12 PM, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

Hello Swift community,

The review of "SE-0105: Removing Where Clauses from For-In Loops" begins now and runs through June 29. The proposal is available here:

  https://github.com/apple/swift-evolution/blob/master/proposals/0105-remove-where-from-forin-loops.md

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

  https://lists.swift.org/mailman/listinfo/swift-evolution

or, if you would like to keep your feedback private, directly to the review manager.

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and contribute to the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  * What is your evaluation of the proposal?
  * Is the problem being addressed significant enough to warrant a change to Swift?
  * Does this proposal fit well with the feel and direction of Swift?
  * If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  * How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at

  https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

-Chris Lattner
Review Manager

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


(Karl) #18

-1

I've followed this discussion since the beginning, and I feel the usage is clear given that for...in is a *data-driven* loop

I wouldn't mind renaming to "if" if there is some confusion, but I think we use "where" consistently in the language (and Dave Abrahams proposal for closure argument names takes this further), so could be argued that it's already clear.

Perhaps we should use "where" consistently for data-filtering operations, and possibly rename the generic constraint specifier. If we wanted to be really rigorously consistent.

Karl

···

Sent from my new Email (https://itunes.apple.com/app/apple-store/id922793622?pt=814382&mt=8&ct=my_new_email)

On Jun 23, 2016 at 6:12 AM, <Chris Lattner via swift-evolution (mailto:swift-evolution@swift.org)> wrote:

Hello Swift community,

The review of "SE-0105: Removing Where Clauses from For-In Loops" begins now and runs through June 29. (x-apple-data-detectors://1) The proposal is available here:

  https://github.com/apple/swift-evolution/blob/master/proposals/0105-remove-where-from-forin-loops.md (https://github.com/apple/swift-evolution/blob/master/proposals/0105-remove-where-from-forin-loops.mdReviews)

Reviews (https://github.com/apple/swift-evolution/blob/master/proposals/0105-remove-where-from-forin-loops.mdReviews) are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

  https://lists.swift.org/mailman/listinfo/swift-evolution (https://lists.swift.org/mailman/listinfo/swift-evolutionor)

or (https://lists.swift.org/mailman/listinfo/swift-evolutionor), if you would like to keep your feedback private, directly to the review manager.

What goes into a review?

The goal of the review process is to improve the proposal (x-apple-data-detectors://4) under review through constructive criticism and contribute to the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

* What is your evaluation of the proposal?
* Is the problem being addressed significant enough to warrant a change to Swift?
* Does this proposal fit well with the feel and direction of Swift?
* If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
* How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at

  https://github.com/apple/swift-evolution/blob/master/process.md (https://github.com/apple/swift-evolution/blob/master/process.mdThank)

Thank (https://github.com/apple/swift-evolution/blob/master/process.mdThank) you,

-Chris Lattner
Review Manager

_______________________________________________
swift-evolution mailing list (mailto:listswift-evolution@swift.orghttps)
swift-evolution@swift.org (mailto:listswift-evolution@swift.orghttps)
https (mailto:listswift-evolution@swift.orghttps)://lists.swift.org/mailman/listinfo/swift-evolution


(Erica Sadun) #19

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,
hard to discover (although I like others have taught it to promote its visibility),
elevates one style (continue if false) above others (continue if false, break if true, break if false), which are not expressible using similar shorthand,
introduces a fluent style that discourages design comments at the point of use,
can be difficult to breakpoint during debugging.

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.

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.

···

On Jun 23, 2016, at 7:42 AM, Ryan Lovelett via swift-evolution <swift-evolution@swift.org> wrote:
On Jun 23, 2016, at 9:07 AM, Tony Allevato via swift-evolution <swift-evolution@swift.org> wrote:

On Jun 23, 2016, at 3:02 AM, Jonathan Hull via swift-evolution <swift-evolution@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.

For any feature to be included, it should provide measurable benefits, fix a real problem, be named well, be discoverable, and provide non-trivial utility. I think "where", while convenient for a very narrow case of use, fails these tests.

-- Erica


(James Campbell) #20

-1 Where provides a nice clarity when distinguishing the clauses from the
optional binding

···

*___________________________________*

*James⎥Head of Trolls*

*james@supmenow.com <james@supmenow.com>⎥supmenow.com <http://supmenow.com>*

*Sup*

*Runway East *

*10 Finsbury Square*

*London*

* EC2A 1AF *

On 23 June 2016 at 16:59, Shawn Erickson via swift-evolution < swift-evolution@swift.org> wrote:

I am -0.5 on removing the where clause. I will note that removing it now -
given the appearing limited usage - shouldn't cause a large disruption to
most users. It may allow us time to think more about it and things related
to it since it can be added back at a later point without breaking swift 3
users.

I personally was bitten by misusing where with a for-in, I had the mental
model that it would abort the loop. To be honest I am not sure why I had
that mental model given long history with SQL where clause and using where
heavily in switch case statements (e.g. acts as a filter). I think for some
uses I had an assumption that the optimizer could prove that the where
would in fact always filter past a certain loop point and that may have
screwed up my mental model in the general case.

If you make such a mistake with where you may never know because from a
line debugging perspective your loop content never gets executed if the
where is violated yet you may still be looping (possibly causing
destructive consumption or a performance issue).

With that said I do find the syntax fairly clean and helpful when using
for-in (if not abused by chaining many together). I don't have a better
name for it, if it stays around I think it should stay named where to align
with where in other constructs in the language.

I do think for completeness we should consider adding 'until' for abort
looping case. We should also consider moving the location of the where (and
potential until) on the other side of 'in'.

One negative to this syntax (assuming not abused) is not being able to
probe things with a line based debugger. Of course many compact constructs
in the language are that way. ...maybe someday lldb and Xcode could allow
for statement scoped breakpoints

-Shawn

On Wed, Jun 22, 2016 at 9:12 PM Chris Lattner <clattner@apple.com> wrote:

Hello Swift community,

The review of "SE-0105: Removing Where Clauses from For-In Loops" begins
now and runs through June 29. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0105-remove-where-from-forin-loops.md

Reviews are an important part of the Swift evolution process. All reviews
should be sent to the swift-evolution mailing list at

        https://lists.swift.org/mailman/listinfo/swift-evolution

or, if you would like to keep your feedback private, directly to the
review manager.

What goes into a review?

The goal of the review process is to improve the proposal under review
through constructive criticism and contribute to the direction of Swift.
When writing your review, here are some questions you might want to answer
in your review:

        * What is your evaluation of the proposal?
        * Is the problem being addressed significant enough to warrant a
change to Swift?
        * Does this proposal fit well with the feel and direction of
Swift?
        * If you have used other languages or libraries with a similar
feature, how do you feel that this proposal compares to those?
        * How much effort did you put into your review? A glance, a quick
reading, or an in-depth study?

More information about the Swift evolution process is available at

        https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

-Chris Lattner
Review Manager

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

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