2015-04-26 2 views
3

Я хотел бы иметь возможность использовать определенный тип в качестве специализированного параметра для параметра defmethod. Мотивация - это читаемость и гибкость для изменения на более позднем этапе. Что-то вроде:Использование общего пользовательского типа Lisp в defmethod

(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 устарел. Пожалуйста, используйте Common Lisp HyperSpec [CLHS] (http://www.lispworks.com/documentation/HyperSpec/Front/Contents.htm), который основан на стандарте ANSI Common Lisp. –

+0

CLHS говорит о 'параметрах-specializer-names'' defmethod': _ Если параметр-specializer-name является символом, он называет класс_ – user3414663

+0

На самом деле CLHS также говорит: «Оператор deftype не создает никаких классов. – user3414663

ответ

6

Методы не специализируются на типах, они специализируются на классах или EQL. Частично это происходит потому, что объект может иметь много типов (например, целое число 1 представляет собой FIXNUM, BIT, UNSIGNED-BYTE и т. Д.), И неясно, как решить приоритет.

Если вы хотите меньше накладных расходов и пользовательских абстракций для типов, TYPECASE или ETYPECASE могут работать лучше, чем общие функции и методы.

0

Лучшее решение, которое я смог найти, это использовать filtered dispatch.

Что-то вроде этого:

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

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

Однако я могу прибегнуть к предложению Xach, если накладные расходы на использование этого оказывается слишком высокой.

Смежные вопросы