Я написал функцию match-rewriter
, которая по существу match-lambda
, за исключением того, что она возвращает свой аргумент, если совпадение не найдено:
(define-syntax match-rewriter
(syntax-rules ()
((_ (patt body) ...)
(λ (x) (match x (patt body) ... (_ x))))))
Теперь я хотел бы использоватьmatch-rewriter
, чтобы взять строки, представляющие исходный код для let*
, и переписать его как вложенный унарный lets
:
(define let*→nested-unary-lets
(match-rewriter (`(let*((,<var> ,<val>) ...) ,<expr1> ,<expr2> ...)
Я действительно озадачен тем, как сопоставить шаблон с этим.Мне нужно вернуть:
`(let((,<var1> ,<val1>)) let((,<var2> ,<val2>)) let((...)) ... )...) ,<expr1> . ,@<expr2>)
Но вложенность поставила меня в тупик.Любой совет приветствуется.
Хорошо, вот моя лучшая попытка:
(define let*→nested-unary-lets
(match-rewriter
(`(let* (()) ,<expr1> ,<expr2> ...)
(`(let () ,<expr1> . ,<expr2>)))
(`(let* ((,<var1> ,<val1>) (,<var2> ,<val2>) ...) ,<expr1> ,<expr2> ...)
`(let ((,<var1> ,<val1>) (let*→nested-unary-lets
'(let* ((,<var2> ,<val2>) ...) ,<expr1> . ,<expr2>)))))
))
Но вот как он себя ведет:
(пусть *→ nested-unary-let '(let * ((a 1) (b (+ a 1)) (c (+ ab))) (displayln c)))' (let ((a 1) (let * → nested-unary-let '(let * (((bc) ((+ a 1) (+ ab))) ...) (displayln c)))))
Я в замешательствепорядок аргументов в:
(let* (((b c) ((+ a 1) (+ a b)))
Мне кажется, это должно быть:
(let* ((b (+ a 1)) (c (+ a b)))
Также было бы неплохо, если бы вызов let*→nested-unary-lets
выполнялся вместопросто печатать как текст.