在lisp包中重新定义内置函数的方法

时间:2013-11-08 07:38:42

标签: common-lisp packages

我目前正在编写矢量算术的小实现,我想定义自己的« - »和«+»(以及其他)函数,它们将在向量上运行。

我还希望将所有这些功能放在一个包中。

我想要这个假设的包,比如说它叫做«vec»,表现得像这样:

  • 在包内,我定义了函数« - »和«+»,但当我调用 +或 - (在同一个包中)时,调用Common Lisp内置函数。
  • 如果以前无法使用,我想将内置+-称为cl:+cl:-,但无需明确导入其他所有必需的功能:cl
  • 当我导入vec包或在另一个包的定义的:use部分中提及它时,common-lisp包的« - »和«+»仍然可用,并且包vec的函数被调用与(vec:+ v1 v2)类似,因此vec:+cl:+之间没有名称冲突。

那么,什么被认为是实现这种行为的最佳(和正确)方式?

1 个答案:

答案 0 :(得分:6)

无法定义符号+并让它同时引用另一个包中的+

您无需导入符号。如果导出它们,您可以将它们用作foo:+。如果未导出它们,则可将其用作foo::+

如果您不想在使用包中访问符号,那么using(在程序意义上 - 确保将包作为向量操作的命名空间引入)是没有意义的。 。如果你想写vec:+,那么使用包VEC是没有意义的。只需从VEC导出符号。

仅供参考:

CL-USER 6 > (defpackage "VEC"
               (:use "CL")
               (:shadow cl:+ cl:-)
               (:export "+" "-"))
#<The VEC package, 0/16 internal, 2/16 external>

CL-USER 7 > (defun vec:+ (a b) (+ a b))
VEC:+

CL-USER 8 > (defun vec:- (a b) (- a b))
VEC:-

CL-USER 9 > (defpackage "GRAPH" (:use "CL"))
#<The GRAPH package, 0/16 internal, 0/16 external>

CL-USER 10 > (in-package "GRAPH")
#<The GRAPH package, 0/16 internal, 0/16 external>

GRAPH 11 > (defun foo (a b) (+ (vec:+ a b) 42))
FOO

注意,如果当前包是VEC,则+引用VEC:+。对于CL +,您需要编写CL:+

始终牢记:

  • 包在读取时解析。
  • 当前包确定在读取时间内使用的默认包。更改当前包不会改变已读取的符号。