[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: left to right order of evaluation



Yes, there is a slight misnomer in the discussion -- it is, as you
mention in your previous note, relevant only to whether "to do the
SYMBOL-FUNCTION of G before computing the args" or not.  The question of
left-to-right order for argument evaluation wasn't ever, as far as I can
recall, seriously questioned.

Two items may influence the pertinent point however:
  1) Interpreters classically "snoop" at the function position first,
     regardless of whether they are classical Lisp interpreters, or the
     "mindless uniformity" style so favored by functional programming
     types.  Thus, without extra forethought, interpreter would probably
     do the SYMBOL-FUNCTION before doing the args; in fact, without the
     severe limitation on "special forms" in CL , it would be possible 
     in other dialects to change even the EXPR/FEXPR decision on the 
     "function" after beginning the argument evaluations.
  2) As you mention, there is some variability here in compile-time
     environments; back at the beginning of the VAX/NIL project, we 
     opted for a design that would "open up" a function call frame on 
     the stack before actually evaluating the arguments; the format of 
     the compiled code was to "push" into this opened-up frame, rather 
     than merely "push"ing at the stack tip.  This permitted an error
     for "undefined function" to be signalled before the "arguments"
     were computed (with potentially many side-effects); it also enabled
     more debugging information to be obtained from the stack frame
     during the interval of time of evaluating the arguments.

Point 2 was a bit controversial; especially in view of the LispMachine
pattern which was simply to push at the stack tip, and *after* all
arguments were pushed, then decide what to do about a function call.
One area of concern was performance, and the follow should explain why
this decision, *for the VAX* was not a performance impact.

Since the VAX has an very flexible set of instructions, with plenty of
registers to be "frame pointers", this decision caused no slowdown in
the compiled code, but rather cost only an extra byte or two per operand
pushed.  The VAX PUSHL opcode, oddly enough, isn't particularly fast --
Rich Bryan and I once reported this odd observation to a mail list
(forget which one, maybe NIL@MC), but others, notably Fateman, had
reported the same finding earlier.  To no one's surprise, the VAX CALLS
instruction is the big loser here and I've heard rumors that the DEC
Common Lisp folks have, upon "second system re-design", dropped it
altogether in favor of JSB for Lisp function calling.

As you may infer, I rather favor the doing of the SYMBOL-FUNCTION first,
not only because of the extra debugging information that this way may
supply, but also because it tends to lessen the conflict engendered by
the "separate function cell" which so antagonizes the functional
programming types.  However, like you, I would place "performance" at a
priority higher than that for this particular matter of uniformity.


-- JonL --