【问题标题】:Adding Macros in Scheme在 Scheme 中添加宏
【发布时间】:2016-10-19 09:10:32
【问题描述】:

对于一个大学项目,我们正在制定学习计划,但是我们却陷入了一项知识匮乏的艰巨任务。我们被赋予了某些函数,例如“'let”、“'cond”、“and'”等,并被要求添加宏。

(define eval
  (λ (e env)
    (cond ((symbol? e) (lookup-var e env))
          ((not (list? e)) e) ; non-list non-symbol is self evaluatory
          ;; special forms go here:
          ((equal? (car e) 'λ)      ; (λ VARS BODY)
           (let ((vars (cadr e)) (body (caddr e)))
             (list '%closure vars body env)))
          ((equal? (car e) 'if)
           (eval_ (if (eval_ (cadr e) env) (caddr e) (cadddr e)) env))
          ((equal? (car e) 'quote) (cadr e))
          ;; Add More Macros Here:
          ;; ((equal? (car e) 'let) xxx)
          ;;((equal? (car e) 'cond) xxx)
          ;;((equal? (car e) 'and) xxx)
          ;((equal? (car e) 'or) xxx)
          (else (let ((eeoe (map (λ (e0) (eval_ e0 env)) e)))
                  (apply_ (car eeoe) (cdr eeoe)))))))

所以基本上我们被要求填写空白,';;' cmets是。 我尝试做'cond部分并得到了这个

((equal? (car e) 'cond)
           (env (cdr e) env))

但我不知道它是否正确(对方案知之甚少)。任何帮助弄清楚这一点将不胜感激。谢谢。

【问题讨论】:

    标签: macros scheme lisp


    【解决方案1】:

    您添加的不是真正的宏,而是特殊形式。如果您知道let 只是匿名函数调用的语法糖。例如。

    (let ((a expr1) (b expr2)) body ...)
    

    如果您更改和评估,您的评估器已经支持:

    ((lambda (a b) body ...) expr1 expr2)
    

    为了让您继续前进,let 的工作方式如下:

    (let ((bindings (cadr e))
          (body (cddr e)))
      (eval_ `((lambda ,(map car bindings) ,@body) ,@(map cadr bindings))))
    

    现在是真正的宏,您将引入一种新类型的%closure,这样每当您发现它作为运算符时,您就绑定符号而不是它们的求值,在其上运行求值器,就好像它是一个函数一样,然后执行_eval on结果。然后,无需实现condlet,您只需添加一个函数即可将其重写为您已经支持的内容。因此,您可以像这样制作let

    ((lambda (let)
       (let ((a expr1) (b expr2))
         (cons a b)))
      (~ (bindings . body) `((lambda ,(map car bindings) ,@body) ,@(map cadr bindings))))
    

    它假设你有 quasiquote 和 map,但如果没有这些,它可以很容易地用更详细的代码来实现。 ~ 只是随机选择作为λ 的宏版本。在评估时,它可能会生成一个 %mclosure 结构,您需要特别处理它,以便不评估其参数,而是评估结果。从那时起,您可以通过在引导环境中预定义%mclosure 来支持特殊形式。

    【讨论】:

      猜你喜欢
      • 2013-12-01
      • 1970-01-01
      • 2018-06-18
      • 2012-10-24
      • 2010-12-21
      • 1970-01-01
      • 1970-01-01
      • 2014-03-23
      • 1970-01-01
      相关资源
      最近更新 更多