I'm learning syntax-case macro system. This is what I have so far:
(define-syntax loop
(lambda (x)
(syntax-case x ()
[(_ (var val x ...) body)
(with-syntax ([recur (datum->syntax #'var 'recur)])
#'(let recur ((var val) x ...)
body))])))
(loop [i 0 j 10]
(if (< i 10)
(begin
(display i)
(display " ")
(display j)
(newline)
(recur (+ i 1) (- j 1)))))
The problem is the binding in let. The above code creates
[(i 0) j 10]
and when I change the code into:
(define-syntax loop
(lambda (x)
(syntax-case x ()
[(_ (var val ...) body)
(with-syntax ([recur (datum->syntax #'var 'recur)])
#'(let recur ((var val) ...)
body))])))
I get:
[(i 0) (i j) (i 10)]
I think that I need to use recursive macro, but I'm not sure how to do this with syntax-case.
EDIT: here is an explanation of loop macro in Clojure if you're not familiar with it. It works like named let with the name recur that calls the loop recursively. But the list of variables and values is a flat list instead of list of pairs.
Clojure's loop:
(loop [i 10 j 20]
(if (> i 0)
(recur (- i 1) (- j 2))))
Scheme's named let:
(let recur ((i 10)
(j 20))
(if (> i 0)
(recur (- i 1) (- j 2))))
recur. The alternating id and initial value bit without wrapping each pair in parens is the tough part; that doesn't lend itself well to syntax patterns.