Idiomatic way to specialize on type keyword for lisps that do not make keyword a class

StackOverflow https://stackoverflow.com/questions/22926071

  •  29-06-2023
  •  | 
  •  

Вопрос

In CLHS 4.3.7 Figure 4.8 lists the the set of classes that correspond to predefined type specifiers. 'keyword' is not among them. But it goes on to say that "Individual implementations may be extended to define other type specifiers to have a corresponding class".

So I assume this is what Clozure CL has done for the 'keyword' type specifier and the code below seems to bear that out. In lisps that do not do this (eg. SBCL and LispWorks which I have checked) what is the best way to get the Clozure CL behaviour? Or failing that, some workable compromise?

It seems kind of gross to explicitly test for the keyword type as I have done in the first definition of method foo below, but I can't see how to make the keyword type into a class if my lisp implementation has not already done it for me...

(in-package :cl-user)

(defmethod foo ((sym symbol))
  (let ((type (if (keywordp sym) "keyword" "symbol")))
    (format t "symbol specializer with ~A: ~A~%" sym type)))

#+clozure (defmethod foo ((sym keyword))
            (format t "We have keyword ~A~%" sym))

;; SBCL
(foo 'bar) => symbol specializer with BAR: symbol
(foo :bar) => symbol specializer with BAR: keyword

;; Clozure CL
(foo 'bar) => symbol specializer with BAR: symbol
(foo :bar) => We have keyword BAR
Это было полезно?

Решение

ANSI Common Lisp defines no class with the name KEYWORD. It is a non-portable extensions of Clozure Common Lisp.

There is also no portable way to introduce such a class.

Since symbol is a built-in class, you can't extend it with a subclass.

So I think the simple IF is ugly, but necessary. Another solution would be much more involved (imagine using the MOP to introduce a new way to dispatch over an own parallel class structure for types...).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top