[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Flush COMPILER-LET?
- To: Kent M Pitman <KMP@scrc-stony-brook.arpa>
- Subject: Re: Flush COMPILER-LET?
- From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
- Date: Tue, 27 Sep 88 19:06:00 BST
- Cc: sandra <@cs.utah.edu:sandra@defun>, CL-Compiler@sail.stanford.edu
> (TYPED-VAR Z) won't be expanded until I finally call this closure,
> but by then the COMPILER-LET bindings have long since gone.
>
> Only happens in interpreted-only implementations which have no
> semantic pre-pass. Why am I not surprised? Sigh...
I agree with you there (that a pre-pass eliminates the problem). I'm
not sure why you say "interpreted-only implementations", though. Lisps
that have a compiler can still have this problem in their interpreter.
> > You can do the same thing with MACROLET, but it feels quite awkward.
>
> But it works. ...
>
> If you can think of it. I guess I think it's such a radical trick that
> average programmers will never think of.
Well, I had to do something like this recently. I wrote it with
COMPILER-LET and, since the Lisp I used lacked a pre-pass in its
interpreter, it didn't work. So I tried MACROLET in various ways.
The COMPILER-LET solution was certainly easier to discover.
> It's yucky because it doesn't let you say what you really mean. You get so
> caught up in mechanism that you lose the expressional abstraction a variable
> provides. Further, it's harder than this example because of the need to use
> explicit MACROEXPAND and an ENV argument.
That's what I did too (use MACROEXPAND and &ENVIRONMENT). But I decided
it was too yucky and eventually hit on the following variation:
(defmacro local-type-declare (declarations &body forms)
(expand-local-type-declare '() declarations forms))
(defmacro typed-var (var)
(error "TYPED-VAR [of ~S] must be in a LOCAL-TYPE-DECLARE." var))
(defun expand-local-type-declare (nest declarations forms)
(let ((nested-declarations (append declarations nest)))
`(macrolet
((local-type-declare (declarations &body forms)
(expand-local-type-declare
',nested-declarations declarations forms))
(typed-var (var)
(let ((type (assoc var ',nested-declarations)))
(if type `(the ,(cadr type) ,var) var))))
,@forms)))
> Assuming COMPILER-LET was made to work reliably (including the situation
> described above) and a reasonable example was provided,
I wouldn't want to flush it if it could be made to work reliably.
But what if it can't?
> Also, the MACROLET version doesn't deal with the issue of side-effects.
> Offhand I see no way to use MACROLET to simulate a situation which uses
> COMPILER-LET and where a compiler-let variable is re-assigned (by SETQ)
> in a contained macro call. The kind of macro where you'd do that would be
>
> (WITH-MY-STICKY-DECLARATIONS
> (+ (MY-THE FIXNUM X) (MY-SQRT X)))
>
> where MY-THE might be like THE, but it could push onto a list of
> declarations maintained by WITH-MY-STICKY-DECLARATIONS so that MY-SQRT
> could be a macro that knew X was a FIXNUM.
Would something like the following suffice?
(defmacro with-my-sticky-declarations (&body forms)
(let ((place (gensym)))
`(macrolet
((my-the (type var)
(push (list var type) ,place)
`(the ,type ,var))
(my-sqrt (form)
(if (symbolp form)
(let ((type (assoc form ,place)))
...)
...)))
,@forms)))
-- Jeff