On 2016-06-10 11:39:34 +0000, Leonardo Pessoa via swift-evolution said:

I would vow to remove where clauses altogether. Most of the times I used it in ifs, fors and switches I ended up thinking it hardened readability of my code (perhaps because of placement, but I do not think alternatives made it more readable) and so it was my decision to stop using where whenever possible in my code. Since Erica's performance test pointed out using guard is nearly as fast as using where and the core team is removing wheres from ifs, I think the ones in fors could go next.

Interestingly, I find where clauses in `for` to be a useful tool to *improve* readibility. To me, it flows much better to write & read this:

   for (start, duration) in days where calendar.isDateInWeekend(start) {
       ...
   }

rather than this:

        for (start, duration) in days {
       guard calendar.isDateInWeekend(start) else { continue }
       ...
   }

or this:

        for (start, duration) in days.filter({ calendar.isDateInWeekend($0.0) 
}) {
                ...
        }

Of these three, I'd argue the first is the easiest to understand for a person who's never seen Swift code before. (Admittedly I doubt that's something languages should be optimized for, though.) The extra punctuation and the use of $0 instead of the loop's bindings makes the third approach seem especially noisy & scary.

Obviously, editorial tools like this aren't essential, and I could easily adapt to live without such syntactic sugar. But I do not like the idea of systematically ridding the language of such charming constructs when there is no technical reason to do so. SE-0099 fixed a technical problem with the syntax of a shorthand construct, without removing it from the language. It did not bring back Swift 1's `if` pyramids.



Moreover, Erica is absolutely right about `switch`: while `where` clauses are arguably non-essential in `for` loops, `switch` statements would lose a great deal of their expressive power without them. For example, in the following snippet (taken from a lexer in SwiftPM), all cases are logically at the same level. I think it's a win that Swift allows them to be expressed as such, and I'd strongly object to a proposal that removed this capability.

   switch c {
   case UInt8(ascii: "\n"): ...
   case UInt8(ascii: "#"): ...
   case let c where c.isSpace(): ...
   case UInt8(ascii: "\""): ...
   case let c where c.isNumberInitialChar(): ...
   case let c where c.isIdentifierChar(): ...
   case UInt8(ascii: ","): ...
   case UInt8(ascii: "="): ...
   case UInt8(ascii: "["): ...
   case UInt8(ascii: "]"): ...
   case UInt8(ascii: "."): ...
   default: ...
   }

Obviously, we could rewrite this to use a single `if` ladder, but I think most would not find that an improvement.

(The same argument applies to `catch` statements, although with less force.)

As long as `where` is kept in `switch` and `catch`, and as long the grammar is unambiguous, I think there is little point to removing where clauses from `for`. To improve consistency, I'd not mind if SE-0099 kept `where` as an alternative way to spell `,` in `if` statements, too.

--
Károly
@lorentey


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

Reply via email to