[Jprogramming] Tail recursion (bug hijack)

Pascal Jasmin godspiral2000 at yahoo.ca
Sat Mar 19 13:54:28 UTC 2016


to make a slightly off topic reply, this will crash J (win 64) (using the definitions in replied post)


vr =: ($:@v0)
recursive2=: vr`v1 at .v2

recursive i.20

I can accept that I am using $: wrong, but if vr is defined as what appears to be equivalent:

vr =: $:@v0

then recursive2 -: recursive (no crash)

Is there a special meaning to the parenthesized version that could be done intentionally in some contexts?





----- Original Message -----
From: Louis de Forcrand <olius at bluewin.ch>
To: programming at jsoftware.com
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`v1 at .v2 <—> v1@(v0^:(-. at 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`v1 at .v2
   power=: v1@(v0^:(-. at 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


More information about the Programming mailing list