From: Madhu on 7 Nov 2009 19:57 * Kenneth Tilton <4af59568$0$22536$607ed4bc(a)cv.net> : Wrote on Sat, 07 Nov 2009 10:42:32 -0500: | Pascal J. Bourguignon wrote: |> Kenneth Tilton <kentilton(a)gmail.com> writes: |> |>> There's no way to funcall a setter! FUNCTION does not take variables! | | Ah, silly me, I looked at fdefinition but didn't Get It. The point of going through get-setf-expansion is because FDEFINITION is not guranteed to work on DEFSTRUCT-defined accessors: See <http://groups.google.com/group/comp.lang.lisp/msg/08ffb56f97156c5c> -- Madhu
From: Ron Garret on 7 Nov 2009 20:49 In article <m3d43ujxy7.fsf(a)moon.robolove.meer.net>, Madhu <enometh(a)meer.net> 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)))))) > > > ;; Example Use > (defstruct foo a) > (defvar $a (make-foo)) > (funcall (find-or-make-setter 'foo-a) 10 $a) ; => #S(FOO :A 10) > > -- > Madhu Note that this fails for accessors that take more than one argument: ? (find-or-make-setter 'nth) ;Compiler warnings : ; In an anonymous lambda form: In the call to CCL::%SETNTH with arguments (#:G270 #:G269), ; 2 arguments were provided, but at least 3 are required ; by the current global definition of CCL::%SETNTH #<Anonymous Function #x300041F5D2DF> ? (funcall * '(1 2 3) 1 2) > Error: Too many arguments in call to #<Anonymous Function #x300041F5D2DF>: > 3 arguments provided, at most 2 accepted. AFAIK, there is no way to fix this in portable CL because there is no potable way to query a function for its argument list, and so no portable way to construct a complete accessor form from a naked accessor function. rg
From: Madhu on 7 Nov 2009 21:03 * Ron Garret <rNOSPAMon-66A018.17493007112009(a)news.albasani.net> : Wrote on Sat, 07 Nov 2009 17:49:31 -0800: | | Note that this fails for accessors that take more than one argument: The code I exhibited to Ken Tilton was expected to work only for accessors of one argument. Sorry if I did not make that explicit. HTH -- Madhu
First
|
Prev
|
Pages: 1 2 Prev: How to set the value? Next: Remembering information during compilation |