Damian Conway writes: > Luke Palmer started a discussion: > > > >I see this idiom a lot in code. You loop through some values on a > >condition, and do something only if the condition was never true. > >$is_ok is a control flow variable, something I like to minimize. Now, > >there are other ways to do this: > > > > if (0..6 ==> grep -> $t { abs(@new[$t] - @new[$t+1]) }) > > { ... } > > > >But one would say that's not the cleanest thing in the world. > > Only because you overdid the sugar. : > > if grep {abs(@new[$^t] - @new[$^t+1]) > 3} 0..6 > { ... } > > is pretty clean.
Right, but I messed it up, which isn't that important until later: unless grep {abs(@new[$^t] - @new[$^t+1]) > 3} 0..6 { ... } Yeah, it is cleaner (I really like to put the list up in the front seat, but in this case it doesn't help), but it's not really *clearer*, IMO. Still a bit too "poetic" to read easily, IMO. > But, in any case, handling exceptional cases are what exceptions are for: > > try { > for 0..6 -> $t { > die if abs(@new[$t] - @new[$t+1]) > 3; > } > CATCH { > push @moves: [$i, $j]; > } > } And that's exactly equivalent to: for 0..6 -> $t { if abs(@new[$t] - @new[$t+1]) > 3 { push @moves: [$i, $j]; last; } } Which also eliminates the control variable. My C<if>/C<unless> typo may have misled you, but the original example pushed only if *none* of them passed the condition. [snip] > So we might also write: > > for 0..6 -> $t { > last if abs(@new[$t] - @new[$t+1]) > 3; > } > < 7 and push @moves: [$i, $j]; Providing the semicolon rule doesn't bite us in the curly brace. Hmm, you inspired a fine ambiguity: if $something { ... } < 7 and $foo > if $something_else { ... } Maybe control structures shouldn't return values after all :-p (I honestly don't know what I have against that, other than fear that someone might actually use it) Luke