[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
New Issue: SYNTACTIC-ENVIRONMENT-ACCESS
I am about to prepare a revised version of the proposal. Here are
some specific replies before I start. Sorry about the length, but it
seemed better to reply to all of these together.
Date: 2 Oct 88 11:57 PDT
From: masinter.pa@Xerox.COM
would you say this supercedes:
-----
Issue: SPECIAL-VARIABLE-TEST
Yes, I think it includes everything covered by SPECIAL-VARIABLE-TEST.
Date: Sun, 2 Oct 88 15:21 EDT
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Date: 2 Oct 88 11:57 PDT
From: masinter.pa@Xerox.COM
would you say this supercedes:
"supersedes"
Issue: SPECIAL-VARIABLE-TEST
Since EB's proposal is more elaborate and might not get past X3J13, I
would prefer if both were presented and the committee could decide.
I don't want to see the failure of this proposal to pass leave us with
nothing to show.
Seems reasonable to me, although I'm encouraged by the reaction so far
to the new proposal.
Date: Sun, 2 Oct 88 15:54 EDT
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
The return values of ENVIRONMENT-VARIABLE-KIND in this proposal clashes
with PROCLAIM-LEXICAL in a bad way. I would prefer if it returned at least
two values:
Value 1 (KIND):
NIL = No declared semantics
LEXICAL = Lexical variable
SPECIAL = Special variable
MACRO = Symbol macro
Value 2 (WHERE-DECLARED):
GLOBAL = Globally declared
LOCAL = Locally declared
NIL = Not declared
This seems like a good idea to me; I'll incorporate it into the
proposal.
A third value you might consider returning is CONSTANT-P, so that a
variable declared by DEFCONSTANT could be distinguished. You could deal
with this by a separate function, though, similar to ENVIRONMENT-INLINE.
Also a good idea. I'm leaning towards Moon's suggestion of combining
all those functions and returning several multiple values from
ENVIRONMENT-VARIABLE-KIND and ENVIRONMENT-FUNCTION-KIND.
Another value to consider is PERVASIVE-P. As currently defined,
PERVASIVE-P is always true when WHERE-DECLARED is GLOBAL and never
true when WHERE-DECLARED is LOCAL. There has been a proposal to
introduce a pervasive special declaration (I'm not sure if it ever
became a formal cleanup issue).
In fact, I also think the returned values (other than T and NIL) should
be keywords because
- keywords are easier to deal with
- keywords are safe here (the set is non-extensible)
- it would be more consistent with other inquiry functions
like FIND-SYMBOL, which return status info in keyword package.
Fine with me. Sandra suggested the same thing. I had considered it
myself before using the defining form names, which I was never
entirely comfortable with.
Your suggested values would map as follows:
KMP suggestion EB suggestion
NIL, NIL NIL
SPECIAL, GLOBAL PROCLAIM
SPECIAL, LOCAL DECLARE
LEXICAL, LOCAL T
MACRO, LOCAL SYMBOL-MACROLET
My proposal leaves a few meaningless combinations, but has the virtue of
being extensible for other situations possibly yet to come, such as:
MACRO, GLOBAL Symbol macros (Symbolics Genera has them)
LEXICAL, GLOBAL Global lexicals (see issue PROCLAIM-LEXICAL)
The following other case which exists now but which you didn't address
might be worth considering, too:
NIL, GLOBAL Reserved words (eg, &FROBOZZ)
Yes, but it doesn't seem very important, since you can find this out
by doing (member x lambda-list-keywords).
I'd also be curious to know why you want ENVIRONMENT-VARIABLE-TYPE to
return NIL in the case where something's undeclared.
I just wanted to be able to distinguish whether the type was declared
T or defaulted to T.
I propose it return
T (the default type, after all), and perhaps offer a second return value
which says whether the information was declared or defaulted. Actually,
come to think of it, the second return value could be NIL, LEXICAL, or
GLOBAL for consistency with my suggestion above.
Yes. I would like to put this all into ENVIRONMENT-VARIABLE-KIND, as
I said.
Perhaps also ENVIRONMENT-INLINE could return as many as three values:
INLINE-P, INLINE-INFO-AVAILABLE-P, and WHERE-DECLARED
so that you could distinguish global from local information, etc.
The reason I suggest these is that a lot of kind of reasoning could
be done by looking only at the first value. The way you have all your
functions structured, you have to case for a lot more things than you
might really want to know. eg, if your only interest is to determine
if a variable is going to do a special reference, you have to look
for two markers (DECLARE and PROCLAIM) under your scheme, but a binary
value under mine. Similarly, if you want to know the type of something,
you have to special-case NIL under your scheme but can just use the
return value directly under mine. Only advanced applications where
more info is needed would need to pick up the additional values. Further,
the additional information is richer than the information provided in
your proposal.
All good ideas.
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Date: Mon, 3 Oct 88 10:56:21 MDT
> Date: Sun, 2 Oct 88 11:30:37 pdt
> From: Eric Benson <eb@lucid.com>
>
> ENVIRONMENT-TARGET env [Function]
>
> This function returns one of the three symbols EVAL, COMPILE or
> COMPILE-FILE, depending on whether the environment is from the
> interpreter, the in-core compiler, or the file compiler. If
> MACROEXPAND or MACROEXPAND-1 is called directly without supplying
> the environment argument, the environment passed to any expander
> functions will have target EVAL.
I really dislike this part of the proposal. I hate to have to keep
repeating myself, but there are other situations besides the three
listed here in which code may be processed. The example I've cited
before is a filter that reads in code from a file, performs some
preprocessing to decorate the code with lots of type declarations, and
writes it out to another file. I contend that anything that needs to
know whether the code is being processed by the interpreter or
compiler ought to be a special form (this includes EVAL-WHEN and
whatever we decide to do about LOAD-TIME-EVAL) and should be left
strictly alone by code walkers.
Are you comfortable with ENVIRONMENT-REMOTE-P?
As to the claim that CLOS needs this information, my understanding
from reading 88-002R is that what CLOS really needs to store in the
environment is information about the class hierarchy and which
functions are generic functions. (I'm guessing that the current
implementation does not do this, and instead stores the information
externally to the environment in different places depending on whether
it's for the compiler or interpreter.)
On the whole, I'm rather lukewarm about this proposal. I hate to add
this much more complexity to the language but I think it's probably
necessary. When local macro definitions were the only thing that the
environment was used for, you could hack out a code walker by defining
your own representation for environment objects and your own
MACROEXPAND-like function that understands that representation.
No, that doesn't work, because it doesn't allow you to pass the
correct environment to a macro that actually uses the environment.
That's the reason PCL's code walker has implementation-specific hooks
to create and access environments.
I
don't think that's possible any more if we are going to start
requiring that other information (i.e., for CLOS) be stored in the
environment. Also, you really do need access to proclamations (and
not just SPECIAL proclamations).
I intended all of these to provide access to proclamations as well as
declarations. I'll try to make that clearer in the next version.
A minor quibble: on all of the functions in this proposal that return
symbols, how about making them keywords, please?
I agree.
Date: Mon, 3 Oct 88 22:51 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
> ENVIRONMENT-TARGET env [Function]
>
> This function returns one of the three symbols EVAL, COMPILE or
> COMPILE-FILE, depending on whether the environment is from the
> interpreter, the in-core compiler, or the file compiler. If
> MACROEXPAND or MACROEXPAND-1 is called directly without supplying
> the environment argument, the environment passed to any expander
> functions will have target EVAL.
I really dislike this part of the proposal. I hate to have to keep
repeating myself, but there are other situations besides the three
listed here in which code may be processed. The example I've cited
before is a filter that reads in code from a file, performs some
preprocessing to decorate the code with lots of type declarations, and
writes it out to another file. I contend that anything that needs to
know whether the code is being processed by the interpreter or
compiler ought to be a special form (this includes EVAL-WHEN and
whatever we decide to do about LOAD-TIME-EVAL) and should be left
strictly alone by code walkers.
I think we have some confusion here between interpreter versus compiler
on the one hand, and operating in the local Lisp world versus outputting
to a file to be loaded later on the other hand. I feel that it is
completely inappropriate to add something that distinguishes between
the compiler and the interpreter. I'd like to see that part of the
proposal dropped.
I agree.
The important distinction is between what I will call local environments
and remote environments. A defining form (DEFUN, DEFVAR, DEFCLASS, etc.)
evaluated in a local environment affects the current Lisp world, but in
a remote environment it does not affect the current Lisp world, however
its effects still need to be remembered in a model of the Lisp world
that will be created later. Both COMPILE-FILE and your example program
annotating program work with remote environments. I defy you to come up
with an example where the local/remote environment distinction doesn't
make sense and a third type is needed. Thus I think ENVIRONMENT-TARGET
would better be named ENVIRONMENT-REMOTE-P.
Right.
Date: Mon, 3 Oct 88 22:56 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
I agree with the general tenor of Kent's comments. I'd like to see
an alternate version of the proposal written up that way, so we can
see the ramifications.
I'm working on it.
I also wonder about having separate accessors for scope, type, and
(for functions) inlinitude. Would it be more or less elegant to
have a single accessor that returns all this information as multiple
values? I'd say more elegant, although I'm not sure what happens
if the type was proclaimed but the inlinitude was declared.
I would like to combine all of these aspects into returned values from
ENVIRONMENT-VARIABLE-KIND and ENVIRONMENT-FUNCTION-KIND (and probably
change those names). That's going to mean a lot of retured values,
though. Does anyone think that's a bad idea?
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Date: Mon, 3 Oct 88 22:00:24 MDT
> Date: Mon, 3 Oct 88 22:51 EDT
> From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
>
> The important distinction is between what I will call local environments
> and remote environments. A defining form (DEFUN, DEFVAR, DEFCLASS, etc.)
> evaluated in a local environment affects the current Lisp world, but in
> a remote environment it does not affect the current Lisp world, however
> its effects still need to be remembered in a model of the Lisp world
> that will be created later. Both COMPILE-FILE and your example program
> annotating program work with remote environments. I defy you to come up
> with an example where the local/remote environment distinction doesn't
> make sense and a third type is needed. Thus I think ENVIRONMENT-TARGET
> would better be named ENVIRONMENT-REMOTE-P.
That's a very nice way to put it. Rather than trying to introduce
*more* kinds of environments, I would actually go in the other
direction and say that code walkers shouldn't even need to know the
distinction between local and remote environments. An implementation
ought to be free to use different representations for the two, but as
long as the accessors return the correct information, is there any
reason why you would need to know where it came from?
> Again the compiler/interpreter distinction is a red herring and CLOS has
> no reason to care about that distinction. The important distinction
> is local/remote. CLOS needs to know whether a DEFCLASS form changes the
> behavior of objects of that class in the current world, or only affects
> a future ("remote") world.
That's pretty much what I was trying to say: CLOS doesn't really need
to know whether the information is needed by the compiler or
interpreter or something else, as long as it finds the right
information.
If the local/remote environment model is adopted (or even if we don't
provide any way to tell the difference between the two), some way
would have to be provided for a code walker to create a remote
environment. The existing proposal assumes that everything the
compiler doesn't create must be an EVAL (that is, local) environment.
Right. AUGMENT-ENVIRONMENT will have to take a :REMOTE-P argument.
Sender: GRAY@Kelvin.csc.ti.com
Date: Wed, 5 Oct 88 18:58:37 CDT
From: David N Gray <Gray@DSG.csc.ti.com>
> Also, it has
> proven impossible to write a portable code walker in Common Lisp, due
> to insufficient access to the information contained in environments
> and the inability to augment environments with local function
> definitions.
I can see how writing a code walker is easier if you can augment the
local macro information, but I don't see what all the rest of this stuff
is needed for.
"All the rest of this stuff" is useful to code walkers for the same
reason it's useful to compilers.
> Proposal (SYNACTIC-ENVIRONMENT-ACCESS:ADD-FUNCTIONAL-INTERFACE):
>
> The following functions provide information about syntactic
> environment objects. In all of the functions the argument named ENV
> is a environment, of the sort received by the &ENVIRONMENT argument
> to a macro. In all cases it is an error to supply an argument which
> is not a syntactic environment.
I would like to add that it is an error to use an environment object
outside of the dynamic extent of the macro expander invocation which
received it as an &ENVIRONMENT argument. This proposal would be much
easier to implement if the implementation of these accessors were
permitted to, for example, recognize that the environment is a compilation
environment and then fetch the information from wherever the compiler
keeps it, than if the compiler's data structures had to be redesigned to
actually store all of the information in environment objects having
indefinite extent.
The extent of environment objects has been discussed before. I don't
remember whether that became a full-fledged cleanup issue, but I think
it is orthogonal to this issue. Larry, has such an issue been
presented? If not, David, you are welcome to present one.
> ENVIRONMENT-TARGET env [Function]
>
> This function returns one of the three symbols EVAL, COMPILE or
> COMPILE-FILE, depending on whether the environment is from the
> interpreter, the in-core compiler, or the file compiler.
I agree with Moon's comments that the real issue is local versus remote.
> ENVIRONMENT-OPTIMIZE-LEVEL attribute env [Function]
>
> ATTRIBUTE is one of the symbols SPEED, SPACE, SAFETY or
> COMPILATION-SPEED. This function returns an integer between 0 and
> 3, which reflects the current settings of the OPTIMIZE proclamation
> or declaration.
I hope this doesn't require an evaluator to keep track of OPTIMIZE
declarations even though it has no use for them itself.
Or type or inline declarations for that matter. I hate to put in some
weasely wording about how not all of this information may be
available. Does anyone have any feelings about this? I'm inclined to
make interpreters maintain such information in spite of the fact that
they have no use for it. I don't perceive it as a big burden to bear.
For example, I can see how to add it to Lucid's EVAL (which I wrote)
very easily and (I believe) without a noticeable increase in overhead.
How do other people feel about this?
> Rationale:
>
> This proposal provides a portable interface to environment
> information which must otherwise be obtained by
> implementation-dependent means. The ENSURE-GENERIC-FUNCTION and
> FIND-CLASS functions of CLOS require the ENVIRONMENT-TARGET function.
Yes, but I'm not sure that there is anything that can be portably done
with that information. Just because the implementation needs to do
something is not sufficient justification for making it available to
users. In this case, I suspect that CLOS is going to need more than
ENVIRONMENT-TARGET to do everything it needs to do.
What is your suspicion based on?
> A
> useful code walker requires the capability of adding local function
> definitions to an environment.
So who requires the other capabilities?
The other capabilities are not strictly "required" for a code walker
to function, but they are useful.
Date: Fri, 7 Oct 88 15:16 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Date: Mon, 3 Oct 88 22:00:24 MDT
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
....
If the local/remote environment model is adopted (or even if we don't
provide any way to tell the difference between the two), some way
would have to be provided for a code walker to create a remote
environment.
Yes, in EB's proposal AUGMENT-ENVIRONMENT needs a :REMOTE argument
which defaults to the remoteness of the ENV argument and specifies
the remoteness of the returned environment.
Absolutely.
One other thing I would like clarified. It makes sense to be able to
have more than one distinct remote environment around at any given
time; for example, if COMPILE-FILE is called recursively it ought to
create a new remote environment for each file.
That's true, although I was refraining from proposing anything that
complicated. If we get into that, then we also will have to make
environments extensible as I think I mentioned before. But if we
confine ourselves to just putting in a way to tell whether this is a
remote environment or not, that will be enough to get CLOS off the
ground.
Maybe there should be a way to distinguish between remote environments
that do not share a common parent. I can see how that might be
useful. How about if ENVIRONMENT-REMOTE-P returned either NIL or some
non-NIL object that is unique to that particular family of remote
environments? All the calls to COMPILE-FILE within a single
WITH-COMPILATION-UNIT would share the same remote environment parent.
Does it make any sense
to have more than one distinct local environment around, or is there
only one?
There is only one local global environment (gnashing of teeth in the
background over the terminology) in Common Lisp, but there can be more
than one in some dialects of Scheme (they're called "locales").
Multiple local global environments seem like a sound approach to solving
the same problems that packages were invented to solve.
On the terminology, this shows that "remote" is an okay word, but we
shouldn't use "local" as the antonym of "remote", since "local" is already
used as the antonym of "global". How about "running"?
How about "resident"?