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


Reply via email to