From: Peter Seibel
Subject: When to pass on environment object?
Date: 
Message-ID: <m3ad9gc7no.fsf@javamonkey.com>
So unless I missed any, the list below are all the functions that take
an environment object as an argument. It seems to me that whenever one
calls one these functions from code that is computing a macro
expansion, one should pass the environment object that was "passed" to
the macro (via a &environment parameter). Is that right? Or are there
situations where one would want the compile-time computation to use
the null lexical environment instead of the compile-time environment?

MACRO-FUNCTION
GET-SETF-EXPANSION
COMPILER-MACRO-FUNCTION
MACROEXPAND-1
MACROEXPAND
CONSTANTP
MAKE-LOAD-FORM
SUBTYPEP
TYPEP
UPGRADED-COMPLEX-PART-TYPE
UPGRADED-ARRAY-ELEMENT-TYPE

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp

From: Joe Marshall
Subject: Re: When to pass on environment object?
Date: 
Message-ID: <8yoznuzr.fsf@ccs.neu.edu>
Peter Seibel <·····@javamonkey.com> writes:

> So unless I missed any, the list below are all the functions that take
> an environment object as an argument. It seems to me that whenever one
> calls one these functions from code that is computing a macro
> expansion, one should pass the environment object that was "passed" to
> the macro (via a &environment parameter). Is that right? 

Yes, you pretty much should *always* pass the &environment parameter.

> Or are there situations where one would want the compile-time
> computation to use the null lexical environment instead of the
> compile-time environment?
>
> MACRO-FUNCTION
> GET-SETF-EXPANSION
> COMPILER-MACRO-FUNCTION
> MACROEXPAND-1
> MACROEXPAND
> CONSTANTP
> MAKE-LOAD-FORM
> SUBTYPEP
> TYPEP
> UPGRADED-COMPLEX-PART-TYPE
> UPGRADED-ARRAY-ELEMENT-TYPE

Well, you *might* not want to capture certain names in the
compile-time environment.  In those cases, you shouldn't pass the
&environment parameter.  I can't say that I've ever encountered this
occasion, though.
From: Kent M Pitman
Subject: Re: When to pass on environment object?
Date: 
Message-ID: <sfwznhftasr.fsf@shell01.TheWorld.com>
Joe Marshall <···@ccs.neu.edu> writes:

> Well, you *might* not want to capture certain names in the
> compile-time environment.  In those cases, you shouldn't pass the
> &environment parameter.  I can't say that I've ever encountered this
> occasion, though.

Sure you have.  In the LispM's MEXP function.

It's basically a tool for interactively prompting for forms and showing
you the macro expansion.  It just uses a null lexical environment to
do the expansion.

Also, there are codewalkers that might pass either NIL or an environment,
as a appropriate.
From: Joe Marshall
Subject: Re: When to pass on environment object?
Date: 
Message-ID: <4qznnlk2.fsf@ccs.neu.edu>
Kent M Pitman <······@world.std.com> writes:

> Joe Marshall <···@ccs.neu.edu> writes:
>
>> Well, you *might* not want to capture certain names in the
>> compile-time environment.  In those cases, you shouldn't pass the
>> &environment parameter.  I can't say that I've ever encountered this
>> occasion, though.
>
> Sure you have.  In the LispM's MEXP function.

I meant those cases when I'm writing macros that expand other macros.
From: Kent M Pitman
Subject: Re: When to pass on environment object?
Date: 
Message-ID: <sfw65k3axqf.fsf@shell01.TheWorld.com>
Joe Marshall <···@ccs.neu.edu> writes:

> Kent M Pitman <······@world.std.com> writes:
> 
> > Joe Marshall <···@ccs.neu.edu> writes:
> >
> >> Well, you *might* not want to capture certain names in the
> >> compile-time environment.  In those cases, you shouldn't pass the
> >> &environment parameter.  I can't say that I've ever encountered this
> >> occasion, though.
> >
> > Sure you have.  In the LispM's MEXP function.
> 
> I meant those cases when I'm writing macros that expand other macros.

Ah.  Right. 

Best I can come up with is something like in Emacs mode hooks or in
LispM's "initializations lists" where you accumulate a list of forms
to be evaluated at some known time and then you execute them.
Perhaps in such a case, you might ultimately have a macro call that
grabs those forms from a source other than the lexical position of
the macro call and expands into them.  I think the purpose of
&environment is to preserve the lexical contour in which the form is
visible.  If the form was added from a point other than the macro call, 
especially one of uncertain origin, it is surely beter to use the
null lexical environment than to foist a lexical environment on it
that is unfamiliar (and potentially hostile) unless you've documented
the exact nature of the to-be-forced lexical contour to the person
in the remote location ...  so you might choose to write

 (defvar *inits* '())
 (defun add-init (form) (push form *inits*))
 (defmacro do-inits ()
   `(eval '(progn ,@(reverse (mapcar #'macroexpand *inits*)))))

in order to expand the macros as early as possible (in case they are
not defined at runtime) but in order to get the null lexical environment
rather than any unpredictable lexical  environment of the (do-inits) form.

Maybe that's contrived, but that I think gives a sense for the character
of what would have to be true for this to get the null lexical env.
And it helps explain why mostly the situation doesn't come up at all.
But I'm still prone to say that style rules are made to once in a while
be broken, so I don't want to say that it's a hard-and-fast rule that  you
must pass the env.  You simply must pass it unless you are in a situation
where it is the wrong thing...

Please also ignore the fact that I'm not sure that a macro implementation
of do-inits is bteter than a functional one.  I would use a function.  But
then I wouldn't have been able to illustrate even this kludgey a situation.
From: Joe Marshall
Subject: Re: When to pass on environment object?
Date: 
Message-ID: <znhfm4ki.fsf@ccs.neu.edu>
Kent M Pitman <······@world.std.com> writes:

> But I'm still prone to say that style rules are made to once in a while
> be broken, so I don't want to say that it's a hard-and-fast rule that  you
> must pass the env.  You simply must pass it unless you are in a situation
> where it is the wrong thing...

I'm guessing that in those cases where you *want* to ignore the
&environment, you probably will *know* you want to ignore the
&environment.
From: Kent M Pitman
Subject: Re: When to pass on environment object?
Date: 
Message-ID: <sfw65k2t5qj.fsf@shell01.TheWorld.com>
Joe Marshall <···@ccs.neu.edu> writes:

> Kent M Pitman <······@world.std.com> writes:
> 
> > But I'm still prone to say that style rules are made to once in a while
> > be broken, so I don't want to say that it's a hard-and-fast rule that  you
> > must pass the env.  You simply must pass it unless you are in a situation
> > where it is the wrong thing...
> 
> I'm guessing that in those cases where you *want* to ignore the
> &environment, you probably will *know* you want to ignore the
> &environment.

Yes, this is exactly the point I was making.  But people here sometimes
put unreasonable pressure on the "show me an example or i won't believe 
you that there's ever a case" line.  There are just a number of things 
where the style rule is "Always do it this way, but remember in the back
of your mind that it could, in principle, be sometimes done otherwise."
... since, as I say, sometimes you have to violate style rules.