I understand the points made by Roger and Pascal on this topic, but I
think they are at cross purposes.
It is said that you can write in Fortran in any language. I don't
think the same is true of Lisp, and there's a reason for it.
A Fortran program uses static arrays and explicit looping. Not only
do most languages provide explicit syntactic support for this, there
is also hardware support for index calculations.
Lisp is a little different: its data structures are naturally
recursive, and it can do a head,rest split without new memory
allocation. While there may not be direct hardware support for tail
recursion, there are well-known techniques that enable one to do this
without changing the stack size.
J is also different. The most natural operation is applying a verb
independently to argument cells. While this is a divide and conquer
technique, it is not naturally recursive. It does take care of the
easy parallelizable case of iteration. The scan adverbs deal with
other important cases.
Here's how I think of it.
Language Natural Data Structure Natural Operation
Fortran array a get or set a[i]
List list tail recursion
J array y f y, scan
In general, you have got to use operations that are somewhat natural
for the language at hand, or you'll be sorry. An extreme case occurs
with stack languages like PostScript: while you can declare variables,
you have to learn to "trust the stack", and keep track of the runtime
state yourself. That's why most PostScript programs are written by
other programs, not programmers.
I am not convinced that recursion is a natural operation in J.
Obviously it works fine for simple examples. With tail recursion, you
build up the stack, but that's often not a big deal. However, if you
try to emulate Lisp using {.,&<}. rather than using scan adverbs, you
spend a lot of time copying parts of the argument. Lisp does not have
this overhead.
A rude awakening comes to most J programmers who use primitives at
small rank on large amounts of data and then try the same thing with
user-defined verbs: the program grinds to a halt. The difference is
that the former frequently have integrated rank support while the
latter do not, and there is a significant cost whenever a verb is
started up. I suspect this start-up cost is the killer when you try
fine-grained recursion in J.
I have found the type of technique described in the "Extracting
Variable-Length Fields" section of Henry's book very useful. In most
of the instructional materials on J, the power operator does not get
its due. I believe that many of the search problems on Project Euler
which are solved through recursive depth-first search in conventional
languages are better solved through breadth-first iteration in J. For
those of you who have access to the forum, a good example is st's [Sam
Tardieu's] (near-) solution to Problem #122.
Best wishes,
John
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm