[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: No setf-method known for funcall
From: |
Barry Margolin |
Subject: |
Re: No setf-method known for funcall |
Date: |
Thu, 18 Aug 2005 21:59:28 -0400 |
User-agent: |
MT-NewsWatcher/3.4 (PPC Mac OS X) |
In article <871x4r9vbx.fsf@thalassa.informatimago.com>,
Pascal Bourguignon <spam@mouse-potato.com> wrote:
> kcin@mytrashmail.com writes:
>
> > I'd like to setf a "place" which is retrieved indirectly with a funcall
> > call:
> >
> >
> > (defstruct my
> > a b)
> >
> > (setq myinstance (make-my))
> >
> > (setf (my-a myinstance) 33) ; this works
> >
> > (setq my-get-func 'my-a)
> > (setf (funcall my-get-func myinstance) 33)
> > ; this doesn't work
> > ; "No setf-method known for funcall"
>
> Write a defsetf-er for funcall!
>
>
> (require 'cl)
>
> (defmacro with-gensyms (syms &rest body)
> `(let ,(mapcar (lambda (s) `(,s ',(gensym (symbol-name s)))) syms) ,@body))
>
> (define-setf-method funcall (fun &rest args)
> "setf-method for (funcall fun args...)"
> (let* ((vfun (eval fun))
This won't work if the code is compiled. SETF is expanded at compile
time, but you need to EVAL the variable at run time (and need to do it
each time through the loop).
> (vexp (get-setf-method `(,vfun ,@args))))
> (message "\n%S\n" vexp)
> (when (null vexp)
> (error "There is no defsetf for %s in %S"
> vfun (cons fun args)))
> vexp))
In real Common Lisp, you can only SETF a FUNCALL if the function
argument is a literal, since SETF can get the function and its SETF
method. E.g. you can do:
(setf (funcall #'car) ...)
but you can't do:
(let ((func #'car))
(setf (funcall func) ...))
--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***