Pascal wrote:
>  Your goals seem to have been to make a pretty calling convention 

To be honest with you, I can no longer remember what goals I had in mind
when I wrote that code, or even if I had meaningful goals at all.  I have
a vague recollection of a newcomer to the Forums who (having a background
primarily in mainstream languages) intimated that not only were J's
calling conventions primitive (rather than spare), but that they were so
because the language itself was insufficiently powerful to express more
structured function signatures.  

I'm fairly protective of our little language, so if I'm not imagining the
whole episode, I can see that kind of implication getting my back up, and
creating the utility to demonstrate that J certainly can express such
ideas, and that it doesn't simply because it approaches problems in a
different way. In other words, that infrequent use of named parameters
doesn't arise from a lack of power, but a lack of desire (I mean, it's not
like Ken hadn't seen Pascal or Ada or C, and their calling conventions,
before he rebuilt APL as J).

>  leverage J's existing multi-assign facilities which is what my approach 
> does, 
>  with the convention that a passed null parameter is to be replaced with 
> defaults

Well, multi-assignment is how the defineAndDefaultParams conjunction works
(that's the ({."1 params) =. {:"1 params part), and as the name implies,
if the user doesn't supply a particular parameter, it is defaulted [1]. 
In addition to the named parameters, an additional set of names is defind:
<parameter>_is_default (e.g. max_is_default), which are set to 0 if the
user specified the parameter, and 1 if he didn't. This is intended as a
convenience for the verb writer; to allow him to distinguish the cases
where the user did not specify a parameter, and where he did, but the
value he specified happened be identical to the author's default (not all
parameters have sensible defaults, so whether a parameter is truly missing
might be useful information). 

The derived verb can be called with named parameters (i.e. a rank-2 table
of name;value pairs) or with simply ordered values (i.e. a rank-1 vector
of values in the same order the parameters are declared); in either case,
"missing" values are defaulted (and the appropriate <param>_is_default
values set to 1). Combined with the sneaky strand-notation script (added
years later), this allows us to emulate the calling conventions most
commonly used in other languages (in particular, foo['file.txt',42,'blue']
in the latter case, and foo[filename='file.txt',max=42,color='blue'] in
the former).*

>  Anyways, I came up with another J implementation of something else in your 
> file 
>  that has been a topic on the forums: Lexical closures.

Like strand notation permitting optional parameters, the earlier extension
to lexical closures was both a lark and really only useful for
demonstrating J's ability to emulate features of other languages. In
particular, combining the named-parameter notation with lexical closures
permits us to declare "static" variables, which retain their value across
invocations.  Again, not something J is "missing", but rather something
which cuts against the grain of the language (or is at least irrelevant to
the way I practice it).

So my implementation of lexical closures was intentionally silly and
cutesy. Fundamentally it's predicated on memory-mapping local variables,
which means they retain their state. I'd urge you (and everyone) to avoid
doing that. I intended it to be a joke, but more than one person has
tripped up over it when searching for "lexical closures" as it relates to
J programming (especially since Paul Graham, who has some influence,
declared the availability of lexical closures a litmus test for a
"powerful" programming language).  

Anyway, because of that, we created a FAQ entry for lexical closures on the
J wiki [1], which (whether or not LCs are useful in J) provides a reliable
implementation, that is similar in spirit to your approach (except it uses
anonymous locales to encapsulate all state, as opposed to redefining the
function, as you do [2]).

-Dan
 
[1]  FAQ on lexical closures in J, using anonymous (numbered) locales.
     http://www.jsoftware.com/jwiki/Guides/Lexical%20Closure#Solutions

[2]  Your approach of redefining f is neat, though rather than using n~ ::
] y to 
     extract the previous value (which won't work in 100% of cases), you
might 
     consider  (< ('';1;0) {:: 5!:1 <n) 5!:0  or something like it.

*    Actually, the details of the strand-notation script might interest
you: it's
     related to your most recent thread about adverbial conjunctions taking
both
     their arguments on the left. Strand notation is nothing more than a 
     recursively-defined operator which takes any number of arguments on
the left.

----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to