2012-03-11 2 views
16

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

EDIT: Я должен был быть более ясным в вопросе, что меня больше интересует по сравнению с утверждением 'if'. Большое спасибо за ответы!

+0

Где линия, заключенная между выражением if и overglorated goto? – Kevin

+1

Возможно, вам будет интересно http://stackoverflow.com/q/5986120/625403, который не является точно дублирующим, но тесно связан. – amalloy

ответ

16

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

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

+0

Ах, это действительно то, что я плохо понял, спасибо! Итак, мультиметоды не ограничиваются пространством имен, в котором объявлено defmulti? – Iger

+0

@Iger Правильно. – sepp2k

23

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

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

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

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

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

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

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

1

Ответ на ivant выше можно расширить, взглянув на this article. Он неплохо объясняет мощь протоколов. Подумайте о мультиметодах как протоколах со многими измерениями.