all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* No setf-method known for funcall
@ 2005-08-18 12:31 kcin
  2005-08-18 14:24 ` Pascal Bourguignon
  0 siblings, 1 reply; 4+ messages in thread
From: kcin @ 2005-08-18 12:31 UTC (permalink / raw)


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"


Any ideas?

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: No setf-method known for funcall
  2005-08-18 12:31 No setf-method known for funcall kcin
@ 2005-08-18 14:24 ` Pascal Bourguignon
  2005-08-19  1:59   ` Barry Margolin
  0 siblings, 1 reply; 4+ messages in thread
From: Pascal Bourguignon @ 2005-08-18 14:24 UTC (permalink / raw)


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))
         (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))

(progn
  (setf x (cons :a :b))
  (setf f (function cdr))
  (setf (funcall f x) 1)
  (insert (format "--> %S\n" x))
  (dolist (f (list (function car) (function cdr)))
    (setf (funcall f x) 2))
  (insert (format "--> %S\n" x)))

--> (:a . 1)
--> (2 . 2)

-- 
"By filing this bug report you have challenged the honor of my
family. Prepare to die!"

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: No setf-method known for funcall
  2005-08-18 14:24 ` Pascal Bourguignon
@ 2005-08-19  1:59   ` Barry Margolin
  2005-08-19  3:47     ` Pascal Bourguignon
  0 siblings, 1 reply; 4+ messages in thread
From: Barry Margolin @ 2005-08-19  1:59 UTC (permalink / raw)


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

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: No setf-method known for funcall
  2005-08-19  1:59   ` Barry Margolin
@ 2005-08-19  3:47     ` Pascal Bourguignon
  0 siblings, 0 replies; 4+ messages in thread
From: Pascal Bourguignon @ 2005-08-19  3:47 UTC (permalink / raw)


Barry Margolin <barmar@alum.mit.edu> writes:
> In article <871x4r9vbx.fsf@thalassa.informatimago.com>,
>  Pascal Bourguignon <spam@mouse-potato.com> wrote:
>> Write a defsetf-er for funcall!
>[...]
>> (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).

Indeed.

One problem to implement a run-time setf funcall, is that setf-ers are
defined from the name of the function:

(defun example (cons) (car cons))
(defun set-example (cons value) 
       (format *trace-output* "set-example")
       (setf (car cons) value))

(setf (symbol-function 'test) (symbol-function 'example))

(setf (symbol-function test) (symbol-function example))
(defun set-test (cons value)
       (format *trace-output* "set-test")
       (setf (car cons) value))
(defsetf test set-test)

(setf x (cons 0 0))

[44]> (setf (example x) 1)
set-example
1
[45]> (setf (test    x) 2)

set-test
2

But:
(setf fun (function test))
(setf (funcall fun x) 1)

could not know whether to use set-example or set-test, 
for (and (eq fun (function example)) (eq fun (function test)))


To make (setf (funcall ...) ...) work, we'd have to associate the
setters to the function objects instead of the function names (the
symbols).

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
-----BEGIN GEEK CODE BLOCK-----
Version: 3.12
GCS d? s++:++ a+ C+++ UL++++ P--- L+++ E+++ W++ N+++ o-- K- w--- 
O- M++ V PS PE++ Y++ PGP t+ 5+ X++ R !tv b+++ DI++++ D++ 
G e+++ h+ r-- z? 
------END GEEK CODE BLOCK------

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2005-08-19  3:47 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-08-18 12:31 No setf-method known for funcall kcin
2005-08-18 14:24 ` Pascal Bourguignon
2005-08-19  1:59   ` Barry Margolin
2005-08-19  3:47     ` Pascal Bourguignon

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.