This is the mail archive of the guile@sourceware.cygnus.com mailing list for the Guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

generalized set!



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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]