On Wed, Sep 16, 2009 at 03:28:47PM -0400, Minimiscience wrote: > I have a Perl 6 function currently written in the form: > > sub func($x) { > for @data -> $datum { > if condition($datum, $x) ff * { > # Do various things > } > } > # Do various other things > } > > I want the "various things" code to be run for the first element in > C<@data> for which C<condition($datum, $x)> returns true and for every > element in C<@data> after that (regardless of whether C<condition()> is > true, and ignoring the possibility of C<last>s) and for the state of > whether C<condition()> has returned true to be reset for each invocation > of C<func()>. I originally thought that the C<ff> operator with Whatever > as its right-hand operand (so that it never unflipped/flopped) would do > what I meant, but the documentation for Perl 5's C<..> in scalar context > (which S03 currently defers to) seems to imply that C<ff>'s state is > maintained across function invocations. Rakudo doesn't seem to have > implemented C<ff> yet, so I can't test it, but if the state is indeed > maintained across calls in Perl 6, how should I write C<func()> instead? > The best way I can think of is the very C-like practice of creating a > variable to store whether C<condition($datum, $x)> has returned true yet > and updating it each iteration until true is returned, but it seems like > Perl 6 should have a better way.
The theory here is that the C<ff> state is based on an implicit C<state> variable declared in the same scope, and therefore would have the same lifetime as that state variable. A state variable is not like a C static, insofar as you get a new state variable when the closure is cloned. In this case. the call to the C<for> loop should be treating the block as an argument to the implementation of the loop, and should therefore clone a new closure containing the C<ff>, so it ought to reset the implicit state variable on every reinitialization of the whole loop (but not on each loop iteration). So I think in theory it should do what you want. (However, I can well imagine an implementation botching the cloning of the loop body by assuming it's static and not cloning it. That would not be Perl 6, since in Perl 6 every block is assumed to be a closure, and C<for> is assumed to work just like C<map>, which will certainly clone its closure.) Larry