> On Jun 8, 2016, at 10:51 PM, Erica Sadun via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> 
>>> On Jun 8, 2016, at 9:36 PM, Brent Royal-Gordon <br...@architechies.com> 
>>> wrote:
>>> 
>>> Upon accepting SE-0099, the core team is removing `where` clauses from 
>>> condition clauses, writing "the 'where' keyword can be retired from its 
>>> purpose as a boolean condition introducer." 
>>> 
>>> Inspiried by Xiaodi Wu, I now propose removing `where` clauses from `for 
>>> in` loops, where they are better expressed (and read) as guard conditions.
>> 
>> Do you propose to remove `for case` as well? That can equally be handled by 
>> a `guard case` in the loop body.
>> 
>> Alternate proposal: Move `where` clauses to be adjacent to the 
>> pattern—rather than the sequence expression—in a `for` loop, just as they 
>> are in these other syntaxes.
>> 
>>      for n where n.isOdd in 1...1_000 { … }
>> 
>> This makes them more consistent with the syntax in `switch` cases and 
>> `catch` statements, while also IMHO clarifying the role of the `where` 
>> clause as a filter on the elements seen by the loop.
> 
> I saw your post on that *after* I finished sending this. Moving `where` next 
> to the pattern, like you'd find in `catch` and switch `case`, the code would 
> look like this:
> 
> for i where i % 2 == 0 in sequence {
>     // do stuff
> }

This is the best version yet - the placement of 'where' makes total sense and I 
really like it there.


> I agree that's really clever and an improvement but after coming up with all 
> the points about wrong expectations about termination vs filtering, the 
> better use of guard, and fetishes about vertical compactness, I think (call 
> it +0.6) I'm going to stick to my guns on this one - and for `for case` too. 
> I've been wuxxed.
> 
> * New users might expect the sequence to terminate as soon as i % 2 is 1, 
> rather than the correct interpretation which is "this is a filtering 
> operation"
> * The code can be expressed less ambiguously as 
> 
> for i in sequence.filter({ return i % 2 == 0 }) {
>     // do stuff
> }

This seems to trade what was a very declarative syntax about the intent of some 
code (especially with 'where' in the middle of the statement) for one that 
injects its own specialized vocabulary into the context (knowing what filter 
does, a function call, a closure with a return keyword and a pair of extra 
braces and parenthesis!) which means, to me anyway, significant cognitive 
overhead. It will also be a lot slower without optimization enabled due to the 
intermediate array. (I've found *significant* speed ups switching .forEach() 
with for loops in debug builds, for example.)


> * The while version can be expressed as
> 
> for i in sequence.prefix(while: { return $0 % 2 == 0 } ) {
>     // do stuff
> }

And now we've gone from, again, what is likely a very simple and declarative 
style using a for/while kind of statement and turned it in to something that 
has *even more* cognitive overhead to figure out what it does because now I 
have to reason about what "prefix" means here (normally I only think of prefix 
in the context of strings) and if there's a special variation of it using the 
"while" argument that I need to also be aware of...

Maybe it's just me, but.. I don't get it. I want to be able to quickly 
understand a piece of code's intent, not wade through fancy constructions for 
their own sake.

l8r
Sean - who might be too tired to be emailing responsibly 

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

Reply via email to