Почему Clojure мультиметоды лучше, чем выражения "если" или "случай"
Я потратил некоторое время, пытаясь понять Clojure multimethods. Главный аргумент "pro" multimethod, насколько я понимаю, является их гибкостью, однако я смущен аргументами о том, почему мультиметоды лучше, чем простой оператор if или case. Может кто-нибудь, пожалуйста, объясните, где изображена линия между полиморфизмом и выражением overglorated case?
EDIT: Я должен был быть более ясным в вопросе, что меня больше интересует сравнение с оператором if. Большое спасибо за ответы!
Ответы
Ответ 1
Разница между multimethods и большим if-statement заключается в том, что вам нужно изменить функцию, содержащую case-statement, чтобы добавить случаи в if-statement. Вы можете добавить новый метод, не касаясь ранее существующих методов.
Итак, если вы определяете мультиметод внутри вашей библиотеки и хотите, чтобы ваши пользователи могли расширять его для своих собственных типов данных, это не проблема. Если бы вы использовали if-statement, это было бы большой проблемой.
Ответ 2
Скажем, у нас есть типы A, B, C, D и E и методы m1, m2, m3, принимающие один аргумент предыдущих типов. Вы можете поместить их в таблицу следующим образом:
| A | B | C | D | E |
m1 | | | | | |
m2 | | | | | |
m3 | | | | | |
Стратегия оператора "switch" реализует одну строку этой таблицы за раз. Предположим, вы добавили новый тип F. Вам нужно будет изменить все реализации для его поддержки.
Полиморфизм на основе классов (С++, Java и т.д.) позволяет вам вместо этого реализовать целый столбец. Таким образом, добавление нового типа легко, поскольку вам не нужно менять уже определенные классы. Но добавить новый метод сложно, так как вам придется добавить его ко всем другим типам.
Мультиметоды позволяют реализовать отдельные ячейки таблицы независимо друг от друга.
Эта гибкость еще больше, если вам нужно отправить несколько аргументов. Каждый новый аргумент добавляет другое измерение в эту таблицу, и как swich-based, так и рассылки на основе классов становятся очень сложными довольно быстро (c.f. Visitor pattern).
Обратите внимание, что мультиметоды на самом деле даже более общие, чем изображенные, так как вы можете отправлять практически все, а не только типы аргументов.
Ответ 3
Ответ ivant выше можно расширить, взглянув на в этой статье. Он неплохо объясняет мощь протоколов. Подумайте о мультиметодах как о протоколах со многими измерениями.