[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]


You raise some interesting points here....

I actually *can* think of one example where it's useful for a macro to
SETQ a special variable as a side effect -- when the variable is some
kind of a counter used to generate unique labels.  I'd rather not forbid
SETQ'ing entirely, but it is something that has to be used with caution.
I agree, leaving out references to assignment would help simplify the

> Suppose that instead of referencing the value as a special, you had 
> an operator COMPILER-SYMBOL-VALUE to get its value. [That could be a 
> function, macro, or special form.] I wouldn't have a problem calling
> a function to get this data because I still get to use the same basic
> `shape' of code. Also, uses of COMPILER-LET are rare enough that a
> bit of extra syntax is not overwhelming.

If you don't mind having to pass an explicit environment argument to
COMPILER-SYMBOL-VALUE (as you have to do for GET-SETF-METHOD, for
example), I think this bit of code will do what you want.

(defun compiler-symbol-value (symbol &optional env)
    (macroexpand `(compiler-symbol-value-aux ,symbol) env))

(defmacro compiler-symbol-value-aux (symbol)
    `(symbol-value ',symbol))

(defmacro compiler-let (var-value-pairs &body body &environment env)
    (let ((bindings
              (mapcar #'(lambda (v)
	       		    (if (symbolp v)
			        (cons v nil)
				(cons (car v) (eval (cadr v)))))
        `(macrolet ((compiler-symbol-value-aux (symbol)
	                (let ((info  (assoc symbol ',bindings)))
			    (if info
			        (cdr info)
				(compiler-symbol-value symbol ',env)))))

I wouldn't object greatly to adding this to the language, although
somebody is bound to ask why we should bother when it is something
that users can easily write for themselves if they need this

> People think in terms of containers (variables)
> as places to put things, and procedures (functions) as things that do things.
> They don't like to think of a container as being represented by a function
> whose meaning is might be locally changed in some contexts. It's just not
> natural.

What I was suggesting is that some people might not formulate the
problem as having anything to do with a "container" in the first
place.  Step back a bit and look at the bigger picture.  The problem
the example in the writeup is trying to solve is providing a macro to
decorate variable references with type declarations within a
particular lexical scope.  Actually, the most intuitive way I find to
think about this problem is the way that the new example I added to
the discussion section presents it (and the way I wrote the
COMPILER-LET macro above): first see if the variable matches those
that were supplied types in the innermost lexical scope, and if not
recurse on the next outermost lexical scope.  Although you might find
it more intuitive to lump all the variable/type pairs into a
container, the container is not inherent in the solution to the

> The question about whether the extent of an &ENV argument is indefinite or
> dynamic is interesting. Is there a cleanup to cover this?

I don't think so.  To me it seems more likely that some
implementations destructively bash on environment objects after you've
returned from the macro function, than that anybody is trying to
stack-allocate them.  I think we do need to clarify this, along with
all the zillion other unresolved problems with environment objects.  I
was hoping issue SYNTACTIC-ENVIRONMENT-ACCESS would help address some
of these problems but it's been languishing from neglect.