可以“延伸”吗? Scheme中的函数/ lambda / macro? [英] Is it possible to "extend" a function / lambda / macro in Scheme?
问题描述
例如:如果我希望函数相等?
识别我自己的类型或记录,我可以添加的新行为吗?
?没有删除或覆盖旧的?
For example: if I want the function equal?
recognize my own type or record, can I add a new behavior of equal?
? without erasing or overwriting the old one?
或者例如,如果我想使函数+
接受还有字符串?
Or for example if I want to make the function "+"
accept also string?
推荐答案
不是使用 import
,更好的解决方案是通过让
- 绑定它来跟踪原始功能。最好还是检查参数的类型是否为字符串,而不是它不是数字。使用这两种方法意味着可以组合技术。
Rather than using import
, a better solution is to keep track of the original function by let
-binding it. It's also better to check that the type of the argument is a string, rather than that it is not a number. Using both of these approaches means that it's possible to compose the technique.
(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)))))
以上将产生一个 +
适用于数字,字符串或向量的函数。一般来说,这是一种更具扩展性的方法。
The above will produce a +
function that works on numbers, strings, or vectors. In general, this is a more extensible approach.
我能够在MIT / GNU中验证上述方法是否正常工作Scheme,Guile,Racket,Chicken,TinyScheme和SCSH。但是,在某些实现中,例如Biwa Scheme,有必要使用 set!
而不是 define
。在Ikarus中, set!
不能用于导入的基元,而 define
会破坏环境,所以有必要分两步执行此操作:
I was able to verify that the above works correctly in MIT/GNU Scheme, Guile, Racket, Chicken, TinyScheme, and SCSH. However, in some implementations, such as Biwa Scheme, it is necessary to use set!
instead of define
. In Ikarus, set!
cannot be used on an imported primitive, and define
messes up the environment, so it is necessary to do this in two steps:
(define new+
(let ((old+ +))
(lambda args
(if (string? (car args))
(apply string-append args)
(apply old+ args)))))
(define + new+)
请注意,根据 R5RS , define
和 set!
在这种情况下应该是等价的:
Note that according to R5RS, define
and set!
are supposed to be equivalent in this case:
在程序的顶层,定义
At the top level of a program, a definition
(define <variable> <expression>)
与赋值表达式具有基本相同的效果
has essentially the same effect as the assignment expression
(set! <variable> <expression>)
if < variable>
已绑定。
这篇关于可以“延伸”吗? Scheme中的函数/ lambda / macro?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!