如何在Scheme中的运行时重载函数?

如何在Scheme中的运行时重载函数?,scheme,Scheme,rt。 我想在运行时重新定义函数,以便在运行时更改系统的行为。 谢谢。如果您想重载前面定义的函数,只需重新定义即可。这也适用于重新定义诸如car和cdr等功能,例如将car变成cdr: (定义(车辆x)(cdr x)) 但是,我认为通过这样的重新定义,您将无法影响其他已定义的功能,因此使用car的系统功能仍将使用原始系统car,而不是您的: (定义(测试x)(车辆x)) (定义(车辆x)(cdr x)) (测试(1、2、3)) 一, 我想这是因为在内部,一旦函数被读取或求值,符号就会消失,并被它

rt。 我想在运行时重新定义函数,以便在运行时更改系统的行为。
谢谢。

如果您想重载前面定义的函数,只需重新定义即可。这也适用于重新定义诸如car和cdr等功能,例如将car变成cdr:

(定义(车辆x)(cdr x))

但是,我认为通过这样的重新定义,您将无法影响其他已定义的功能,因此使用car的系统功能仍将使用原始系统car,而不是您的:

(定义(测试x)(车辆x))

(定义(车辆x)(cdr x))

(测试(1、2、3))

一,

我想这是因为在内部,一旦函数被读取或求值,符号就会消失,并被它们所绑定的内容替换;在这种情况下,函数的实际代码。因此,将符号重新绑定到其他函数不会影响已定义代码的其余部分。这通常是一件好事,因为它有助于维护引用的透明度


如果要重新定义方案关键字(如lambda或cond),请使用let语法(请参见)

建议使用let在本地执行此操作,这也适用于此意义上的关键字:

(let ((define +))
   (define 2 3)) ; ===> 5
或者甚至将它们重新定义为常量,记住,Scheme是lisp-1:

(let ((define 2) (+ 4))
   (- define +)) ; ===> -2
甚至:

(let ((quote /))
   '3) ===> 1/3

只在局部执行会保留函数样式。

第二次使用
define
是坏习惯,上面返回1的事实是由于相关原因。坏习惯:好的。但至于“相关原因”:我不这么认为。(test'(1 2 3))在使用(set!…)语法重新定义car时也会返回1而不是(2 3),正如我所说的,在考虑绑定的工作方式时,我认为这非常有意义。同意吗?对不起,忽略我最后的评论和回答。似乎我在使用一个非标准的方案实现来测试这个。麻省理工学院的方案正如你们所说,这使得我的答案是错误的。根据实际使用的设置,即使是单个实现也可能产生不同的结果。例如,您看到了一个内联已知原语(
car
)值的结果,该结果可以被禁用。如果我在一个文件中写入(set!foo(lambda(x)…不同的东西…),那么我只需要那个文件,对吗?我不确定你的意思——如果你使用racket,那么你需要在同一个模块中完成设置。(他的评论应该在答案旁边,顺便说一下…)伊莱,开始!作品但只适用于我之后定义的函数。我真正想要的是。我有一个函数a,它使用另一个函数B。在运行时,我想将B重新定义为不同的行为。所以A也会有一个新的行为。有可能吗?是的,应该可以。同样,如果你正在使用球拍,那么
设置
应该在同一个模块中——例如,您可以定义一个执行变异的
set foo
函数。或者,您可以使用一个参数——这是封装这种全局状态的更常见的方法。
(let ((quote /))
   '3) ===> 1/3