This was an edit to an earlier post. I am reposting it because I think the original isn't getting any more views since I accepted a partial answer already.
I have written a function match-rewriter which is just match-lambda except that it returns its argument if no match is found.
Using match rewriter I want to be able to write rules that can be passed to another function rewrite which is this:
#| (rewrite rule s) repeatedly calls unary function 'rule' on every "part"
of s-expr s, in unspecified order, replacing each part with result of rule,
until calling rule makes no more changes to any part.
Parts are s, elements of s, and (recursively) parts of the elements of s. (define (rewrite rule s) |#
(let* ([with-subparts-rewritten
(if (list? s) (map (λ (element) (rewrite rule element)) s) s)]
[with-also-rule-self (rule with-subparts-rewritten)])
(if (equal? with-also-rule-self with-subparts-rewritten)
with-also-rule-self
(rewrite rule with-also-rule-self))))
Here is an example of proper usage:
(define arithmetic
(match-rewriter (`(+ ,a ,b) (+ a b))
(`(* ,a ,b) (* a b))
))
(rewrite arithmetic '(+ (* 2 (+ 3 4)) 5))
==>
19
Now I have written:
(define let→λ&call
(match-rewriter (`(let ((,<var> ,<val>) . (,<vars> ,<vals>)) ,<expr> . ,<exprs>)
`((λ (,<var> . ,<vars>) ,<expr> . ,<exprs>) ,<val> . ,<vals>))))
to implement lets as lambda calls, but this is how it is behaving:
(rewrite let→λ&call '(let((x 1) (y 2) (z 3)) (displayln x) (displayln y) (displayln z)))
'((λ (x y 2)
(displayln x)
(displayln y)
(displayln z))
1
z
3)
which, I have to say, really has me stumped. Strangely this call:
(rewrite let→λ&call '(let((w 0) (x 1) (y 2) (z 3)) (displayln w) (displayln x) (displayln y) (displayln z)))
'(let ((w 0) (x 1) (y 2) (z 3))
(displayln w)
(displayln x)
(displayln y)
(displayln z))
Just returns its argument, meaning that match-rewriter did not find a match for this pattern.
Any advice is appreciated.
Thanks.