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

Common lisp 在lisp包中重新定义内置函数的方法,common-lisp,packages,Common Lisp,Packages,我目前正在编写向量算术的小型实现,我想定义我自己的«-»和«+»(可能还有其他)函数,这些函数将对向量进行操作 我还想把所有这些函数放在一个包中 我希望这个假设的包,比如说它被称为«vec»,表现如下: 在包内,我定义了函数«-»和«+»,但在调用+或-(在同一个包内)时,会调用公共Lisp内置函数 如果前面的方法不可行,我想将内置的+和-调用为cl:+和cl:-,但不需要从:cl显式导入所有其他需要的函数 当我导入vec包,或者在中提到它时:使用另一个包的定义的部分,common lisp包

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

我还想把所有这些函数放在一个包中

我希望这个假设的包,比如说它被称为«vec»,表现如下:

  • 在包内,我定义了函数«-»和«+»,但在调用+或-(在同一个包内)时,会调用公共Lisp内置函数
  • 如果前面的方法不可行,我想将内置的
    +
    -
    调用为
    cl:+
    cl:-
    ,但不需要从
    :cl
    显式导入所有其他需要的函数
  • 当我导入
    vec
    包,或者在
    中提到它时:使用另一个包的定义的
    部分,common lisp包的«-»和«+»仍然可用,包vec的函数调用类似
    (vec:+v1 v2)
    ,因此
    vec:+
    cl:+
    之间没有名称冲突

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

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

您不需要导入符号。如果它们被导出,您可以使用它们作为
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
CL-USER 6>(defpackage“VEC”
(:使用“CL”)
(:阴影cl:+cl:-)
(:导出“+”—”)
#
CL-USER 7>(定义向量:+(a b)(+a b))
VEC:+
CL-USER 8>(定义向量:-(a b)(-a b))
VEC:-
CL-USER 9>(定义软件包“图形”(:使用“CL”))
#
CL-USER 10>(包装“图形”中)
#
图11>(defun foo(ab)(+(vec:+ab)42))
福
注意,如果当前包是
VEC
,则
+
指的是
VEC:+
。对于CL
+
您需要编写
CL:+

始终牢记:

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

非常感谢!这个
:shadow
正是我所需要的。您可能对的网格子系统感兴趣,它定义了通用数组(包括外部数组)的操作。数学符号和一些数组操作符号被阴影化。查看init/package.lisp文件以了解阴影是如何完成的。@利亚姆,谢谢,我会看一看。@sds,不太清楚。我对软件包特别感兴趣,但这个问题的答案确实也非常适合我的情况!谢谢