Dan, it seems you have put much experimentation and thought into this subject. What do you make of this:
$:@:>: :: ] 0 6666 foo=. 3 : 'foo :: ] >:y' foo 0 9999 On Wed, Jan 26, 2011 at 4:00 PM, Dan Bron <[email protected]> wrote: >> Thanks, Dan. An example showing what *doesn't* work and explaining why >> not is a huge aid to understanding it. > > The simplest and most illustrative example of what doesn't work is: > > $: 0 > |stack error > | $:0 > > That is, in this case, $: refers only to itself, and so would recurse > forever, only J won't let you do that. This finite recursion is in contrast > to your standard infinite loop, which J is happy to let you construct & > execute. Now, of course, certain infinite loops will hit the physical > machine's limits (e.g. out of memory, precision of numeric values, etc) and > then J will halt. But generally speaking these values are large enough so > that either you don't have to worry about them, or when you do you can > generally anticipate & work around the limits (e.g. reading in a 4GB file in > chunks). > > In contrast, the limit of recursion is finite and *small*: > > $:@:>: :: ] 0 NB. Increment & recurse until stack error; > report maximum stack depth > 6666 > > and it is not imposed by your physical hardware, but by the compiler options > used when your J binary was generated. Essentially, you're hitting *C's* > stack depth. Now, of course, many $: problems are logarithmic > (divide-and-conquer) and 2^6666x is a large number (and it gets better if > you can make more decisions at each branch). So in many cases this depth > may be sufficient. But I've hit cases where it isn't, and this constraint > forced me to change my statement of the problem to be solved (i.e. J code), > generally for the worse (additional complexity & maintenance). And often > enough, at least in the early days of my J career, that now I'm wary of $: > altogether. Since those days Roger has addressed this issue to a > considerable extent, but it still occasionally bites (e.g. search [1] for $: > ). > > Of course, the obvious response is that programming is defined by the > tension between "saying what you want" (expressing the problem "naturally") > and working with the resources you have (e.g. available stack). And that > sometimes you have to compromise, as when I rewrite a $: verb to be a ^: > verb, or a hybrid. My take on that is: > > 1. The stack limit feels very artificial, and the field has a > number of well studied methods to avoid it (e.g. skip C's stack and use the > heap). > 2. Sometimes you can predict when $: is risky, but often you can't. > > > In light of (2), one oftens ends up rewriting $: as ^: or something > prophylactically; so why not just write it that way in the first place? > (And this tends to drive a feedback cycle where your expertise with $: > wanes, and as a consequence you're less comfortable with it, so you reach > for it less often .... ) > >> foo=: 3 : 0 >> 0 $: y >> : >> ... >> ) > > Nope, that won't work. Think of $: referring to the line it's in at the > very most (which line can be inside a explicit definition, e.g. foo could > call Fibonacci or Factorial). In fact, that's how it's implemented [2]. > You can use 0&$: : foo instead. Or something sillier: > > > (N=:'foo')=: 3 : 0 > 0 N~ y > : > ... > ) > > -Dan > > > [1] Outstanding bug list in J: > http://www.jsoftware.com/jwiki/System/Interpreter/Bugs > Search for $: . Not all bugs are related to stack size. > > [2] Implementation of $: : > http://www.jsoftware.com/pipermail/general/2006-May/027079.html > > [3] Interesting note on the value of $: : > http://www.jsoftware.com/pipermail/general/2006-May/027090.html > > > > ---------------------------------------------------------------------- > For information about J forums see http://www.jsoftware.com/forums.htm > ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm
