Clojure, как и многие другие функциональные языки, использует возможность бесплатного ввода текста для обеспечения простых способов реализации parametric polymorphism. Это в основном означает, что один метод может быть сконструирован таким образом, что ему не нужны типы значений, аргументы, которые он задает.
Возьмем, к примеру, метод concat
. Он принимает любое количество аргументов различных форм и помещает их в единый список, как так:
user=> (concat [:a :b] nil [1 [2 3] 4])
(:a :b 1 [2 3] 4)
Потому что один не нужно объявлять набор текста для аргументов, concat
могут быть написаны таким образом, что вы можете предоставить аргумент любого типа (вектор, функция, ключевое слово, строка и т. д.), и он будет действовать на них аналогичным образом.
Clojure's multimethods позволяет поддерживать эту концепцию на объектах Java, которые могут иметь совершенно разные структуры (например, таксономии), используя метаданные или другие свойства, чтобы определить подходящий способ борьбы с данным аргументом. Смотрите следующий пример (взятый из defmulti):
(defmulti greeting
(fn[x] (x "language")))
(defmethod greeting "English" [params]
(str "Hello! " (params "id")))
(defmethod greeting "French" [params]
(str "Bonjour! " (params "id")))
=>(greeting {"id" "1", "language" "English"})
"Hello! 1"
=>(greeting {"id" "2", "language" "French"})
"Bounjour! 2"
Метод greeting
возвращает значение "language"
из карты, которая соответствует "English"
или "French"
DEFMETHOD который возвращает правильное соответствующее значение. Надеюсь, вы можете увидеть, как эта концепция потенциально может быть применена практически к любому типу данных или структуре объектов. Эта мощная идея полиморфизма - это то, что разработчики Clojure пытаются показать на странице обоснования.
В Java, например, у вас есть иерархия классов и должны использовать эти классы и интерфейсы в качестве основы для полиморфизма. С помощью нескольких методов Clojure вы можете создать произвольные иерархии/системы классификации (таксономии) в качестве основы полиморфизма. –