help-gnu-emacs
[Top][All Lists]
Advanced

[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 ***


reply via email to

[Prev in Thread] Current Thread [Next in Thread]