From: Kenneth Tilton on 7 Nov 2009 07:04 There's no way to funcall a setter! FUNCTION does not take variables! Python can do it! kt
From: Madhu on 7 Nov 2009 07:56 * Kenneth Tilton <4af5624a$0$31273$607ed4bc(a)cv.net> : Wrote on Sat, 07 Nov 2009 07:04:30 -0500: | There's no way to funcall a setter! FUNCTION does not take variables! So create a funcallable from the `setter's' name and funcall it! Here's an implementation that even compiles the setter and caches it! (defvar *setter-cache* (make-hash-table :test #'eq)) (defun find-or-make-setter (accessor-symbol &optional (accessor-cache *setter-cache*)) (check-type accessor-symbol symbol) (check-type accessor-cache hash-table) (or (gethash accessor-symbol accessor-cache) (setf (gethash accessor-symbol accessor-cache) (multiple-value-bind (vars vals store-vars writer-form reader-form) (get-setf-expansion (list accessor-symbol 'object)) (declare (ignore reader-form)) ;;(warn "computing ~A." accessor-symbol) (let* ((bindings (nconc (pairlis vars (mapcar 'list vals)) (pairlis store-vars (list '(new-value))))) (form `(lambda (new-value object) (let ,bindings ,writer-form)))) (compile nil form)))))) ;; Example Use (defstruct foo a) (defvar $a (make-foo)) (funcall (find-or-make-setter 'foo-a) 10 $a) ; => #S(FOO :A 10) -- Madhu
From: Pascal J. Bourguignon on 7 Nov 2009 07:57 Kenneth Tilton <kentilton(a)gmail.com> writes: > There's no way to funcall a setter! FUNCTION does not take variables! > > Python can do it! CL too. C/USER[90]> (defvar *store* nil) *STORE* C/USER[91]> (defun (setf store) (newval) (setf *store* newval)) (SETF STORE) C/USER[92]> (defun store () *store*) STORE C/USER[93]> (funcall (fdefinition '(setf store)) 42) 42 C/USER[94]> (store) 42 C/USER[95]> (funcall (fdefinition '(setf store)) 1) 1 C/USER[96]> (store) 1 C/USER[97]> (setf store) is a setter. On the other hand, while you can write (setf (car x) v), (setf car) may be not defined: SETF can have specific knowledge of some places without a need for an external setter. -- __Pascal Bourguignon__
From: Kenneth Tilton on 7 Nov 2009 10:42 Pascal J. Bourguignon wrote: > Kenneth Tilton <kentilton(a)gmail.com> writes: > >> There's no way to funcall a setter! FUNCTION does not take variables! >> >> Python can do it! > > CL too. > > > C/USER[90]> (defvar *store* nil) > *STORE* > C/USER[91]> (defun (setf store) (newval) (setf *store* newval)) > (SETF STORE) > C/USER[92]> (defun store () *store*) > STORE > C/USER[93]> (funcall (fdefinition '(setf store)) 42) Ah, silly me, I looked at fdefinition but didn't Get It. thx,kt
From: Kenneth Tilton on 7 Nov 2009 10:43 Madhu wrote: > * Kenneth Tilton <4af5624a$0$31273$607ed4bc(a)cv.net> : > Wrote on Sat, 07 Nov 2009 07:04:30 -0500: > > | There's no way to funcall a setter! FUNCTION does not take variables! > > So create a funcallable from the `setter's' name and funcall it! Here's > an implementation that even compiles the setter and caches it! > > (defvar *setter-cache* (make-hash-table :test #'eq)) > > (defun find-or-make-setter (accessor-symbol > &optional (accessor-cache *setter-cache*)) > (check-type accessor-symbol symbol) > (check-type accessor-cache hash-table) > (or (gethash accessor-symbol accessor-cache) > (setf (gethash accessor-symbol accessor-cache) > (multiple-value-bind > (vars vals store-vars writer-form reader-form) > (get-setf-expansion (list accessor-symbol 'object)) > (declare (ignore reader-form)) > ;;(warn "computing ~A." accessor-symbol) > (let* ((bindings > (nconc > (pairlis vars (mapcar 'list vals)) > (pairlis store-vars (list '(new-value))))) > (form `(lambda (new-value object) > (let ,bindings ,writer-form)))) > (compile nil form)))))) "compile"? Calm down! kt
|
Next
|
Last
Pages: 1 2 Prev: How to set the value? Next: Remembering information during compilation |