2005/11/1, Raymond Toy <[EMAIL PROTECTED]>:
> >>>>> "Kris" == Kris Steegmans <[EMAIL PROTECTED]> writes:
>
> Kris> Hi all,
>
> Kris> Consider the following:
> Kris> (defun fun (&key arg)
> Kris> (declare (ignore arg))
> Kris> nil)
> Kris> (defun (setf fun) (value &key arg)
> Kris> (declare (ignore arg value))
> Kris> nil)
> Kris> (push 'a (fun :arg 'bla))
>
> Kris> This gives the following note when executing this:
> Kris> ; Note: The first argument (in keyword position) is not a constant.
>
> Kris> If I check the macroexpansion of the last form, I can see where it
> Kris> comes from:
> Kris> (macroexpand-1 '(push 'a (fun :arg 'bla)))
> Kris> (LET* ((#:G2520 'A)
> Kris> (#:G2519 :ARG)
> Kris> (#:G2518 'BLA)
> Kris> (#:G2517 (CONS #:G2520 (FUN #:G2519 #:G2518))))
> Kris> (FUNCALL #'(SETF FUN) #:G2517 #:G2519 #:G2518))
> Kris> T
>
> Kris> It evaluates ':arg' to make sure it gets evaluated only once, but
> then
> Kris> the keyword argument to (setf fun) is no longer a constant.
>
> I don't know why it does that. I thought the compiler would be able
> to figure out that #:g2519 is bound to :arg and is constant, but I
> guess not.
>
> Ray
>
The compiler must indeed be able to figure out that.
On the other hand, I even question is why the compiler should give a
note about that. I think it is perfectly legal common lisp to have a
keyword that is not a constant:
(defun g (&key a b c)
...)
(defun f (keyword value)
(g keyword value))
Another option would be to rewrite the push macro to check for
constants and don't declare variables for them in the let* expression.
With some macro hacking this should be possible.
Kris