Fel*_*ipe 5 inheritance scheme r6rs r5rs r7rs
例如:如果我希望函数equal?识别我自己的类型或记录,我可以添加新的行为equal?吗?没有删除或覆盖旧的?
或者,例如,如果我想使函数"+"接受也字符串?
更好的解决方案是通过绑定import来跟踪原始函数,而不是使用。let最好检查参数的类型是否为字符串,而不是数字。使用这两种方法意味着可以组合该技术。
(define +
(let ((old+ +))
(lambda args
(if (string? (car args))
(apply string-append args)
(apply old+ args)))))
(define +
(let ((old+ +))
(lambda args
(if (vector? (car args))
(apply vector-append args)
(apply old+ args)))))
Run Code Online (Sandbox Code Playgroud)
上面将生成一个+适用于数字、字符串或向量的函数。一般来说,这是一种更具可扩展性的方法。
我能够验证上述内容在 MIT/GNU Scheme、Guile、Racket、Chicken、TinyScheme 和 SCSH 中是否正常工作。然而,在某些实现中,例如Biwa方案,有必要使用set!而不是define. 在 Ikarus 中,set!不能在导入的基元上使用,并且define会弄乱环境,因此需要分两步执行此操作:
(define new+
(let ((old+ +))
(lambda args
(if (string? (car args))
(apply string-append args)
(apply old+ args)))))
(define + new+)
Run Code Online (Sandbox Code Playgroud)
请注意,根据R5RS,define和set!在这种情况下应该是等效的:
在程序的顶层,有一个定义
Run Code Online (Sandbox Code Playgroud)(define <variable> <expression>)与赋值表达式本质上具有相同的效果
Run Code Online (Sandbox Code Playgroud)(set! <variable> <expression>)如果
<variable>是绑定的。