From: andrew@rentec.com (Andrew Mullhaupt)
Newsgroups: comp.lang.apl
Subject: Re: SIGNUM of teaching numerical methods
Date: 22 Jul 92 01:28:46 GMT
Organization: Renaissance Technologies Corp., Setauket, NY.

In article <ROCKWELL.92Jul21093324@socrates.umd.edu> rockwell@socrates.umd.edu (Raul Deluth Miller-Rockwell) writes:
>Andrew Mullhaupt:
>   You may ask - why not use reference counts like real human beings?
>   Because the 'language standard' is construed as 'the interpreter
>   must _copy_ the function arguments to localize them' as opposed to
>   'the interpreter can guarantee the locality of function arguments
>   by whatever effective means it chooses.' The reason for this seems
>   to be some kind of extra safety or something but it's too galling
>   to think about clearly.
>
>This sounds like what happens when you confuse the language with the
>implementation.  But, if I may submit, the "real answer" is more
>likely that no one has dealt with the aspect where each of the
>sub-arrays needs an array header, so they're falling back to a simple
>mechanism [extraction of sub-array] which is guaranteed to give them
>the array header -- which their implementation of cumsum is going to
>expect.
>

No. S has more complicated data types than anyone might comfortably imagine.
They just recently added "objects"... (It's a kitchen sink language...)

You will find that the semantics of the language _demand_ copying in the
guise of 'evaluation' - see Chapter 11 of Becker, Chamber and Wilks _The
New S Language_. I quote:

	"This section describes a model for the S evaluator, in the form of 
	an S function, Eval, which uses the same rules as the actual S
	evaluator (written in C)."

In the rather convoluted explication which follows, it can be seen that the
specification requires that function arguments are evaluated _in the current
frame_ and that this ultimately necessitates copying them.

	"With either default or actual arguments, the _evaluated argument_ is
	inserted as the first element in the current frame..."

The only good news is that if you do not _use_ all the function arguments,
unused arguments will not be evaluated (copied), and the evaluator only
evaluates arguments _once_ since it cannot change them.

Remember that this is Bell Labs - the same people who tried to define UNIX
System V as whatever behavior obtains on a 3b2. (I.e. using a reference
machine as a specification.) So you might argue that the specification, 
given in the form of an implementation, is confused with implementation.
But this doesn't help us overcome the bad result.

>As I understand it, the most recent implementation of J is similar in
>this regard.

Ouch.

>Well, again, if you compile at the global level this goes away.  What
>I mean is, if you've got a function f which depends on g, and function
>g depends on h, then you include in f the code for g and h.  Note that
>this does make your compilation a bit more expensive, and
>reassignments to g and h blow away your compiled code -- if this gets
>to be painful you can add something to the language to isolate such
>functions. 

Yes. Or even be so crude as to give the programmer a pragma. I'm a big fan
of letting the programmer help the processor out with the tough ones.

And it provides one more reason why you need to blow off the copy-required
semantics; they won't let you inline your functions like this.
>code which is using it.  Also note that for calls to functions which
>are themselves recursive you're going to have to compile that
>recursive function twice [once for the initial entry point, again for
>the recursive case -- which is analogous to, but not the same as, the
>base case and recursive case used in defining the function].

It can be worse than that. You can have a function which has more than
two entry points resulting from a recursive definition. I think that using
a cache for old stack frames can go a long way toward speeding up some
of the more offensive recursions, but I bet we can come up with a recursive
function bad enough to make us give up. Note that frame caching can yield
dramatic speedup for a large class of recursion-bound functions.

>Having never seen 'a', and having no way to access it, I really can't
>agree or disagree on this one.  Keeping a language secret does have a
>certain advantage -- no one else is going to use it.  But, it does
>have a disadvantage -- no one else is going to use it.  You makes your
>choices...

'a' is not a secret, otherwise I couldn't have told you about it. There are
papers in the APL literature by Whitney and some others explaining it. You
just can't have it. You _are_ allowed to know about it...

>  I think that's about as close as I've gotten to taking a
>look at where APL is going at Morgan Stanley -- which is to say, not
>close at all.

While I was there, IBM had made the announcement that Morgan Stanley was the
world's biggest APL shop. If you count 'a', it probably still is. There are
many parts to Morgan Stanley, and some of them are not even allowed to
talk to each other about anything, so it isn't surprising if you worked there
but never heard about 'a'.

Later,
Andrew Mullhaupt
Newsgroups: comp.lang.apl