方案:映射let和set!到列表

时间:2011-03-14 06:34:38

标签: mapping scheme syntax-error racket

我正在尝试映射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>))))

感谢任何建议。

感谢。

2 个答案:

答案 0 :(得分:1)

你做不到。如果不使用eval,通常不允许变量名称是动态的(基本上不是符号文字的任何东西)。这是设计的。

如果您的变量名称确实是文字,并且您只想要一次绑定多个变量,则可以使用let-valuesSRFI 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是嵌套的。其次,我们构建代码,而不是试图运行它。