There is a non recursive solution to your example problem which distracts from addressing the ^: transformation part
(-. 0 -.~ ~.@:,@:(}:@divisors"0)) i.20 0 10 11 12 13 14 15 16 17 18 19 Your question is good. I've explored similar thoughts. I have several tools/tricks which could be improved and more "genericised", but they are still tricks used in distinct circumstances. as you pointed out, for simple recursion, there is often your first equivalence. ----- Original Message ----- From: Louis de Forcrand <[email protected]> To: [email protected] Sent: Saturday, March 19, 2016 8:48 AM Subject: [Jprogramming] Tail recursion Let t3 be a recursive verb equivalent to >:@(3&{.) : t3=: $:@}:`>:@.(3 = #) (>:@(3&{.) -: t3) i.1e3 1 (>:@(3&{.) -: t3) i.1e4 |stack error: t3 | (>:@(3&{.)-:t3)i.10000 T3=: >:@(}:^:(-.@(3 = #))^:_) (>:@(3&{.) -: T3) i.1e3 1 (>:@(3&{.) -: T3) i.1e4 1 Most of the time (and this is the point of this post), $:@v0`[email protected] <—> v1@(v0^:(-.@v2)^:_) The one possible exception is if v1 returns 1 BUT v0 is equivalent to ] (for that particular iteration). Then the version using ^: stops, while the recursive version doesn't. However, the problem with the recursive version is the stack of course. This problem could be fixed if special code existed to convert the recursive version to an internal loop. I believe most Scheme interpreters are required to do this, and it's called tail recursion. In the meantime, is there a better way to write this type of verb (tacitly)? Say, for example, that I'm trying to successively remove divisors of each number in a list (except the number itself), removing them in a random order. In the end I should be left with all the numbers which have no multiples of themselves in the list (right?). Problems arise however if the number in question is prime; the list won't be modified that iteration, and so the ^: version would stop there. Is there another (relatively simple) way to do this tacitly? For example: divisors=: (] #~ 0 = |~) >:@i. v0=: -. }:@divisors@({~ ?@#) v1=: ] v2=: -.@(+./)@e. ;@:(<@}:@divisors"0) recursive=: $:@v0`[email protected] power=: v1@(v0^:(-.@v2)^:_) recursive i.20 0 10 11 12 13 14 15 16 17 18 19 power i.20 0 4 5 6 8 9 10 11 12 13 14 15 16 17 18 19 Obviously power stops prematurely. Note that this is an extremely inefficient way to do this and is only for demonstration purposes. Thanks, Louis ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm
