Force evaluation of recursive call in pattern match
I am using match-lambda to rewrite certain functions in terms of more basic ones. Here is an example that takes strings representing input code for let* calls and returns them as strings converted to nested unary lets:
(define let*→nested-unary-lets
(match-lambda
(`(let* (()) ,<exprs>)
`(let () ,<exprs>))
(`(let* ((,<var> ,<val>)) ,<exprs>)
`(let ((,<var> ,<val>)) (let () ,<exprs>)))
(`(let* ((,<var> ,<val>) . ,<clauses>) ,<exprs>)
`(let ((,<var> ,<val>)) (let*→nested-unary-lets '(let* (,@<clauses>) ,<exprs>))))))
Here is an example of a call to let*→nested-unary-lets:
(let*→nested-unary-lets '(let* ((a 1) (b (+ a 1)) (c (+ a b))) (displayln c)))
'(let ((a 1))
(let*→nested-unary-lets
'(let* ((b (+ a 1)) (c (+ a b)))
(displayln c))))
I 开发者_如何学Pythonwas wondering if there is any way to force the evaluation of the recursive call to let*→nested-unary-lets so that the output string contains only nested lets and requries no further evaluation.
Thanks.
You are already using quasiquoting to output your answer in the recursive case, so just add a comma (,
) before the recursive call to let*->nested-unary-lets
(like the ones before <var>
and <val>
) so it is evaluated immediately. The ,
in quasiquotes can splice in the result of any expression, not just variables. The line:
`(let ((,<var> ,<val>)) (let*→nested-unary-lets '(let* (,@<clauses>) ,<exprs>)))
has some other problems as well: in order for the ,@
to work, the '
before the inner let*
needs to be `
. Here is the version I suggest:
`(let ((,<var> ,<val>)) ,(let*→nested-unary-lets `(let* ,<clauses> . ,<exprs>)))
That requires that the match for <exprs>
be changed to . ,<exprs>
to allow more than one.
精彩评论