> On Jun 9, 2016, at 6:54 PM, Jordan Rose <[email protected]> wrote:
> 
> 
>> On Jun 8, 2016, at 22:19, Charlie Monroe via swift-evolution 
>> <[email protected] <mailto:[email protected]>> wrote:
>> 
>>> 
>>> On Jun 9, 2016, at 5:51 AM, Erica Sadun via swift-evolution 
>>> <[email protected] <mailto:[email protected]>> wrote:
>>> 
>>> 
>>>> On Jun 8, 2016, at 9:36 PM, Brent Royal-Gordon <[email protected] 
>>>> <mailto:[email protected]>> 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
>>> }
>>> 
>>> 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
>>> }
>> 
>> It's important to keep in mind that .filter without using .lazy copies the 
>> array. So you need to keep using sequence.lazy.filter({ return i %2 == 0 }), 
>> unless you're OK with giving up some performance, which a) adds boilerplate, 
>> b) not many people will remember to do.
>> 
>> I've taken the time to run a test, going through milion numbers (several 
>> times) using:
>> 
>> for i in arr { if i % 2 == 0 { continue } }
>> for i in arr where i % 2 == 0 { }
>> for i in arr.filter({ $0 % 2 == 0 }) { }
>> for i in arr.lazy.filter({ $0 % 2 == 0 }) { }
>> 
>> Results:
>> 
>> - plain for loop with if-continue: 27.19 seconds (+1.76%)
>> - with where: 26.72 seconds (+0.00%)
>> - .filter: 44.73 seconds (+67.40%)
>> - .lazy.filter: 31.66 seconds (+18.48%)
>> 
>> Yes, 100 milion numbers is an extreme, but it demonstrates that any of the 
>> suggested expressions will be slower, mainly if the caller doesn't use .lazy 
>> (67% !!!). The only comparable solution is adding additional lines of code 
>> into the body of the for loop by adding an if statement.
> 
> Just to double-check, was this with optimizations on? Because -Onone numbers 
> aren’t nearly as motivating, but I would expect -O to remove the loop 
> entirely in the simple case.
> 
> Jordan
> 

See my latest post - included results with -Ofast. But still, using filter and 
lazy.filter is 10+% slower, which were the suggested alternatives to `where`.


_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to