Using a Common Lisp user-defined type in defmethod
Asked Answered
T

2

7

I'd like to be able to use a defined type as a parameter specializer to a defmethod. The motivation is readability and flexibility to change at a later stage. Somehting like this:

(deftype foo () 'fixnum)

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

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

However this doesn't work. CLtL2 says "The form deftype does not create any classes."

So I have to write:

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

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

An alternative would be to define a class called foo which is nothing more than a wrapper around fixnum but wouldn't that be an unacceptable overhead for something so simple as a fixnum?

Is there a better way?

Tiatiana answered 26/4, 2015 at 12:8 Comment(3)
CLtL2 is outdated. Please use the Common Lisp HyperSpec CLHS, which is based on the ANSI Common Lisp standard.Gagliardi
CLHS says of paramet-specializer-names of defmethod: If parameter-specializer-name is a symbol it names a classTiatiana
In fact CLHS also says The operator deftype does not create any classes.Tiatiana
R
12

Methods don't specialize on types, they specialize on classes, or EQL. This is partly the case because an object may be of many types (e.g. the integer 1 is a FIXNUM, a BIT, an UNSIGNED-BYTE, etc.) and it's not obvious how to decide precedence.

If you want less overhead and user-defined abstractions for types, TYPECASE or ETYPECASE may work better than generic functions and methods.

Rodmur answered 26/4, 2015 at 12:48 Comment(0)
T
4

The best solution I have been able to find is using filtered dispatch.

Something like this:

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

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

However I may resort to Xach's suggestion if the overhead for using this turns out to be too high.

Tiatiana answered 22/7, 2015 at 12:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.