【问题标题】:How can I attach a type tag to a closure in Scheme?如何将类型标签附加到 Scheme 中的闭包?
【发布时间】:2013-04-19 07:06:33
【问题描述】:

如何在 Scheme 中将任意标签附加到闭包上?

以下是我想用它来做的几件事:

(1) 标记提供接口的闭包,以便为它们所代表的内容生成一个字符串,就像@kud0h 要求here 一样。一个通用的->string 过程可能包含如下代码:

(display (if (stringable? x)
             (x 'string)
             x)
         str-port)

(2) 更一般地说,确定闭包是否是遵守通用对象接口规则的“对象”,或者可能告诉对象的类(类似于@KPatnode 询问@987654324 @)。

我不能通过调用一个过程来查询它是否支持某个接口,因为如果它不支持一个已知的接口,调用该过程会产生不可预知的结果,很可能是运行时错误。

Chez Scheme 具有putpropgetprop 过程,允许您向符号添加键和值。但是,闭包可以是匿名的,也可以绑定到不同的符号,因此我更愿意将调用约定标记附加到闭包本身,而不是绑定到的符号。

我现在唯一的想法是维护系统中所有“字符串”或“对象”闭包的全局哈希表。这似乎有点笨拙。有没有更简单、更优雅、更高效的方法?

【问题讨论】:

    标签: oop object scheme


    【解决方案1】:

    Racket 有applicable structures:如果将实例用作函数,您可以为结构类型提供应用挂钩。

    如果您想要一个更便携的解决方案,您可以使用哈希表将您的数据与某些过程相关联。但是,除非您的 Scheme 提供了弱哈希表,否则请记住,哈希表会阻止程序被垃圾收集。

    【讨论】:

    • 谢谢。我没有听说过适用的结构,但这听起来确实是一种非常简单的方法,可以将过程附加到某些数据,而不会在调用过程时造成混乱。我正在使用 Chez Scheme,它有弱引用,但如果这只能在 Racket(或 Scheme 的其他扩展)中完成,那可能是一个有争议的问题。
    【解决方案2】:

    我想你可能想看看Racket's object system,而不是标记过程本身,它有一个接口的概念。这听起来与您所追求的非常相似。

    【讨论】:

    • 谢谢!确实,我对制作具有受语言尊重的已定义接口的对象非常感兴趣。 Racket 的对象系统可能正是我想要的。
    【解决方案3】:

    您可以走极端,重新定义lambda 语法。像这样的东西(但未经我测试):

    (define *properties* '())    ;; example only
    
    (define-syntax lambda
      (let-syntax ((sys-lambda
                    (syntax-rules ()
                      ((_ args body ...)
                       (lambda args body ...)))))
        (syntax-rules ()
          ((_ args body ...)
           (let ((func (sys-lambda args body ...)))
             (set! *properties*
                   (cons (cons func '(NO-PROPERTIES))
                         *properties*))
             func)))))
    

    【讨论】:

    • 确实,宏提供了一种语法上很好的方法来方便地附加属性。我在想λo 的意思是“对象 lambda”。至于如何将属性附加到过程,看起来您也在考虑绑定到对象过程列表(或哈希表)的全局变量。这真的是 Scheme 提供的最好的吗?
    • a) 它不需要是全局的,也不需要是属性列表;因此“仅作为示例”。 b) 从设计上讲,Scheme 是一种允许人们探索编程概念的最小语言。 c) 有 TinyClos,或多或少是 Common Lisp 对象系统的 Scheme 实现。
    猜你喜欢
    • 2017-11-02
    • 1970-01-01
    • 1970-01-01
    • 2021-09-12
    • 1970-01-01
    • 1970-01-01
    • 2016-08-01
    • 2020-01-08
    • 2015-12-04
    相关资源
    最近更新 更多