2

I am trying to map let and set! onto lists something like this:

(map (lambda (x) (let ((x #f)))) <list>)

and

(map set! <list1> <list2>)

But, of course, neither is working.

Is there a way to do this? Any advice is appreciated.

Thanks.


The real problem is that I am trying to find a way to pattern match letrec. I need to be able to pattern match:

(letrec ((var val) ...) expr0 expr1 ...)

and convert it -- using match-lambda -- to an equivalent call using only let and set! This is the template I am trying to emulate:

(letrec ((var val) ...) expr0 expr1 ...)

==>

(let ((var #f) ...)
(let ((temp val) ...)
(set! var temp) ...
(let () expr0 expr1 ...)))

The problem is translating this into syntax that match-lambda accepts. Here is what I was working on, assuming there was a way to accomplish the original question:

(match-rewriter (`(letrec((,<var> ,<val>) ...) ,<expr> ...)
                   `((map (λ (x) (let ((x #f)))) ,<var>)
                      (let ((temp ,<val>)))
                        (map set! ,<var> temp)
                        (let () ,@<expr>))))

Any advice is appreciated.

Thanks.

Schemer
  • 1,635
  • 4
  • 19
  • 39

2 Answers2

1

You cannot do that. Short of using eval, variable names are generally not allowed to be dynamic (basically anything that isn't a symbol literal). This is by design.

If your variable names really are literals, and you just want a way to bind multiple variables at once, you can use let-values (SRFI 11) or extended let (SRFI 71).


Edit to match OP's edit: What you want to do sounds like the letrec definition given here. However, that macro uses syntax-case, not match-lambda or the like. You may be able to use it as a starting point, though.

C. K. Young
  • 219,335
  • 46
  • 382
  • 435
  • @Schemer: You mean you want to do something like this? http://www.scheme.com/tspl3/syntax.html#./syntax:s39 (see the `letrec` definition in the example). But, that uses `syntax-case`, not `match-rewriter`. – C. K. Young Mar 14 '11 at 18:15
  • Unfortunately I am constrained to use match-lambda. I need to write a rule letrec→let&set! that pattern matches calls to letrec using match-lambda and returns an equivalent rule that uses only let and set. The problem seems to be that the match-lambda syntax just isn't as powerful as define-syntax. – Schemer Mar 14 '11 at 21:23
0

This is the code you want:

(define (rewrite-letrec l)
  (match l
    [(list 'letrec (list (list vars rhss) ...)
           exprs ...)
     (let ([tmps (map (λ _ (gensym)) vars)])
       `(let (,(map (λ (v) `(,v #f)) vars))
          (let (,(map (λ (tmp rhs) `(,tmp ,rhs)) tmps rhss))
            ,@(map (λ (v t) `(set! ,v ,t)))
            (let () ,@exprs))))]))

There are several differences here. One is that the lets are nested. Second, we're constructing code, not trying to run it.

Sam Tobin-Hochstadt
  • 4,983
  • 1
  • 21
  • 43