为什么Scheme不支持一流的环境?

Pau*_*rth 18 scheme racket

我一直在阅读SICP(计算机程序的结构和插入)并且非常兴奋地发现这种奇妙的特殊形式:"make-environment",他们证明它与eval结合使用作为编写模块化代码的一种方式(摘录)关于"包裹"的第4.3节:

(define scientific-library
  (make-environment
   ...
   (define (square-root x)
    ...)))
Run Code Online (Sandbox Code Playgroud)

然后他们演示了它的工作原理

((eval 'square-root scientific-library) 4)
Run Code Online (Sandbox Code Playgroud)

在他们的榜样,他们然后去证明正是我想要的使用-在计划做"OO"风格的优雅简约的方式......他们"利弊"在一起"类型",这实际上是什么由"make-environment"特殊形式(即vtable)和arg("the state")返回...

我非常兴奋,因为这正是我一直在寻找的一种方法,可以在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.
Run Code Online (Sandbox Code Playgroud)

在SICP中引用了"make-environment"怎么了?这一切看起来都很优雅,正是我想要的,但它似乎并没有得到任何现代Scheme解释器的支持?

理由是什么?简单地说"make-environment"有不同的名字吗?

稍后会发现更多信息

我看了看在线版:

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

我正在阅读的是SICP的第一版.第二版似乎已经用关于非确定性编程和"放大器"运算符的部分取代了关于包的讨论.

Pau*_*rth 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))) 
Run Code Online (Sandbox Code Playgroud)

(取自)

然而,我最终采用了"消息传递"风格,有点像第一个人建议 - 我返回一个函数列表,并有一个通用的"发送"方法,用于通过名称调用特定的函数...即这样的东西

(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)
Run Code Online (Sandbox Code Playgroud)

我一直在阅读,并且我知道如果我真的想要采用完全OO风格的话,那就是所有的CLOS - 但我认为即使是上面也有点矫枉过正.


Noa*_*ine 5

他们这样写是因为麻省理工学院计划确实拥有一流的环境,大概这就是作者计划教他们的课程的内容(因为这本书是在麻省理工学院写的)。

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

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