From: Andy Wingo <wingo@pobox.com>
To: guile-user <guile-user@gnu.org>
Subject: with-accessors macro
Date: Tue, 22 Apr 2008 11:03:46 +0200 [thread overview]
Message-ID: <m3fxtetg5p.fsf@pobox.com> (raw)
Heya hackers,
Use GOOPS? Think slot-ref is ugly? Don't like the permeation of
accessors into the global namespace? `with-accessors' is for you!
Use example:
(define (scale-opacity w ratio)
(with-accessors (opacity)
(set! (opacity w)
(* (opacity w) ratio))))
Definition:
(define-macro (with-accessors names . body)
`(let (,@(map (lambda (name)
`(,name ,(make-procedure-with-setter
(lambda (x) (slot-ref x name))
(lambda (x y) (slot-set! x name y)))))
names))
,@body))
It would be nice to actually use accessors, so that we can get their
compilation characteristics. This version would probably work:
(define (fetch-g-n-s name class)
(assq name (slot-ref class 'getters-n-setters)))
(define-class <lazy-getter> (<generic>))
(define-method (no-applicable-method (gf <lazy-getter>) args)
(if (= (length args) 1)
(let* ((class (class-of (car args)))
(g-n-s (fetch-g-n-s (generic-function-name gf) class)))
(if g-n-s
(begin
(add-method! gf (compute-getter-method class g-n-s))
(gf (car args)))
(next-method)))
(next-method)))
(define-class <lazy-setter> (<generic>)
(slot-name #:init-keyword #:slot-name))
(define-method (no-applicable-method (gf <lazy-setter>) args)
(if (= (length args) 2)
(let* ((class (class-of (car args)))
(g-n-s (fetch-g-n-s (slot-ref gf 'slot-name) class)))
(if g-n-s
(begin
(add-method! gf (compute-setter-method class g-n-s))
(gf (car args) (cadr args)))
(next-method)))
(next-method)))
(define-class <lazy-accessor> (<accessor> <lazy-getter>))
(define (make-lazy-accessor name)
(make <lazy-accessor>
#:name name
#:setter (make <lazy-setter>
#:name (symbol-append 'setter: name)
#:slot-name name)))
(define-macro (with-accessors names . body)
`(let (,@(map (lambda (name)
`(,name ,(make-accessor name)))
names))
,@body))
But GOOPS doesn't do subclasses of <generic> yet. One day that code will
magically spring to utility.
Happy hacking,
Andy
--
http://wingolog.org/
next reply other threads:[~2008-04-22 9:03 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-04-22 9:03 Andy Wingo [this message]
2008-04-23 21:50 ` with-accessors macro Ludovic Courtès
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/guile/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=m3fxtetg5p.fsf@pobox.com \
--to=wingo@pobox.com \
--cc=guile-user@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).