Common lisp CLOS рассылка
Есть ли хороший способ получить универсальную функцию для отправки на автомобиль списка?
Я работал над программой символической алгебры, и на данный момент я храню много данных в виде списков с разными ключевыми словами, такими как car
s, чтобы указать тип. Например, у меня есть симплексы, хранящиеся как '(:simplex #(0 1 2))
и у меня есть кое-что, что я называю шагами, пока хранится как '(:step #(0 1 0 1))
, Я хотел бы иметь возможность взять размеры и границы обоих из них, в идеале используя некоторый встроенный механизм диспетчеризации.
1 ответ
Немного хакер, но вы можете сделать это с eql
specialisers.
(defmethod foo ((first (eql :simplex)) (thing vector))
<method body here>)
Затем вы должны назвать это как
(foo :step #(0 1 0 1))
или же
(apply #'foo '(:step #(0 1 0 1)))
Итак, для вашей ситуации, вы бы сделали что-то вроде
(defmethod dimension ((type (eql :simplex)) (thing vector))
;; calculate dimension of a SIMPLEX here
)
(defmethod dimension ((type (eql :step)) (thing vector))
;; calculate dimension of a STEP here
)
и то же самое для boundary
,
Если вещи, которые вы обрабатываете, на самом деле должны быть разными структурами, вы можете определить struct
с или class
es вместо использования необработанных списков. На этом этапе вы можете легко определить методы для соответствующего типа, что позволит вам обойти неуклюжие требования к вызову этого подхода.