For your divisors problem, I imagine that you just need to make the divisor itself a part of the result.
If it's not a part of the result, then the termination should not matter (because you will start another pass with a different divisor). Thanks, -- Raul On Sat, Mar 19, 2016 at 1:47 PM, Louis de Forcrand <[email protected]> wrote: > On OSX I get a stack error with and without parentheses > around vr for recursive2. Which is completely logical, > as there is no base return value so that the recursion may > stop; $:@v0 means that you're going to apply v0@v0@v0… > forever. $: represents the largest tacit verb containing it, but > that doesn't extend beyond the proverb that contains it. > If you try f. on the verb "recursive2", you'll find that vr will > be rewritten as an ambivalent explicit verb, so that $: stays > contained within vr. > > Thanks for your answer Raul, but what I was really looking > for was a way to avoid the tail recursion. The problem is > that u^:v^:_ y terminates either when 0 = v y OR when > y -: u y . The only way I see to get around this is tail recursion, > or as Marshall said, explicit looping. While I find that the ^: > conjunction works in a more logical way than the power > operator in APL, this is one case where the power operator > obviously comes out ahead: (u⍣v) y terminates when 1 = v y . > > About the divisors problem, if you input a list of primes to the > "recursive" or "power" verbs, the list will indeed be unchanged. > In any case, those verbs were simply the first I could think of. > I know all the verbs in my first post were extremely slow, but > I thought they were good at demonstrating the tail recursion > I'm trying to eliminate. > > Thanks again, > Louis > >> On 19 Mar 2016, at 16:52, Henry Rich <[email protected]> wrote: >> >> I am pretty sure the parentheses are simply deleted during parsing, and that >> what you are seeing is an elusive stack-related crash in recursion that has >> been around for a while. >> >> >> vr =: ($:@v0) >> >> vr2=:$:@v0 >> >> 'vr' -:&(5!:5@<) 'vr2' >> >> 1 >> >> vr >> >> $:@v0 >> >> vr2 >> >> $:@v0 >> >> Henry Rich >> >> >> On 3/19/2016 9:54 AM, Pascal Jasmin wrote: >>> to make a slightly off topic reply, this will crash J (win 64) (using the >>> definitions in replied post) >>> >>> >>> vr =: ($:@v0) >>> recursive2=: vr`[email protected] >>> >>> 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 <[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 >> >> ---------------------------------------------------------------------- >> For information about J forums see http://www.jsoftware.com/forums.htm > > ---------------------------------------------------------------------- > For information about J forums see http://www.jsoftware.com/forums.htm ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm
