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


(Denis Nikitenko) #1

* What is your evaluation of the proposal?
  
-1. The proposal suggest removing a useful feature. The arguments presented in the proposal do not warrant introducing another breaking change into the language.

I found the "where" clause in for-in loops to be clean and elegant. It does what for-loops do best - concentrate the control logic of the loop at the top of the loop. Being able to understand as much as possible about the control flow of the loop from a single line of code - the loop "header" - is a big advantage of for-loops over while-loops.

I have always treated all "jump" instructions - continue, break, and goto - as tools of last resort, especially in loops. When teaching introductory computer science courses, I find that beginners either don't "get" break/continue statements for a while, or start abusing them and turn them into a "code smell", scattering control flow logic all over the body of a multi-page loop. This results in the code that both beginners and non-beginners find difficult to read, debug, and refactor.
  
* Is the problem being addressed significant enough to warrant a change to Swift?
  
I do not think so.

Lack of use is not a strong reason to remove a feature from a language that is about to reach version 3.0, and is currently being used to write commercial applications. The feedback from the discussion list indicates that many Swift users who are aware of the “where" clause in for-in loops like using it.

Inconsistency in the use of “where" in while- and for-loops was a valid concern, but acceptance of propsal SE-0099 fixed this issue.

Guard/if conditions are an alternative that incurs no performance cost, but I find them to be an inferior alternative from the readability/refactoring point of view. For-in loops in Swift - and other C-family languages - are usually aimed at iterating through a complete sequence or collection. Additional "shortcuts" (continue) and "off-ramps" (break), do not really fit into this model and make for less readable code - although they are sometimes necessary. The “where" clause provides a clean way to pre-filter a collection, alleviating the need for most uses of “continue”. To me, this seems like a desirable feature and not a bug.

Lasily filtering of a collection is another alternative. However, as numerous tests posted on this list have demonstrated, it comes with a performance cost. Furthermore, use of lazy filtering assumes familiarity with both higher order functions and lazy evaluation, which are not topics with which beginner programmers - or even many non-beginners - are familiar. As a side note, this operformance cost forced me to refactor several map/filter instances into for-loops in my own code.

Finally, I would like to echo the “breakage fatigue” sentiment. I realize that we have a small window of opportunity to introduce breaking changes before Swift 3 is released. However, at this stage in Swift's existence and acceptance, every source-breaking change should have an even stronger rationale than an additive change. After all, additive changes pose on danger of driving developers and educators away from a language, while source-breaking ones most definitely do.

* Does this proposal fit well with the feel and direction of Swift?
  
Not at all. The where keyword in for-loops always felt very "Swifty". To me, removing it is a step backwards - akin to replacing a while-loop with an if/goto combination.

* 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 several C-family languages with “regular” for-in loops. My most recent experience is with Java. After the rich for-in loops in Swift, Java for-in loops felt very restrictive and clunky. The “where” clause in Swift definitely adds to the flexibility of its for-in loop.
  
* How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
  
I have been following the discussion for quite a while and have given it a lot of thought.