Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Monadic-style R5RS macros

9 views
Skip to first unread message

Andre

unread,
Oct 10, 2003, 9:12:27 PM10/10/03
to
I have put together a few definitions that allows one to
write composable R5RS macros in monadic style. They rely on
Oleg Kiselyov's macro-level ??!apply (see http://okmij.org/ftp/).

The main advantage of this style is that it hides the
explicit continuations that would normally be required for
composable macros. Also, some people may find the do#-syntax
easier.

Just as in lazy languages, the monadic style is used here to
control evaluation order. This is done with the do#-notation,
which can be thought of as a sequential let* at the macro level.

Examples:

(define-monadic-syntax cons# ()
[(cons# h t) (return# (h . t))])

(define-monadic-syntax append# ()
[(append# () y) (return# y)]
[(append# (h . t) y) (do# ((z (append# t y)))
(cons# h (??! z)))])

(define-monadic-syntax reverse# ()
[(reverse# ()) (return# ())]
[(reverse# (h . t)) (do# ((x (reverse# t)))
(append# (??! x) (h)))])

(run# (reverse# (1 2 3 5 list)))

;==> (5 3 2 1)

(define-monadic-syntax compose-rev# ()
[(compost# m1 m2) (do# ((x (reverse# m1))
(y (reverse# m2)))
(append# (??! x) (??! y)))])

(run# (compose-rev# (1 2 list) (3 7 9)))

;==> (2 1 9 7 3)

Andre van Tonder


Code below:

;=============================================================
; Definitions for monadic-style R5RS macros:
; By Andre van Tonder

; Relies on Oleg Kiselyov's macro-level ??!lambda and ??!apply
; at http://okmij.org/ftp/

(define-syntax define-monadic-syntax
(syntax-rules ()
((define-monadic-syntax name lits
[(_ arg ...) (form . args)] ...)
(define-syntax name
(syntax-rules lits
[(_ k arg ...) (form k . args)] ...)))))

(define-syntax return#
(syntax-rules ()
[(return# k exp) (??!apply k exp)]))

(define-syntax do#
(syntax-rules ()
[(do# k ((x (form1 . args1))) (form2 . args2))
(form1 (??!lambda (x) (form2 k . args2)) . args1)]
[(do# k (bind1 bind2 ...) body)
(do# k (bind1) (do# (bind2 ...) body))]))

(define-syntax run#
(syntax-rules ()
[(run# (f . args))
(f (??!lambda (x) (??! x)) . args)]))

;==============================================================
; Some tests:

(define-monadic-syntax cons# ()
[(cons# h t) (return# (h . t))])

(define-monadic-syntax append# ()
[(append# () y) (return# y)]
[(append# (h . t) y) (do# ((z (append# t y)))
(cons# h (??! z)))])

(run# (append# (list 1 2) (4 5 7)))

;==> (1 2 4 5 7)

(define-monadic-syntax reverse# ()
[(reverse# ()) (return# ())]
[(reverse# (h . t)) (do# ((x (reverse# t)))
(append# (??! x) (h)))])

(run# (reverse# (1 2 3 5 list)))

;==> (5 3 2 1)

(define-monadic-syntax compose-rev# ()
[(compose-rev# m1 m2) (do# ((x (reverse# m1))
(y (reverse# m2)))
(append# (??! x) (??! y)))])

(run# (compose-rev# (1 2 list) (3 7 9)))

;==> (2 1 9 7 3)

ol...@pobox.com

unread,
Oct 13, 2003, 5:10:25 PM10/13/03
to
andreu...@yahoo.com (Andre) wrote in message news:<22df0133.03101...@posting.google.com>...

> I have put together a few definitions that allows one to
> write composable R5RS macros in monadic style.

That is very neat!

> Just as in lazy languages, the monadic style is used here to
> control evaluation order. This is done with the do#-notation,
> which can be thought of as a sequential let* at the macro level.

Indeed, both monads and CPS provide a sublanguage that is indifferent to
the evaluation order (call-by-name or call-by-value). That's why
monads are so useful in a lazy language, and considerably less useful
in an eager language (as noted by Moggi and Filinski).

It seems there is another interpretation of your construction:
A-normal form. Your macros follow the grammar of the A-normal
form. The do# notation is a (particular) translation from an A-normal
form to CPS.

0 new messages