This is the mail archive of the
guile@sourceware.cygnus.com
mailing list for the Guile project.
generalized set!
- To: guile at sourceware dot cygnus dot com
- Subject: generalized set!
- From: Michael Livshin <mlivshin at bigfoot dot com>
- Date: 04 Nov 1999 18:41:20 +0200
- Organization: who? me?
I have a couple of questions about the thing:
1. why the obvious candidates like `vector-ref', `car' etc. are not
`procedure-with-setter's? if the reason is "because nobody did it yet",
then I'm willing to (I'm in need of a brainless Guile project ;).
2. what is the preferred convention of placing the `value' argument in
a setter invocation? is it first (like in `array-set!') or last (like
in `vector-set!')? maybe it makes sense to have an additional property
in `procedure-with-setter' objects that indicates this?
the reason I've started to mess with it is a very very neat hack I saw
in comp.lang.lisp and decided to ape. it assumes that the value
argument goes last.
--------------->8 cut 8<------------------------------------------
(define-module (locatives))
(export-syntax locative)
(export locative? contents set-contents!)
;; ugh, pretend you don't see this:
(export %make-locative)
(define l-rtd (make-record-type 'locative '(getter setter source)
(lambda (o p)
(display "#<locative for " p)
(display (l-source o) p)
(display ">" p))))
(define %make-locative (record-constructor l-rtd))
(define l-getter (record-accessor l-rtd 'getter))
(define l-setter (record-accessor l-rtd 'setter))
(define l-source (record-accessor l-rtd 'source))
(define locative? (record-predicate l-rtd))
(define (contents l)
((l-getter l)))
(define (set-contents! l v)
((l-setter l) v))
(defmacro locative (src)
(cond
((symbol? src)
`(%make-locative
(lambda () ,src)
(lambda (v) (set! ,src v))
',src))
((pair? src)
(let ((proc (eval (car src))))
(if (not (procedure-with-setter? proc))
(throw 'non-locateable src))
(let ((setter (setter proc))
(args (cdr src)))
`(%make-locative
(lambda () ,src)
(lambda (v) (,setter ,@args v))
',src))))
(else
(throw 'non-locateable src))))