【问题标题】:Way to redefine builtin function inside a lisp package在 lisp 包中重新定义内置函数的方法
【发布时间】:2013-11-08 07:38:41
【问题描述】:

我目前正在编写向量算术的小型实现,我想定义自己的«-» 和 «+»(可能还有其他)函数来对向量进行操作。

而且我还想将所有这些功能放在一个包中。

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

  • 在包内,我定义了函数 «-» 和 «+»,但是当我调用 + 或 -(在同一个包内)时,会调用 Common Lisp 内置函数。
  • 如果以前不可能,我想将内置 +- 称为 cl:+cl:-,但无需从 :cl 显式导入所有其他需要的函数。
  • 当我导入vec包,或者在另一个包的定义:use部分提到它时,common-lisp包的«-»和«+»仍然可用,并且包vec的函数被称为(vec:+ v1 v2) ,所以vec:+cl:+ 之间没有名称冲突。

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

【问题讨论】:

  • redefining built-in function 的可能重复项
  • 您可能对Antik 的网格子系统感兴趣,它定义了泛化数组(包括外来数组)的操作。数学和一些数组操作符号被遮蔽。查看文件 init/package.lisp 以了解阴影是如何完成的。
  • @Liam,谢谢,我去看看。
  • @sds,不是真的。我对包裹特别感兴趣,但这个问题的答案确实非常适合我的情况!谢谢。

标签: common-lisp packages


【解决方案1】:

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

您不需要导入符号。如果它们被导出,您可以将它们用作foo:+。如果没有导出,可以作为foo::+使用。

如果您不想在 using 包中使符号可访问,那么 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:+

始终牢记:

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

【讨论】:

  • 非常感谢! :shadow 正是我所需要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-20
  • 1970-01-01
  • 2020-08-01
  • 1970-01-01
  • 2011-05-20
  • 2010-10-13
相关资源
最近更新 更多