Scheme 为什么';t方案是否支持一流的环境?

Scheme 为什么';t方案是否支持一流的环境?,scheme,racket,Scheme,Racket,我一直在阅读SICP(计算机程序的结构和解释),并非常兴奋地发现了这种奇妙的特殊形式:“生成环境”,他们演示了将其与eval结合使用作为编写模块化代码的一种方式(摘自第4.3节“包”): 然后,他们将演示它如何与 ((eval 'square-root scientific-library) 4) 在他们的例子中,他们接着准确地展示了我想要的用法——一种优雅、极简的方式,在scheme中实现“OO”风格。。。它们“cons”在一起是一个“type”,实际上是“makeenvironment”特

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

然后,他们将演示它如何与

((eval 'square-root scientific-library) 4)
在他们的例子中,他们接着准确地展示了我想要的用法——一种优雅、极简的方式,在scheme中实现“OO”风格。。。它们“cons”在一起是一个“type”,实际上是“makeenvironment”特殊表单(即vtable)返回的内容,还有一个arg(“state”)

我非常激动,因为这正是我一直在寻找的一种在Scheme中“按符号”执行多态调度的方法,而不必编写大量显式代码或宏

i、 我想创建一个“对象”,它有两个函数,我在不同的上下文中调用它们。。。但我不想用“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中引用的“制造环境”发生了什么变化?这一切看起来都很优雅,这正是我想要的,但它似乎在任何现代口译方案中都不受支持

理由是什么?只是“makeenvironment”有不同的名称吗

以后可以找到更多信息

我看了一下在线版本:


我读的是SICP的第一版。第二版似乎已经用非确定性编程和“amp”操作符部分取代了对包的讨论。

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

经典的调度器功能会起作用吗?我想这和你要找的差不多

(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)
您甚至可以将示例scientific和fast库组合到一个大型分派方法中:

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

在深入挖掘之后,我在新闻网上发现:

“R5RS EVAL和环境说明符是两者之间的折衷 那些非常不喜欢一流环境并想要一个 限制评估,以及未经批准不能接受/理解评估的人 第二个论点是环境。”

此外,我们还发现了这种“变通方法”:

(摘自)

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

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

我一直在深入阅读,并意识到如果我真的想采用完全面向对象的风格,就有所有的CLO——但我认为即使是上面的内容也有点过分。

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

退房


然而,我注意到,尽管麻省理工学院的Scheme仍在积极开发,但它缺少许多真正现代的Scheme所具备的功能,如外部功能界面或GUI支持。您可能不想将其用于一个严肃的软件开发项目,至少不想单独使用。

是的,但写上面的内容是如此乏味nd verbose!make environment宏很棒,但我仍然错过了一件事:我想有一种方法来验证符号是否绑定在环境中,只使用标准的R5R,据我所知,如果没有像存储定义名称表之类的丑陋的黑客攻击,这是不可能的,我刚刚注意到,make-environment技巧可能在方案实现中起作用,也可能不起作用:方案报告环境可能是不可变的,而且宏中的LET可能不会复制环境。在Scheme中(至少在R5RS中)似乎没有一种可移植的方式来创建环境。您对此有任何参考资料吗?
(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)