提问人:Xiaoyong Guo 提问时间:1/8/2022 最后编辑:alinsoarXiaoyong Guo 更新时间:1/9/2022 访问量:226
什么是 MIT Scheme 中的分类器和转换器?
What is Classifier and Transformer in MIT Scheme?
问:
在下面的方案代码中,做右折。当我尝试使用 mit 方案运行时。我遇到了以下错误:accumulate
Transformer may not be used as an expression: #[classifier-item 13]
Classifier may not be used as an expression: #[classifier-item 12]
我在谷歌上搜索,但没有找到有用的信息。它与宏有关吗?
; This function is copied from SICP chapter 2
(define (accumulate op initial sequence)
(if (null? sequence)
initial
(op (car sequence)
(accumulate op initial (cdr sequence)))))
; works as expected
(accumulate
(lambda (x y) (or x y)) ; replace or with and also works
#f
'(#t #f #t #f #f)
))
; does not work
; error: Classifier may not be used as an expression: #[classifier-item 12]
(accumulate
or
#f
'(#t #f #t #f #f)
))
; does not work
; error: Transformer may not be used as an expression: #[classifier-item 13]
(accumulate
and
#f
'(#t #f #t #f #f)
))
答:
是的,它与宏/特殊形式有关,例如 和 .and
or
你可以简单地通过将它们包装成 lambda 来使它工作,结果将是正确的,但当然不会有任何短路。是一个函数,函数接收已经计算过的参数。(accumulate (lambda (a b) (or a b)) ...)
op
要么隐藏 lambdas() 后面的参数并根据需要手动计算它们,要么为每个宏定义每个特定版本,例如(lambda () ...)
op
(define (accumulate-or initial sequence)
(if (null? sequence)
initial
(or (car sequence)
(accumulate-or initial (cdr sequence)))))
在调用 之前,这里仍将进行全面评估,但至少即使在结果已知之后也不会完成它。sequence
accumulate-or
accumulate-or
如果包含一些繁重的计算结果,你想避免这些结果,以防万一,可以考虑使用“惰性序列”。sequence
评论
宏可以用某些语言传递,但不能在 Scheme 和 Common Lisp 中传递。原因是宏应该能够提前扩展。例如。
(define (cmp a b)
(cond ((< a b) -1)
((> a b) 1)
(else 0)))
现在,编译 Scheme 将递归地扩展每个节点,将其替换为扩展,直到它没有变化:
(define (cmp a b)
(if (< a b)
(begin -1)
(cond ((> a b) 1)
(else 0))))
(define (cmp a b)
(if (< a b)
-1
(cond ((> a b) 1)
(else 0))))
(define (cmp a b)
(if (< a b)
-1
(if (> a b)
(begin 1)
(cond (else 0)))))
(define (cmp a b)
(if (< a b)
-1
(if (> a b)
1
(cond (else 0)))))
; end result
(define (cmp a b)
(if (< a b)
-1
(if (> a b)
1
0)))
从这一点来看,它根本不需要存在于底层语言中,因为你永远不会使用它,但必须如何实现它才能工作:cond
(define (test syntax a b)
(syntax a b))
(test or #f #t)
要做到这一点,底层语言需要知道扩展后的内容,因为需要绑定,然后才能进行转换。但是,当代码运行时,宏扩展已经发生,在大多数实现中,您会看到一些指示未绑定变量的内容。似乎 MIT Scheme 添加了对顶级语法语法的错误检查,如果您不覆盖它,它将触发错误。例如。如果添加此内容,您将不会看到任何问题:or
syntax
or
or
(定义(或 b)(如果 a a b)) (定义(和 b)(如果 a b #f))
现在,在这些行之后,任何对 and 的引用都不是语法,而是这些过程。Scheme 中没有保留字,所以如果你做了一些疯狂的事情,比如定义,你就不能在该范围的其余部分使用它:and
or
define
(define define display) ; defiens define as a top level variable
(define define) ; prints the representation of the function display
(define test 10) ; fail since test is an undefined variable so it cannot be displayed.
我创建了一个带有宏的解释 lisp,它实际上可以传递,但它不是很有用,优化的机会大大降低。
评论
or
and