[plt-scheme] How to write context-aware macros?
On Fri, Oct 23, 2009 at 5:52 AM, Noel Welsh <noelwelsh at gmail.com> wrote:
> On Fri, Oct 23, 2009 at 6:52 AM, Simon Haines <con.amalgamate at gmail.com> wrote:
>> I'd like some advice for implementing related macros that share some
>> kind of context. The example I'd like to emulate is (in clojure):
>> http://github.com/ragnard/redis-clojure/blob/master/examples/demo.clj
>
> Probably the simplest way to do this is using syntax parameters. They
> work just about the same as normal parameters.
>
> Note that in the clojure example, only the redis/with-server form need
> be a macro. The others could be implemented as normal functions if the
> with-server form were to expand into a call to parameterize, for
> example.
That seems like the easiest thing. For what Noel described, maybe
something like this:
#!r6rs
(import (rnrs)
(srfi :39)
(srfi :48))
(define redis/address (make-parameter "Undefined"))
(define (redis/info)
(display (format "redis/info: ~a~%" (redis/address))))
(define (redis/get key)
(display (format "redis/get: ~a Key: ~a~%" (redis/address) key)))
(define (redis/set key val)
(display (format "redis/set: ~a Key: ~a Val: ~a~%" (redis/address) key val)))
(redis/info)
(parameterize ((redis/address "127.0.0.1"))
(redis/info))
(define-syntax redis/with-server
(syntax-rules (:host)
((_ (:host address) body ...)
(parameterize ((redis/address address))
body ...))))
(redis/with-server
(:host "10.0.0.1")
(redis/info)
(redis/get "foo"))
I wonder what is the pattern though for the "uninitialized" state of
functions that rely on a parameter. Things like display are easy as
they default to something, but for the redis examples they probably
should generate an error.