I'm seeking a stylish workaround to the a constraint on applications of ^:_ .
The idiom ^:_ is well designed and well documented. It is one of the most useful tools in the J kit and has broad applicability. However, there are some cases where it's almost, but not quite, applicable. Consider the form f^:g^:_ where g is a conditional which determines if f is to be applied (again). Of course if g returns 0, then f isn't applied, and f^:g becomes an identity function, which means its output will match its input, and ^:_ will terminate. So usually ^:g^:_ acts as a while loop, independent of the operation of f, terminating iff g is 0. But now consider an f that is not one-to-one. That is, an f where two or more distinct inputs may produce identical outputs. Using this f in f^:g^:_ becomes problematic. If f receives two inputs in a row which map to the same output, then the loop will terminate early (that is, even if g is 1). Here's a recent example. I'm trying to code the "evoluationary algorithm" from RC http://rosettacode.org/wiki/Evolutionary_algorithm . The code I have so far reads [1]: CHARS =: ' ABCDEFGHIJKLMNOPQRSTUVWXYZ' randomize =: fivePct`mutation} fivePct =: 0.05 >: $ ?...@$ 0: mutation =: (UCALPHA,' ')&(] ,: [ {~ $...@] ?...@$ #...@[) score =: +/@:~:"1 copy100 =: 100 $ ,: done =: 1 - -: initial =: CHARS ([ {~ ?...@$&#~ ) [ f =: ([ (] {~ (i. <./)@:score) randomize@:copy100@:]) (f^:done^:_: initial) 'METHINKS IT IS LIKE A WEASEL' The problem I'm hitting is that f here isn't deterministic. It takes a "parent", generates a random population, and selects the fittest member of that population -- which could legitimately be the original parent. Hence input and output are identical and f^:done^:_: terminates "early". What is I want is for f^:done^:_: to terminate iff done is true (that is, 'METHINKS IT IS LIKE A WEASEL' -: y ). Now, I understand that ^:_ is doing the right thing. I just want it to do a slightly different thing, and I'm asking for elegant ways to achieve that. I know I've hit this wall before. Has anyone else? Can you suggest a stylish workaround? One method I'm considering is artificially (but reversibly) changing the output of f at every iteration, as in defining f_new =: -.&.>@:{. ,&< f (that is, concatenating a boolean and negating it every iteration). -Dan [1] Bear in mind this code is still in development, and may suffer from problems other than the one in question. ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm
