Scheme: mapping let and set! onto lists
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 origi开发者_JAVA百科nal 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.
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.
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 let
s are nested. Second, we're constructing code, not trying to run it.
精彩评论