[plt-scheme] How to write context-aware macros?

From: Grant Rettke (grettke at acm.org)
Date: Fri Oct 23 10:43:03 EDT 2009

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.


Posted on the users mailing list.