Newsgroups: comp.lang.lisp
Path: cantaloupe.srv.cs.cmu.edu!das-news2.harvard.edu!news2.near.net!howland.reston.ans.net!news.sprintlink.net!pipex!uknet!festival!edcogsci!jeff
From: jeff@aiai.ed.ac.uk (Jeff Dalton)
Subject: Re: compiler-let, macrolet, ...
Message-ID: <Cyx092.6vA@cogsci.ed.ac.uk>
Sender: usenet@cogsci.ed.ac.uk (C News Software)
Nntp-Posting-Host: bute-alter.aiai.ed.ac.uk
Organization: AIAI, University of Edinburgh, Scotland
References: <DONC.94Nov3110739@hpai19.ISI.EDU>
Date: Mon, 7 Nov 1994 20:43:50 GMT
Lines: 74

In article <DONC.94Nov3110739@hpai19.ISI.EDU> donc@ISI.EDU (Don Cohen) writes:
>CLtL2 says (p.151) "Many" uses of compiler-let can be done with macrolet.
>It also says (p.400) that macro definitions should not depend on the time
>they're expanded.  I'm having trouble seeing how to get the effect of
>compiler-let if macros can be expanded at odd times.

You're right to suspect that that's a problem.  For instance,

  (defun f ()
    (compiler-let ((...))
      #'(lambda (...) ...)))

Maybe macros in the lambda-expr aren't expanded until the
corresponding function is called.  (I.e. F returns a function
derived from the lanbda-expr, and macros aren't expanded in
that returned function until it's eventually called.)

A compiler-let that just binds variables dynamically won't work in
such cases.

As for the macrolet alternative, typically a macrolet is not used to
get the same effect but to achieve the same aim in another way.

>I can imagine implementing compiler-let as a macro that expands into progv
>around a macroexpand-all (in order to make sure that all the macros inside
>the body are expanded in the right binding context), but of course the
>standard does not contain macroexpand-all.

That would handle problems like the one I suggested above, and
an implementation might have a macroexpand-all internally.

You can probably implement a macroexpand-all using the code-walker
that comes with PCL.

>Another problem I've noticed is that CLtL2 specifies that in the compiler, 
>compiler-let expands macros in the right binding context, but it does not
>require that in the interpreter!  It says the interpreter just treats it
>like let - which seems mean that the interpreter is allowed to expand all 
>the macros before doing the bindings!  (I seem to be seeing that behavior
>in lucid.)

Really?  Can you give an example?  Here's a simple one that works:

>(defvar *a* 1)
*A*
> (defmacro m () '*a*)
M
> (defun f ()
    (compiler-let ((*a* 10))
      (m)))
F
> (f)
10

>Does anyone have any suggestions of how to portably get what I think were
>the intended (perhaps I should say the "useful") effects of compiler-let?
>Is any of this stuff different in the ansi standard, by the way (other than
>the fact that compiler-let is presumably not even mentioned)?
>
>In case you're wondering what I want to use it for:
>I'm trying to define macros that are sensitive to scoped declarations
>(not the declarations already supported by lisp).
>I want to write a macro (with-declarations <decls> . body) that makes
>the decls visible to all the macros that are used in the body, including
>of course, any macros that those macros use.  I seem to recall seeing some
>discussion of this problem before.  Maybe I was even involved.  But I don't
>recall seeing a good solution.

Humm.  I will think about it and look for things.

-- jeff



