So... in general, "recursive" is more of an illustrative concept than
a good idea, which is why eliminating it tends to be so important.
(And, for some reason, many teaching exercises tend to neglect or
misrepresent this issue.)

And while eliminating recursive implementation automatically is
possible for some simple cases, those tend to be the cases where it's
easiest to restructure - these tend to be the good "training
exercises" which could help teach a budding programmer some of their
craft.

 That said, I could not help but notice that t3 and T3 fail when y has
length 0, 1 or 2. Here are rewrites to deal with this issue.

   r3=: >:`($:@,&0)`($:@}:)@.(3 *@- #)
   R3=: >:@(,&0 :. }:^:(3 *@- #))

(We do not have to support support non-numeric y in this example,
because you cannot add 1 to a literal or to a box. But we could
replace (,&0) with ((, {.)) and if the entire expression were
non-numeric that would be a good idea.)

That said, of course, in all cases x {. y will far outperform either
expression. And *that* more than anything else, is a good motive for
leaving things as they are.

I hope this makes sense? (And I hope this is not too discouraging?)

Getting back to your divisors problem, the limit case winds up looking
something like:

   (#~ 1&p:) i. 20
2 3 5 7 11 13 17 19

That said, I have not spent a lot of time exploring the "large primes"
algorithms. Perhaps others could offer suggestions for treating those
cases? (And it might be the case that the language should get one or
more primitives specifically based on the experiences of
mathematicians operating in that area, but of course such hypothetical
primitives should be shown to have some long-term, broad based
utility, also).

Thanks,

-- 
Raul



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