Каковы преимущества использования мультиметодов вместо cond в Clojure? - PullRequest
6 голосов
/ 28 мая 2020

Почему нельзя просто заменить мультиметоды в Clojure выражениями cond?

Я был вдохновлен этим вопросом после просмотра простых примеров мультиметодов в гл. 5 книги Русса Олсена Получение Clojure .

В ответ на аналогичный вопрос ( Производительность multimethod vs cond в Clojure ) пользователь Дэниел Комптон говорит:

Мультиметоды позволяют открытое расширение; другие могут расширить вашу мультиметодную отправку на произвольные выражения. Выражения Cond закрыты для расширения другими или даже вашим собственным кодом.

Но мне совсем не ясно, что означают «открытое расширение» и «закрыто для расширения» в данном контексте, поскольку кажется мне кажется, что и мультиметоды, и выражения cond можно легко редактировать или расширять.

Итак ... почему бы просто не заменить мультиметоды в Clojure выражениями cond?

Или, что то же самое, как и когда именно использование мультиметодов может быть лучше или элегантнее, чем использование cond?

1 Ответ

8 голосов
/ 28 мая 2020

Ключевым моментом здесь является «разрешить открытое расширение». Любой может добавить новые ветки для ваших мультиметодов - cond жестко запрограммирован: новые отправления должны быть добавлены к cond коду на месте.

Допустим: у вас есть несколько виджетов, и вы хотите рисовать их. Виджеты имеют :type, и вы хотите отправить, как draw для этого типа.

Запись большого cond для всех виджетов , о которых вы знаете, будет работать. Но теперь для каждого нового виджета вам нужно коснуться исходного кода cond и изменить его. Это может идеально подходить, например, для реального приложения, которое не требует расширения.

То же самое с мультиметодами, любой может реализовать draw для своих виджет. Итак, вы не знаете их всех при написании кода. Это делает этот подход лучше (или даже обязательным), например, для библиотек.

А теперь представьте, что вы выбрали подход cond для библиотеки, которую пишете. Любой, у кого есть новый виджет, должен написать свой собственный draw, сначала отправить его dr aws, а затем позвонить на draw. Также им нужно будет убедиться, что их draw вызывается везде, где ваш draw был вызван, чтобы он работал (что часто просто невозможно в чистом виде). ​​

Один популярный пример для multimethod прямо в ядре Clojure: print-method. Таким образом, любой может реализовать «сериализацию» для своего типа и играть красиво.

Другие достойные упоминания примеры, на которые стоит обратить внимание: clojure.test и integnt .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...