J's architecture is not set up for tail call elimination and it would be
very difficult to implement.
I would just use an explicit while loop for functions that need to do
something random until a condition is met. It's not very natural to use
(?) to determine control flow in a tacit function anyway. If you really
needed to do it tacitly, you could add a counter to the argument and
increment it at each step.
Marshall
On Sat, Mar 19, 2016 at 01:48:36PM +0100, Louis de Forcrand wrote:
> 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