Types 任意类型说明符上的Defmethod?

Types 任意类型说明符上的Defmethod?,types,lisp,common-lisp,Types,Lisp,Common Lisp,我想做的是: (defgeneric fn (x)) (defmethod fn ((x (integer 1 *))) "Positive integer") (defmethod fn ((x (integer * -1))) "Negative integer") 我想要一个与任意类型说明符一起工作的泛型函数,包括基于列表的函数,例如(和xy),(或xy),(满足p),等等。现在,当我尝试运行上述代码时,会出现一个“Invalid Specializer”错误。一点研

我想做的是:

(defgeneric fn (x))

(defmethod fn ((x (integer 1 *)))
    "Positive integer")

(defmethod fn ((x (integer * -1)))
    "Negative integer")
我想要一个与任意类型说明符一起工作的泛型函数,包括基于列表的函数,例如
(和xy)
(或xy)
(满足p)
,等等。现在,当我尝试运行上述代码时,会出现一个“Invalid Specializer”错误。一点研究表明,
defgeneric
设计用于CLO,而不是任意类型说明符。在Common Lisp中是否有一个类似于defgeneric的系统,可以让我获得我想要的任意类型说明符的行为,而不仅仅是类?

没有任何东西能像CLOS那样提供这样的功能

它实际上也不适合CLO。考虑以下情况,我们有一个泛型函数的以下调用:

(generic-function-foo 2)
现在,我们为以下类型定义了方法:

(integer 0 9)
(integer 1 9)
(integer 0 99)
(integer 1 99)
(integer -1000 1000)
(or (satisfies evenp) (integer 0 30))
(satisfies evenp)
(satisfies divisible-by-two)
(satisfies all-numbers-which-are-in-my-list-of-numbers)
应该运行所有与2匹配的方法中的哪一个?如果我调用
call-NEXT-METHOD
,下一个是哪个

现在我们可以说在源代码中按外观排序。但在CommonLisp中,您可以在运行时添加、删除或重新定义方法。这种行为或多或少是随机的

我们需要一些其他的冲突解决方案。例如:

  • 手动声明优先级
  • 某种优先级值
  • 运行时错误,用户有机会选择一个
  • 一种类型语言,它提供一个顺序
  • 一起放弃秩序
有人试图向CLO提供更具表现力的调度。不过,我不知道向CLO添加类型。请参见谓词分派和筛选分派


除此之外,我会寻找一个基于规则的系统,但这通常与CLOS(公共Lisp对象系统)非常不同,除非它以某种方式集成。

公共Lisp定义了两个相关但不完全相同的层次结构:类型层次结构和类层次结构。每一个类都是一个类型,但反过来不是真的——有些类型不是类。例如,
integer
string
是类,因此也是类型。另一方面,
(整数1*)
(整数p)
是类型,而不是类

> (type-of "toto")
(SIMPLE-BASE-STRING 4)
> (class-of "toto")
#<BUILT-IN-CLASS STRING>
如果您真的需要将代码模块化,则需要首先将您的值分类为可以制作成专门程序的内容,然后在此基础上分派:

(defmethod fn-generic (x (sign (eql 'positive)))
  "Positive integer")

(defmethod fn-generic (x (sign (eql 'negative)))
  "Negative integer")

(defun classify (x)
  (cond
    ((< x 0) 'negative)
    ((= x 0) 'null)
    ((> x 0) 'positive)))

(defun fn (x)
  (fn-generic x (classify x)))
(defmethod fn generic(x(符号(eql'positive)))
“正整数”)
(定义方法fn通用(x(符号(eql'负)))
“负整数”)
(定义分类(x)
(续)
((x0)“正”))
(十)
(fn通用x(分类x)))

您实际上似乎在寻找的是模式匹配,比如在ML或Erlang中。这是一个与分派截然不同的概念,尽管它们有相似的目的


一个流行的公共Lisp模式匹配库是(可从Quicklisp获得)。

Zero是正的和负的?@RainerJoswig修复了此问题,但它并没有真正改变问题的目的。是的,但它暴露了此类功能的问题。如果两种方法都匹配:使用哪一种?这些方法无法排序。。。对于零,两种方法都是匹配的。“哪一个应该被使用?”RainerJoswig说得对,但这不是什么大问题。例如,可以执行上指定的最后一个或第一个。@Coredump:这些结果无处不在。你需要订购整个打字系统。这将彻底改变该系统的性质。它与零无关。与对象匹配的任何两种类型都需要具有可比的wrt特定性,否则行为将是随机的。
(defmethod fn-generic (x (sign (eql 'positive)))
  "Positive integer")

(defmethod fn-generic (x (sign (eql 'negative)))
  "Negative integer")

(defun classify (x)
  (cond
    ((< x 0) 'negative)
    ((= x 0) 'null)
    ((> x 0) 'positive)))

(defun fn (x)
  (fn-generic x (classify x)))