Subject: Re: Question about the lexical environment
From: rpw3@rpw3.org (Rob Warnock)
Date: Wed, 25 Mar 2009 03:34:53 -0500
Newsgroups: comp.lang.lisp
Message-ID: <3bKdnZyRi-IwcVTUnZ2dnUVZ_vOdnZ2d@speakeasy.net>
Anticomuna  <ts.conceicao@uol.com.br> wrote:
+---------------
| I am a bit confused about the &environment keyword in defmacro.
| 1 - How do I create an instance of an environment object to pass to
|     macro calls?
+---------------

You don't. The system does, when it expands your macro.

+---------------
| 2 - What do I do with it?
+---------------

In ANSI CL, basically all you can do with it is pass it on
to one of these functions:

    MACROEXPAND
    MACROEXPAND-1
    MACRO-FUNCTION
    COMPILER-MACRO-FUNCTION
    GET-SETF-EXPANSION

+---------------
| Can I install it in the place of the current one for the expansion
| of the macro?
+---------------

Nope, sorry. And you can't return it, either. In ANSI CL it has dynamic
extent, and is only valid during the expansion of the macro in question.

But that's sort of o.k., since *nothing* defined, standard, or portable
about the type, format, or contents of the environment object, so what
could you do with it even if you *could* store it away?!? [But see the
postscript below.]

+---------------
| I understand how lexical environments work, I just don't understand
| why it is explicitly handled by the developer and what is its life-
| cycle (when it is created, used and dereferenced).
+---------------

As noted in CLHS "Issue MACRO-ENVIRONMENT-EXTENT:DYNAMIC":

    CLtL says that &ENVIRONMENT is "useful primarily in the rare cases
    where a macro definition must explicitly expand any macros in a
    subform of the macro call before computing its own expansion".

But you can't reliable "expand macros in a subform of the macro call"
unless you can tell whether symbols in a CAR of forms *are* macros
or functions, and since FLET/LABELS & MACROLET can mutually shadow
each other, you need the current lexical environment at the point
of expansion to make those decisions. So the &ENVIRONMENT arg was
introduced to allow the user (very limited) access to the current
lexical environment, but only for the purposes of passing it on to
the above-mentioned five functions during the expansion.

So... Don't overthink it. There's very little you can do with
environment objects in ANSI CL, and probably you won't ever
need to. But if someday you do, the above may help.


-Rob

p.s. Several times above I said "in ANSI CL". That's because there
*are* implementations that have extensions which provide much more
useful lexical environments, especially one by Franz that's similar
to the CLtL2 environments proposal that didn't make it into ANSI
Common Lisp, see:

    http://www.franz.com/support/documentation/7.0/doc/environments.htm
    http://www.lispwire.com/entry-proganal-envaccess-des
    http://www.lispwire.com/entry-proganal-envaccess-tech

The latter says:

    A version of this module has been incorporated into Allegro CL
    since version 6.1.
    ...
    This module is intended to work with all major CL implementations
    at a "level 1" state (see the Powerpoint presentation), and is known
    to work on CMUCL (18e and 19a), clisp (2.33.2), and SBCL (0.8.16).
    It compiles and loads on an old 4.1 version of Lispworks, but
    environment objects cannot be printed; a format bug is suspected.
    ...

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607