0

I thought i could define a method which accepts keyword arguments. But when i have multiple methods with keyword arguments of different types, it seems that lisp uses the last evaluated method. For example below:

(defmethod f (&key (x list)) (make-list 3 :initial-element (first x)))
(defmethod f (&key (x number)) (* 2 x))

Now f's :x accepts only numbers and throws errors for lists:

(f :x 2)                ;4

but

(f :x '(2))

The value (2) is not of type NUMBER when binding SB-KERNEL::X [Condition of type TYPE-ERROR]

How can i define multiple methods with &key args of different types?

Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346
  • 4
    Common Lisp does not support dispatching on keyword arguments. Thus it's not possible to declare classes for keyword arguments. See the syntax of defmethod in the Common Lisp HyperSpec: http://www.lispworks.com/documentation/HyperSpec/Body/m_defmet.htm#defmethod – Rainer Joswig Oct 23 '19 at 14:25

1 Answers1

4

You can only dispatch on required positional parameters. Any &optional, &key, &rest and &aux parameters only work as in normal lambda lists.

Because of this, your second definition did not differ in the dispatching part and overwrote the existing method. I also believe that your example should have issued warnings about list and number being unbound variables.

Svante
  • 50,694
  • 11
  • 78
  • 122