2015-04-26 25 views
3

我希望能够使用已定义的类型作为defmethod的参数专用程序。动机是可读性和灵活性,以在稍后阶段改变。 Somehting like:在defmethod中使用Common Lisp用户定义类型

(deftype foo() 'fixnum) 

(defmethod bar ((x foo)) ...) 

(defmethod baz ((x foo)) ...) 

但是,这是行不通的。 CLtL2说“表单deftype不会创建任何类。”

所以我必须写:

(defmethod bar ((x fixnum)) ...) 

(defmethod baz ((x fixnum)) ...) 

另一种方法是定义一个名为foo类无非是围绕fixnum的一个封装,但不会说是这么简单的东西不可接受的开销作为fixnum

有没有更好的方法?

+1

CLtL2已过时。请使用基于ANSI Common Lisp标准的Common Lisp HyperSpec [CLHS](http://www.lispworks.com/documentation/HyperSpec/Front/Contents.htm)。 –

+0

CLHS表示'defmethod'的'paramet-specializer-names':如果parameter-specializer-name是一个符号,它命名为class_ – user3414663

+0

实际上CLHS也表示_运算符deftype不会创建任何类._ – user3414663

回答

6

方法不专注于类型,它们专注于类或EQL。部分情况是这样,因为一个对象可能有很多种类型(例如,整数1是一个FIXNUM,一个BIT,一个无符号的字节等),如何决定优先级并不明显。

如果您希望较少的开销和用户定义的类型抽象,TYPECASE或ETYPECASE可能比泛型函数和方法更好。

0

我一直能找到的最佳解决方案是使用filtered dispatch

事情是这样的:

(define-filtered-function bar (x) 
    (:filters (:foo (typep x 'foo)))) 

(defmethod bar :filter :foo (x) ...) 

不过,我可以诉诸Xach的建议,如果使用这种开销原来是太高。