Scheme macros: an interactive Tutorial

Fork me on GitHub
(lambda (x) x)
(define f (lambda (x) x)) f
((lambda (x) x) (+ 3 4))
(let ((x (+ 3 4))) x)
((lambda (y) (* y y)) (+ 3 4))
(let ((y (+ 3 4))) (* y y))
(eval '(+ 3 4))
(expand '(let ((y (+ 3 4))) (* y y)))
(print-gensym #f)
(expand '(let ((y (+ 3 4))) (* y y)))
(print-gensym 'pretty/suffix)
(expand '(let ((y (+ 3 4))) (* y y)))
(expand '((lambda (y) (* y y)) (+ 3 4)))
(let ((adj 'little)) (list 'Mary 'had 'a adj 'lamb))
(let ((adj 'little)) `(Mary had a ,adj lamb))
(let ((op '+)) `(,op 3 4))
(eval (let ((op '+)) `(,op 3 4)))
(eval (let ((op '*)) `(,op 3 4)))
(let ((var 'x)) `(let ((,var 3)) (* ,var ,var)))
(let ((var 'x) (body '(x 4))) `(let ((,var 3)) ,body))
(let ((var (gensym "x")) (body '(x 4))) `(let ((,var 3)) ,body))
(let ((var (gensym "x")) (body '(x 4))) `(let ((,var 3)) ,body))
(let ((var (gensym "x")) (body '(x 4))) `(let ((,var 3)) ,body))
(define my-proc (lambda (x) (* x x))) (my-proc 3)
(define (my-proc x) (* x x)) (my-proc 3)
(define-syntax my-let (syntax-rules () [(my-let ((id e)) body) ((lambda (id) body) e)]))
(my-let ((y (+ 3 4))) (* y y))
(expand '(my-let ((y (+ 3 4))) (* y y)))
(define-syntax my-let (syntax-rules () [(my-let ((id e)) body) ((my-lambda (id) body) e)]))
(expand '(my-let ((y (+ 3 4))) (* y y)))
(let* ((x (+ 4 5)) (y (* x x)) (y (+ x y))) (* x y))
(let ((x (+ 4 5))) (let ((y (* x x))) (let ((y (+ x y))) (* x y))))
(expand '(let* ((x (+ 4 5)) (y (* x x)) (y (+ x y))) (* x y)))
(define-syntax my-let* (syntax-rules () [(my-let* () body) body] [(my-let* ((id e) (id* e*) ...) body) (let ((id e)) (my-let* ((id* e*) ...) body))]))
(let* ((x (+ 4 5)) (y (* x x)) (y (+ x y))) (* x y))
(my-let* ((x (+ 4 5)) (y (* x x)) (y (+ x y))) (* x y))
(expand '(my-let* ((x (+ 4 5)) (y (* x x)) (y (+ x y))) (* x y)))

References