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

时间:2009-03-06 00:39:02

标签: scheme racket

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

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

然后他们演示如何使用

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

在他们的例子中,他们继续演示完全我想要的用法 - 一种优雅,极简主义的方式,在计划中做“OO”风格......他们“合作”在一起一个“类型”,实际上是“make-environment”特殊形式(即vtable)和arg(“状态”)返回的......

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

即。我想创建一个“对象”,例如,两个函数,我在不同的上下文中调用...但我不想通过“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-Z-H-28.html#%_sec_4.3

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

4 个答案:

答案 0 :(得分:12)

经过多次挖掘后,我在新闻网上发现了这个informative thread

“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))) 

(摘自this

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

(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 - 但我认为即使上面也有点矫枉过正。

答案 1 :(得分:4)

由于性能原因,Scheme没有一流的环境。当Scheme被创建时,它不是最快的语言,因为它具有诸如一流函数,延续等等的漂亮东西。添加一流的环境会进一步削弱性能。所以这是在早期的计划日内做出的权衡。

答案 2 :(得分:4)

他们这样写的是因为麻省理工学院计划确实有一流的环境,大概就是作家们计划教他们班级的东西(因为这本书是在麻省理工学院写的)。

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

然而,我注意到MIT Scheme虽然仍然有些积极开发,但缺乏真正现代Scheme所具有的许多功能,如外部函数接口或GUI支持。您可能不希望将它用于严肃的软件开发项目,至少不是单独使用它。

答案 3 :(得分: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)