Here's the code for bind, return, getstore, and setstore (define (bind a b) (lambda (store) (type-case Any*Store (a store) [a*s (x newstore) ((b x) newstore)]))) (define (return a) (lambda (store) (a*s a store))) (define getstore (lambda (store) (a*s store store))) (define (setstore newstore) (lambda (dc) (a*s #f newstore))) ... and here's the "sdo" macro. (define-syntax (sdo stx) (letrec ([popclause (lambda (clause) (syntax-case clause (<-) [(a <- rhs) (list #'a #'rhs)] [rhs (list #'bogus #'rhs)]))] [rearrange (lambda (lopops) (if (null? (cdr lopops)) (cadar lopops) #`(bind #,(cadar lopops) (lambda (#,(caar lopops)) #,(rearrange (cdr lopops))))))]) (syntax-case stx () [(_ clause ...) (let* ([popped (map popclause (syntax->list #'(clause ...)))]) (rearrange popped))]))) Here's a simple test case: (test ((sdo (s <- getstore) (p <- (return (+ s 1))) (dc <- (setstore p)) (dc2 <- (return 4))) 16) (a*s 4 17)) Note that these won't work until you define Any*Store. Exercise: Develop the monadic doMap method, that accepts a monadic function and a list and returns the result of mapping the function across the arguments.