I am trying to re-write let*
hygiene macro, I have it as normal macro and I would like to have it as hygiene macro if it's possible. I don't have too much experience with this macro types. So I would really appreciate help. Also my another representation of working let*
macro is not working, with same error as hygiene macro.
Working let*
(define-macro let*1
(lambda (assgn . body)
(let ((loop (gensym))
(lst (gensym)))
(let loop ((lst assgn))
(if (null? lst)
`(begin ,@body)
`((lambda (,(caar lst))
,(loop (cdr lst)))
,(cadar lst)))))))
Not working hygiene let*
-> error: lambda: not an identifier in: (caar lst)
(define-syntax let*2
(syntax-rules ()
((let*2 (set ...) body ...)
(let loop ((lst '(set ...)))
(if (null? lst)
body ...
((lambda ((caar lst))
(loop (cdr lst)))
(cadar lst) 1))))))
Not working let*
, but also having same error as the second one.
(define-macro let*3
(lambda (assgn . body)
(let ((loop (gensym))
(lst (gensym)))
`(let ,loop ((,lst assgn))
(if (null? ,lst)
(begin ,@body)
((lambda ((caar ,lst))
(,loop (cdr ,lst)))
(cadar ,lst)))))))
Apologize for little confusing question, I am stucked with this problem for some time already and caffeine isn't usefull anymore.
Some tests (I picked symbol names to test symbol-capture(I know I didn't had to)):
(let*1 ((body 10)
(lst (+ body 1)))
(list body lst))
(let*2 ((body 10)
(lst (+ body 1)))
(list body lst))
(let*3 ((body 10)
(lst (+ body 1)))
(list body lst))
Edit: Question is answered, added solution without using let by editing Lief Andersen code
(define-syntax let*
(syntax-rules ()
((let*2 ([x1 e1][x2 e2] ...)body ...)
((lambda (x1)
(let* ([x2 e2] ...)
body ...))
e1))))
Your second one is the closest. A hygenic let*
macro can be written with define-syntax-rule
. (If you're writing this in an implementation of scheme rather than racket, you can also just compose define-syntax
and syntax-rule
for the same effect.)
(define-syntax-rule (let* ([x1 e1]
[x2 e2] ...)
body ...)
(let ([x1 e1])
(let* ([x2 e2] ...)
body ...))
And if you're feeling really pedantic, you can make a hygenic let
macro:
(define-syntax-rule (let ([x e] ...)
body ...)
((lambda (x ...) body ...) e ...))