>I can't help feeling that there has to be a better way, but since you>can't know at compile time what the parameter names _are_, I don't>know what that better way might be.

>[How about this: at compile time, make up an array of pointers with an>entry for each {caller, callee, arguments} triple used in a module,>e.g. "foo calls bar using zip, zorp, and two positionals", and make>the calls go through that array.

There are no modules.

This is an *interactive* language with some functions coming from a
file, some functions being typed in, some functions being saved out to
a file, edited and reloaded, &c &c. Functions don't have names. (A
variable may be be bound to a function, but the function doesn't know
that.) In particular, functions may be _parameters_. I don't quite
see how the moderator's approach handles something like

The details are slightly off (in one case intentionally) but you
really truly can do this awful thing! Don't blame _me_, it wasn't
_my_ idea. I may be able to talk the R people into some changes to
their language in order to improve performance, and forbidding changes
to the variable names associated with a function may be one of them.
May! I certainly _won't_ be able to talk them out of passing
functions around as data, and don't mean to try.

To the best of my knowledge, here's what GCL does.
(0) Every keyword symbol (like :fred) has a slot used for argument
passing. This slot is initially a value that means "not set and
not wanted either."

(1) The caller passes the keywords with their arguments.

(2) The callee walks over its formals setting each to the
"wanted but not yet set" state.

(3) It then walks over the actuals, checking that each is still in
the "wanted but not yet set" state when encountered, and storing
the associated value in the slot.

(4) It then walks over the formals again picking up the values from
the slots and evaluating the defaults for those that are missing.

(5) It then walks over the actuals again resetting the symbols to
the initial state.

So that's 3 passes over the actuals and 2 passes over the formals.
1 pass is the ideal minimum. I reckon I can do it in 2 passes over
the actuals and 1 pass over the formals.

It might be possible to come up with a hybrid system where
- calls to protected pervasive globals with known parameter profiles
are compiled directly
- calls to non-locals have an in-line cache to see if it is still the
same function that was called last time
- calls to parameters and functions extracted from data structures go
through the "slow" interface.

--
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
[My, they've thrown you quite a ball of mud, haven't they? I think
something like my hack would work if you matched up actual functions
(by internal addresses of some sort) with calls per source routine.
Whatever you do, it'll probably be ugly and slow, but what do they
expect? The only way to make programs run fast is to make the source
code hold still long enough that you can do some analysis on it. -John]
--