[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Maclisp interpreter/compiler nearly identical w/ (declare (special t)) on??
- To: fateman @ UCBDALI
- Subject: Maclisp interpreter/compiler nearly identical w/ (declare (special t)) on??
- From: Kent M Pitman <KMP @ MIT-MC>
- Date: Tue, 09 Oct 1984 04:02:00 -0000
- Cc: common-lisp @ SU-AI
- In-reply-to: Msg of Fri 14 Sep 84 09:40:12 pdt from fateman%ucbdali at Berkeley (Richard Fateman)
Date: Fri, 14 Sep 84 09:40:12 pdt
From: fateman%ucbdali at Berkeley (Richard Fateman)
... If we look at Maclisp with (declare (special t)), is it not the
case that (nearly) identical semantics are used for the interpreter
and compiler, given CORRECT programs? ...
I'm afraid I take offense at this. Maclisp interpreted semantics are *very*
different than compiled semantics. Common Lisp is not completely there, but
puts its heart in the right place by at least acknowledging the problem.
Also, it has corrected at least some of the Maclisp problems. Here are a
few Maclisp interpreter/compiler differences that come to mind at the
moment to jar your memory; I'm sure this is not an exhaustive list:
* If you make a "correct" number declaration for X and Y, you may
risk that (PLUS X Y) which would run correctly interpreted will
be open coded as if (+ X Y) had been written. In PLUS case interpreted,
however, overflow becomes a bignum while in the + case interpreted,
the result is undefined (wraparound or some such thing occurs undetected).
I didn't see any obvious place in the CL manual where it says if
this is fixed.
* There are a bunch of control variables such as CAR, CDR, and EVAL
which are (necessarily) ignored by compiled code. They radically
affect the semantics of interpreted code by allowing the user to
extend the notion of what was "defined" without providing a mechanism
for informing the compiler of such extensions.
There are no such variables in CL.
* The status of macros in the car of a form was not uniformly treated in
interpreted and compiled form. In the form ((FOO BAR) ...), if FOO was a
macro, the interpreter would cause the result of expanding (FOO BAR) to be
evaluated before being applied, while the compiler would compile an apply
to the result of expanding (FOO BAR) directly rather than compiling a call
to the result of evaluating the expansion. Early Maclisp actually attempted
to define this as reasonable behavior; I think it was eventually flushed
and compiler warnings were issued in some cases saying to use FUNCALL.
I could not determine where or whether the CL manual takes a stand on this
issue. It would be nice if it simply declared that forms other than
((LAMBDA ...) ...) whose cars are lists are explicitly undefined.
* Compiled macros, if redefined, have no effect on running programs.
This is still true in CL. If interpreted CL definitions were ENCLOSE'd
(a la Scheme) at definition time, this could be fixed.
* Constant quoted expressions which were EQUAL will have been made EQ by the
FASLOAD process. This fact has been heavily depended upon by Macsyma on
the pdp10 to avoid wasting huge amounts of space needlessly, and must be
understood by all programs to avoid accidentally side-effecting constants
which ought by right have no relation to each other.
I guess this one is under active discussion.
* Function definitions for interpreted and compiled code differ.
(FUNCALL (GET 'X 'EXPR)) runs the same interpreted and compiled, but
(DEFPROP X (LAMBDA () 3) EXPR) runs differently compiled than interpreted.
There is definitely an advance in CL by having simply a function cell and
eliminating this nonsense about having 18 different places to store
functions. There's some question in my mind about whether macros belong
in the function cell, but this is at least treated uniformly from
interpreter to compiler.
* EVAL-WHEN does different things in an EVAL context than a COMPILE context.
I can't imagine wanting to fix this given the current state of the world,
although if, as I mentioned above, CL had an analog to Scheme ENCLOSE which
was used at appropriate times in both interpreter and compiler, I could
imagine changing the set of keys that EVAL-WHEN used (to not be EVAL and
COMPILE, but instead something more abstract) so that they were uniformly
treated in interpreted and compiled code.
* EVALFRAME works completely differently in compiled and interpreted contexts
since call the compiler may optimize out intermediate call frames. Hence
(LET ((THIS-FRAME (EVALFRAME ...))) ...) works fine compiled but must be
treated very carefully interpreted.
This issue isn't addressed by CL, hence is sort of fixed.
* Number EQness of small numbers may not be preserved in compiled code, but
is guaranteed in many cases in interpreted code. Technically, it was never
guaranteed that this was so, but in practice, I (and probably others) wrote
code that relied on the fact and achieved useful ends.
The introduction of EQL in CL makes a positive stride in the right direction.
I don't know if I consider this problem completely resolved.