-----Original Message-----
From: [email protected]
[mailto:[email protected]] On Behalf Of Marshall
Lochbaum
Sent: Monday, February 11, 2013 12:01 PM
To: [email protected]
Subject: Re: [Jprogramming] Recursive programming (and scoping therein)

I assume the problems you're having are in getting num and divisors to work
inside the lambda clause. J can handle this fine--just use tacit code rather
than an explicit function for the lambda. Here is the same code in J.

remel =: ([ }.~ [: >: i.)"_ 0

allfactors =: af q:

af =: [ , 4 : 0 ^: (*@#@])
  x (% af&.>(;@:) y <@remel ]) ~.y
)

af uses a bit of refactoring to avoid having to write the case where y
(divisors) is empty explicitly. We know we want to tack x (num) to the
beginning of the list regardless of what happens in the function. Once we
have made this choice with the [ , at the beginning of af's definition, we
see that the rest of the function should just return an empty list if passed
an empty list for y. Therefore we add ^:(*@#@]) to af. This means the
explicit portion is only executed if y has nonzero length. Otherwise it will
do nothing, that is, return y which is the empty list we want.

The inside of the function is fairly straightforward. We compute the nub of
y to use as the right argument. Then y <@remel ] gives a boxed list of terms
(remel divisors x), and % with left argument x and right argument ~.y gives
the terms (/ num x). We apply af to them using af&.> to give a list of boxed
results and combine these into a single list with ; .

af can also be written in a completely tacit form, although in this form we
can't easily juggle the three terms num, divisors, and (unique divisors).
The easiest way out of this is just to compute the nub of divisors twice.

af =: [ , ((%~.) $:&.>(;@:) (<@remel ~.)@]) ^: (*@#@])

This verb uses $: for self-reference, but is largely the same as the other
form of af.

I realize that methods like these aren't really equivalent to proper scoping
rules, but I think most of the time they are good enough.

Marshall

On Mon, Feb 11, 2013 at 01:04:31PM +0000, Alex Giannakopoulos wrote:
> Are there any resources on recursive programming in J?  Couldn't find 
> much by searching.
> I would particularly like to know about scoping, and also so-called 
> free variables.
> 
> It seems to me that the enforced naming of variables as 'x' and 'y' 
> might cause problems in nested functions, necessitating awkward 
> renaming and copying.
> 
> I will give a little example here (my apologies to those unfamiliar 
> with
> Scheme.)
> I am trying to write a routine that will return ALL the factors of a 
> number, not just the prime ones.
> I do this by using an auxiliary routine that takes the number to 
> factor and a list of numbers still to combine.
> 
> ;; function (unique numlist) corresponds to J's ~.
> ;; function (remel alist elem) corresponds to J's   [ }.~ [: >: i.
> ;; function (primefactors n) corresponds to J's   q:
> 
> (define (allfactors n) (af n (primefators n))
> 
> (define (af num divisors)
>   (if (null? divisors) (list num)
>       (let ((uniquefactors (unique divisors)))
>            (flatten
>            (cons num
>                  (map (lambda(x) (af (/ num x) (remel divisors x)))
>                       uniquefactors))))))
> 
> Now I tried to express this in J, but can't even get to first base, 
> because of the scoping problems I mentioned.
> I realise that recursion is not the primary mode for programming J, 
> and a good solution may instead use something like running totals (\), 
> but for the time being I am stuck.
> Any suggestions gratefully received.
> ----------------------------------------------------------------------
> 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

Reply via email to