Sylwester's answer is correct, but I wanted to make a bigger point: unless your Scheme implementation doesn't provide a hygienic procedural macro system, there is no good reason to use define-macro
.
For anaphoric macros, such as the one you want to write, it's best to use syntax parameters, if you're using a Scheme implementation that supports it, such as Racket or Guile. Here's a Racket example:
#lang racket
(provide slambda self)
(require racket/stxparam srfi/31)
(define-syntax-parameter self
(lambda (stx)
(raise-syntax-error 'self "Can only be used inside slambda")))
(define-syntax slambda
(syntax-rules ()
((_ params body ...)
(rec (ohai . params)
(syntax-parameterize ((self (make-rename-transformer #'ohai)))
body ...)))))
Of course, as you can see in my example, I used rec
. In the general case where you want to make self-referential procedures, it's best to use rec
for that; you simply specify the name you want to refer to the procedure by (rather than using a hardcoded self
). Since rec
is not anaphoric, its definition is much simpler:
(define-syntax rec
(syntax-rules ()
((_ (id . params) body ...)
(rec id (lambda params body ...)))
((_ id value)
(letrec ((id value)) id))))
You would use it like this (in this case, I use recur
as the self-reference; of course, you can choose any name you like):
(define nested-length
(rec (recur x)
(cond ((null? x) 0)
((pair? x) (+ (recur (car x)) (recur (cdr x))))
(else 1))))