[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
common lisp- &environment objects
Date: Sun, 9 Jun 1985 23:17 EDT
From: "Scott E. Fahlman" <Fahlman@CMU-CS-C.ARPA>
One false move here and we have not Lisp but Conniver. How about
requiring "dynamic" extent for environment objects, and no more? Will
that take care of the needs for macro-expansion, steppers, and so on?
True, you could imagine cute ways of using environments that outlive
their invocations, but I REALLY don't want to pay for those cute uses
with inefficiency or severe constraints on the implementor. If anyone
wants to implement Conniver in Common Lisp, I can supply the old Maclisp
code, but let's not drag down Common Lisp itself.
Moon very carefully solved this problem in Symbolics' implementation of
Common Lisp by having an &ENVIRONMENT keyword to defmacro and making
sure all possible expanders of macros took an optional environment
argument, to which they can pass to MACROEXPAND(-1). This isn't cute;
it is functional. It isn't inefficient and it doesn't pose any
constraints on the implementor, unless I misunderstand what "the
implementor" is suposed to mean.
I don't understand what you are saying here. What does this have to do
with the extent of environment objects? What, exactly, are you arguing
for?
I'm arguing that CLtL says much too little about environments. It does
not say how to get your hands on one, but specifies them as optional
arguments to functions, for example EVALHOOK, APPLYHOOK, MACROEXPAND(-1)
(and in our implementation EVAL). Dynamic extent isn't good enough; how
can you do upward funargs? This is far from cute:
(defun adder (val)
#'(lambda (x) (+ x val)))
it is instead at the heart of lexical scoping.
As I said in an immediate follow-up to the above message, you only get a
lot of additional expense if you actually let users do all of the
"obvious" things with an immortal environment object, such as going to
the tags
Tags have dynamic extent. Going with tags outside their dynamic extent
should generate errors.
and diddling the lexical variables.
What good is lexical scoping if you can't diddle lexical variables?
I really don't care if
environment objects have indefinite or dynamic extent, as long as these
expensive kinds of uses are clearly forbidden once you exit the dynamic
extent, but the politics of this group are such that we must be very
careful about introducing features that, if taken to their logical
conclusion, lead us to somewhere we don't want to go; there are always a
lot of people who demand that everything be taken to its logical
conclusion, and damn the expense, so it is sometimes better not to take
the first step.
CLtL'84, on page 39 pretty clearly gives the scope and extent of just
about everything. Maybe you are concerned that I want the users to
diddle with the environment itself? Not at all. The structure of the
environment is peculiar to the implementation. I am, perhaps
incorrectly, assuming that creating a lexical closure captures the
current environment.
I do note that the original query suggested that Symbolics was
stack-allocating environment objects, and other implementations might
want to do similarly tense things in order to make the interpreter
reasonably cons-free. That suggests to me that it would be a good idea
to allow environment objects to have dynamic extent only, unless someone
can explain why this is unworkable or can demonstrate some important
thing that cannot be done if we take this position. I am always
nervous about disappearing objects, such as the disappearing &rest args
in Zetalisp (not legal in Common Lisp), but in the case of environment
arguments we might choose to go with a dangerous but efficient solution.
I'll repeat the classic lexical scoping example:
(defun adder (val)
#'(lambda (x) (+ x val)))
Environments must have indefinite extent (at least the environment of
non-special variables and local functions (FLET, LABELS)). The way this
works is that the environment has a slot which is called ENV-EVACUATION
which is the heap version created as necessary. Therefore, internal
interpreter functions (e.g., the definition of the FUNCTION special
form) explicitly evacuate the environment since it is being stored in
permanent storage.