我正在尝试映射let并设置!在列表上这样的东西:
(map (lambda (x) (let ((x #f)))) <list>)
和
(map set! <list1> <list2>)
但是,当然,两者都没有效果。
有办法做到这一点吗?任何建议都表示赞赏。
感谢。
真正的问题是我正试图找到一种模式匹配letrec的方法。我需要能够模式匹配:
(letrec ((var val) ...) expr0 expr1 ...)
并使用match-lambda将其转换为仅使用let和set的等效调用!这是我试图模仿的模板:
(letrec ((var val) ...) expr0 expr1 ...)
==&GT;
(let ((var #f) ...)
(let ((temp val) ...)
(set! var temp) ...
(let () expr0 expr1 ...)))
问题是将其转换为match-lambda接受的语法。这是我正在研究的,假设有一种方法可以完成原始问题:
(match-rewriter (`(letrec((,<var> ,<val>) ...) ,<expr> ...)
`((map (λ (x) (let ((x #f)))) ,<var>)
(let ((temp ,<val>)))
(map set! ,<var> temp)
(let () ,@<expr>))))
感谢任何建议。
感谢。
答案 0 :(得分:1)
你做不到。如果不使用eval
,通常不允许变量名称是动态的(基本上不是符号文字的任何东西)。这是设计的。
如果您的变量名称确实是文字,并且您只想要一次绑定多个变量,则可以使用let-values
(SRFI 11)或扩展let
({{3 }})。
编辑以匹配OP的编辑:您想要做的事情听起来像SRFI 71。但是,该宏使用syntax-case
,而不是match-lambda
等。不过,您可以将它作为起点。
答案 1 :(得分:0)
这是您想要的代码:
(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))))]))
这里有几点不同。一个是let
是嵌套的。其次,我们构建代码,而不是试图运行它。