Почему мультиметоды Clojure лучше, чем утверждения «если» или «случай» - PullRequest
16 голосов
/ 11 марта 2012

Я провел некоторое время, пытаясь понять мультиметоды Clojure.Насколько я понимаю, основным аргументом «за» мультиметоды является их гибкость, однако меня смущает аргументация того, почему мультиметоды лучше простого оператора if или case.Может ли кто-нибудь, пожалуйста, объяснить, где проходит грань между полиморфизмом и чрезмерно прославленным падежом?

РЕДАКТИРОВАТЬ: я должен был быть более ясным в этом вопросе, что я больше заинтересован в сравнении с «если»заявление.Большое спасибо за ответы!

Ответы [ 3 ]

23 голосов
/ 11 марта 2012

Скажем, у нас есть типы A, B, C, D и E, а методы m1, m2, m3 принимают один аргумент предыдущих типов. Вы можете поместить их в таблицу следующим образом:

   | A | B | C | D | E |
m1 |   |   |   |   |   |
m2 |   |   |   |   |   |
m3 |   |   |   |   |   |

Стратегия оператора "switch" реализует по одной строке этой таблицы за раз. Предположим, вы добавили новый тип F. Вы должны будете изменить все реализации, чтобы поддержать его.

Полиморфизм на основе классов (C ++, Java и т. Д.) Позволяет вместо этого реализовать целый столбец. Таким образом, добавить новый тип легко, поскольку вам не нужно менять уже определенные классы. Но добавить новый метод сложно, так как вам придется добавить его ко всем другим типам.

Мультиметоды позволяют реализовать отдельные ячейки таблицы независимо друг от друга.

Эта гибкость еще больше, если вам приходится отправлять несколько аргументов. Каждый новый аргумент добавляет в эту таблицу еще одно измерение, и отправка как на основе классов, так и на основе классов довольно быстро становится очень сложной (см. Образец посетителя).

Обратите внимание, что мультиметоды на самом деле даже более универсальны, чем изображенные, так как вы можете рассылать практически все, а не только типы аргументов.

16 голосов
/ 11 марта 2012

Разница между мультиметодами и большим оператором if заключается в том, что вам нужно изменить функцию, содержащую оператор case, для добавления наблюдений в оператор if.Вы можете добавить новый метод, не затрагивая ранее существующие методы.

Так что, если вы определяете мультиметод внутри своей библиотеки и хотите, чтобы пользователи могли расширять его для своих собственных типов данных, это не проблема.Если бы вы использовали вместо этого оператор if, это было бы большой проблемой.

1 голос
/ 12 марта 2012

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

...