The difficult problem is to convert any arbitrary recursive verb to a
tail-recursive form automatically.  If a recursive verb is already in
tail-recursive form it is better to support that form directly.  The Jx
interpreter does this via the tail recursion optimization adverb (O.) :

   NB. Jx Interpreter

   t3=: ( $:@}:`>:@.(3 = #) )O.  NB. Optimized

   T3=: >:@(}:^:(-.@(3 = #))^:_)

   (t3 -: T3) i.1e5
1


   stp=. ([ ((<;._1 '|Sentence|Space|Time|Space * Time') , (, */&.:>@:(1
2&{))@:(] ; 7!:2@:] ; 6!:2)&>) (10{a.) -.&a:@:(<;._2@,~) ]) ".@:('0 : 0'"_)

   stp 1
  T3 i.1e5
  t3 i.1e5
)
┌──────────┬────────┬──────────┬────────────┐
│Sentence  │Space   │Time      │Space * Time│
├──────────┼────────┼──────────┼────────────┤
│  T3 i.1e5│13635072│11.9597666│163072279   │
├──────────┼────────┼──────────┼────────────┤
│  t3 i.1e5│3148288 │10.4366911│32857709.5  │
└──────────┴────────┴──────────┴────────────┘



On Sat, Mar 19, 2016 at 8:48 AM, Louis de Forcrand <[email protected]> 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

Reply via email to