0

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.

1 Answer 1

1

This pattern:

((,<var> ,<val>) . (,<vars> ,<vals>))

does not do what you want. In particular, it's equivalent to:

((,<var> ,<val>) ,<vars> ,<vals>)

I recommend that you use regular match patterns, rather than quasi-patterns, until you have a better sense of how they work. The pattern for this would be:

(list (list <var> <val>) (list <vars> <vals>) ...)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.