19

我一直在阅读 SICP(计算机程序的结构和解释),并且非常兴奋地发现了这种奇妙的特殊形式:“make-environment”,他们演示了将其与 eval 结合使用作为编写模块化代码的一种方式(摘录来自第 4.3 节“包”):

(define scientific-library
  (make-environment
   ...
   (define (square-root x)
    ...)))

然后他们展示了它是如何工作的

((eval 'square-root scientific-library) 4)

在他们的例子中,他们接着准确地展示了我想要的用法——一种优雅的、极简主义的方式在方案中做“OO”风格......他们“cons”在一起一个“type”,这实际上是什么由“make-environment”特殊形式(即 vtable)和 arg(“状态”)返回...

我非常兴奋,因为这正是我一直在寻找的一种在 Scheme 中“按符号”进行多态调度的方法,而无需编写大量显式代码或宏。

即我想创建一个“对象”,它有两个函数,我在不同的上下文中调用它们......但我不想用“car”和“cdr”来引用它们,我想同时声明并通过它们的符号名称来评估它们。

无论如何,当我读到这篇文章时,我迫不及待地想回家试试。

想象一下,当我在 PLT 计划和 Chez 计划中遇到以下情况时,我会感到失望:

> (make-environment (define x 3))
Error: invalid context for definition (define x 3).
> (make-environment)
Error: variable make-environment is not bound.

SICP 中提到的“make-environment”发生了什么?这一切看起来如此优雅,正是我想要的,但似乎任何现代 Scheme 解释器都不支持它?

理由是什么?仅仅是“make-environment”的名称不同吗?

更多信息稍后发现

我看了一下在线版本:

http://mitpress.mit.edu/sicp/full-text/book/book-ZH-28.html#%_sec_4.3

我正在读的是SICP的第一版。第二版似乎用关于非确定性编程和“amp”运算符的部分取代了对包的讨论。

4

4 回答 4

13

经过更多的挖掘,我在新闻网上发现了这个信息丰富的线程

“R5RS EVAL 和环境说明符是那些极度不喜欢一流环境并想要受限 EVAL 的人和那些在没有第二个参数即环境的情况下无法接受/理解 EVAL 的人之间的妥协。”

另外,发现了这个“解决方法”:

(define-syntax make-environment 
  (syntax-rules () 
    ((_ definition ...) 
     (let ((environment (scheme-report-environment 5))) 
       (eval '(begin definition 
                     ...) 
             environment) 
       environment)))) 


(define arctic 
  (make-environment 
    (define animal 'polarbaer))) 

(取自

然而,我最终采用了一种“消息传递”风格,有点像第一个人建议的那样——我返回一个函数列表,并有一个通用的“发送”方法来按名称调用特定函数......即类似这样

(define multiply
  (list
    (cons 'differentiate (...))
    (cons 'evaluate (lambda (args) (apply * args)))))

(define lookup
  (lambda (name dict)
    (cdr (assoc name dict))))

; Lookup the method on the object and invoke it
(define send
  (lambda (method arg args)
    ((lookup method arg) args)))

((send 'evaluate multiply) args)

我一直在进一步阅读,并且知道如果我真的想采用完全 OO 风格,那么所有的 CLOS 都可以 - 但我认为即使是上面的内容也有点过头了。

于 2009-03-09T08:52:14.690 回答
5

他们之所以这样写,是因为 MIT Scheme 实际上确实拥有一流的环境,并且大概这就是作者计划用它来教授他们的课程的(因为这本书是在 MIT 写的)。

查看http://groups.csail.mit.edu/mac/projects/scheme/

然而,我注意到 MIT 方案虽然仍在积极开发中,但缺乏真正现代方案所具有的许多特性,例如外部函数接口或 GUI 支持。您可能不想将它用于严肃的软件开发项目,至少不会单独使用它。

于 2010-01-11T22:55:40.803 回答
4

由于性能原因,Scheme 没有一流的环境。在创建 Scheme 时,由于一流的函数、延续等漂亮的东西,它并不是最快的语言。添加一流的环境会进一步削弱性能。因此,这是在早期 Scheme 时代做出的权衡。

于 2009-03-06T11:21:08.993 回答
1

经典的调度程序功能会起作用吗?我认为这与您正在寻找的相似。

(define (scientific-library f)
  (define (scientific-square-root x) (some-scientific-square-root x))
  (cond ((eq? f 'square-root) scientific-square-root)
        (else (error "no such function" f))))
(define (fast-library f)
  (define (fast-square-root x) (some-fast-square-root x))
  (cond ((eq? f 'square-root) fast-square-root)
        (else (error "no such function" f))))

((scientific-library 'square-root) 23)
((fast-library 'square-root) 23)

您甚至可以将示例科学和快速库组合成一个大的调度方法:

(define (library l f)
  (define (scientific-library f)
    ...)
  (define (fast-library f)
    ...)
  (cond ((eq? l 'scientific) (scientific-library f))
        ((eq? l 'fast) (fast-library f))
        (else (error "no such library" l))))
(library 'fast 'square-root)
于 2009-03-06T11:24:35.833 回答