* 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
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).