Я пытаюсь переписать let*
макрос гигиены, он у меня как обычный макрос, и я бы хотел, чтобы он был макросом гигиены, если это возможно. У меня нет большого опыта работы с этими типами макросов. Так что я был бы очень признателен за помощь. Также мое другое представление о рабочем макросе let*
не работает с той же ошибкой, что и макрос гигиены.
Работает 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)))))))
Не работает гигиена let*
-> ошибка: лямбда: не идентификатор в: (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))))))
Не работает let*
, но также имеет ту же ошибку, что и второй.
(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)))))))
Прошу прощения за небольшой сбивающий с толку вопрос, я уже какое-то время застрял с этой проблемой, и кофеин больше бесполезен.
Некоторые тесты (я выбрал имена символов для проверки захвата символов (я знаю, что не должен был)):
(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))
Изменить: На вопрос дан ответ, добавлено решение без использования let путем редактирования кода Lief Andersen
(define-syntax let*
(syntax-rules ()
((let*2 ([x1 e1][x2 e2] ...)body ...)
((lambda (x1)
(let* ([x2 e2] ...)
body ...))
e1))))