首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在R7RS方案中模拟一个一流库

在R7RS方案中模拟一个一流库
EN

Stack Overflow用户
提问于 2014-01-12 16:09:55
回答 1查看 361关注 0票数 2

我在考虑一个类似迪伦的对象系统的实现。(最好用于完全可移植的R7RS方案。)在Dylan中,有一个密封类的概念:不能从定义类的模块之外的密封类继承。

将R7RS库视为模块似乎是很自然的。然而,R7RS方案中的库是静态的:在运行时没有保留任何关于它们的内容.从库导入绑定之后,它似乎与所有其他绑定都没有区别。

这是sealed实现的一个问题。假设一个类是由某个define-class表单创建的。此表单有效地扩展为以下内容

代码语言:javascript
复制
(define <new-class> (make <class> ...))

然后,<new-class>绑定可以从创建它的库导出,并导入到其他库中(可能以不同的名称)。假设我们在库A中创建一个密封的<new-class>,并将其导入库B。从B调用的make如何判断它是否能够创建<new-class>的后代?如何允许从A调用的make无条件地创建<new-class>的子类?

(让我们忽略这种方法的一个缺点: R7RS允许多次加载<new-class>库,这有效地创建了几个不同的<new-class>类对象。我真的不知道怎么解决这个问题。)

一个想法是将所有类定义包含在一个表单中:

代码语言:javascript
复制
(define-library (A)
  (import (dylan))
  (export <new-class>)
  (begin
    (dylan-module
      (define-class <new-class> <object>
        ...  ) ) ) )

dylan-module中定义的密封类可以继承,但是一旦表单结束,它们就会被密封。然而,我只想出了一种方法来实现这个目标:

代码语言:javascript
复制
(define-syntax dylan-module
  (syntax-rules ()
    ((dylan-module %define-class body1 body2 ...)
     (begin
       ;; We will gather here all classes that are defined
       ;; inside the dylan-module form.
       (define to-be-sealed (list))

       ;; Locally redefine define-class to define a class
       ;; and add it to the list.
       ;;
       ;; It is necessary to pass %define-class explicitly
       ;; due to hygienic renaming: we want to allow %define-class
       ;; to be used inside of the body of the dylan-module form,
       ;; so we need to use a name from the environment where the
       ;; body is actually written.
       (let-syntax ((%define-class
                      (syntax-rules ()
                        ((%define-class name other (... ...))
                         (begin
                           (define-class name other (... ...))
                           (set! to-be-sealed
                                 (cons name to-be-sealed) ) ) ) ) ))
         body1 body2 ... )

       ;; The `seal` function is defined elsewhere.
       ;; `make` is allowed to subclass the sealed classes
       ;; until they are actually sealed by `seal`.
       (for-each seal to-be-sealed) ) ) ) )

它是这样使用的:

代码语言:javascript
复制
(define-library (A)
  (import (scheme base)
          (dylan) )
  (export <new-class>)
  (begin
    (dylan-module define-class
      (define-class <new-class> <object>
        ...  ) ) ) )

它的愚蠢之处在于:

  • 用户需要拼写出define-class来正确地重新定义它(在Dylan中,泛型函数也可以被密封,所以define-generic会在此之后出现);
  • 泛型make不能以安全的方式创建密封类,应该始终使用define-class宏(或其他一些特例)。
EN

回答 1

Stack Overflow用户

发布于 2015-09-20 05:03:02

在我看来,您不应该尝试将R6RS/R7RS库重新用作类,而应该在Scheme中直接构建您自己的类。库的目的是在编译时提供命名空间控制,而不是在运行时执行任何操作。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21076964

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档