Schemer
Schemer

Reputation: 1665

Scheme pattern matching

I have written the following syntax rule:

(define-syntax match-rewriter  
  (syntax-rules ()
    ((_ (patt body) ...)
     (λ (x) (match x (patt body) ... (_ x))))))

which is essentially match-lambda except that it returns its argument if no match is found rather than throwing an exception.

Now I want to write a function, let_as_lambda, that will take strings of source code as input and rewrite the let statements as the new let_as_lambda function. This is what I have:

(define let_as_lambda  
  (match-rewriter (`(let((,<var> ,<val>)) ... ,<expressions>)
                   `((lambda (,<var> ...) ,<expressions>) ,<val> ...))))

It is clearly wrong as:

(let_as_lambda '(let((x 3)) (+ x 2)))

returns:

'((λ ((x) ...) (+ x 2)) (3) ...)

still showing the ellipses and with the "3" in parentheses. I believe my problem is that I don't understand the proper usage of the symbols `, ., and , in pattern matching.

If someone could show me the correct way to do this it would be greatly appreciated.

Thanks.

Upvotes: 0

Views: 754

Answers (1)

Eli Barzilay
Eli Barzilay

Reputation: 29546

You're probably confused because you use two different pattern matching tools. The first is what you get with syntax-rules and the second is match. They seem close enough but there are some important differences -- and in this case, the main problem is that unlike syntax-rules, you cannot use ... in quasi-quoted results of a match. So to deal with lists of matched values you need to use unquote-splicing (or ,@) and other functions like map etc. For example, compare the results of these two expressions:

(match '(1 2 3) [`(,x ...) `(foo ,x ...)])
(match '(1 2 3) [`(,x ...) `(foo ,@x)])

As a side note, it would be nice if the usual quasi-quote would do what you want, but for a complete solution it needs to be possible with simple functions too -- and that complicates the whole thing (uses of ... will need to translate to apply).

Upvotes: 2

Related Questions