#clojure #metadata
#функциональное программирование #clojure #метаданные
Вопрос:
Как вы использовали метаданные в своей программе Clojure?
Я видел один пример из программирования Clojure:
(defn shout [#^{:tag String} message] (.toUpperCase message))
;; Clojure casts message to String and then calls the method.
Каковы некоторые виды использования? Эта форма программирования совершенно новая для меня.
Ответ №1:
- Строки документации хранятся в виде метаданных под ключом :doc. Вероятно, это наиболее очевидное использование метаданных номер 1.
- Типы возвращаемых данных и параметров могут быть дополнительно помечены метаданными, чтобы повысить производительность, избегая накладных расходов на анализ типов во время выполнения. Они также известны как «подсказки по типу».
#^String
это подсказка по типу. - Хранение вещей «под капотом» для использования компилятором, таких как список аргументов функции, номер строки, в которой был определен var, или содержит ли var ссылку на макрос. Обычно они автоматически добавляются компилятором, и пользователю обычно не нужно управлять ими напрямую.
-
Создание простых тестовых наборов как части определения функции:
(defn #^{:test (fn [] (assert true))} something [] nil)
(test #'something)
Если вы читаете Programming Clojure, то глава 2 содержит хорошее введение в метаданные. На рисунке 2.3 представлено хорошее резюме общих метаданных.
Ответ №2:
Для разнообразия какой-нибудь ответ, который не концентрируется на взаимодействии с самим языком:
Вы также можете, например. отслеживать источник некоторых данных. Непроверенный ввод помечен как :tainted
. Средство проверки может что-то проверить, а затем установить статус на :clean
. Код, выполняющий действия, связанные с безопасностью, может затем отключиться :tainted
и принимать :clean
только отредактированный ввод.
Ответ №3:
Метаданные были чрезвычайно полезны для меня при наборе текста. Я говорю не только о подсказках по типу, но и о полной пользовательской системе типов. Простейший пример — перегрузка print-метода для structs (или любого другого var):
(defstruct my-struct :foo :bar :baz)
(defn make-my-struct [foo bar baz]
(with-meta (struct-map my-struct :foo foo :bar baz :baz baz)
{:type ::my-struct}))
(defmethod print-method
[my-struct writer]
(print-method ...))
В целом, вместе с возможностями проверки Clojure это может очень сильно повысить безопасность и, в то же время, гибкость вашего кода (хотя для фактического кодирования потребуется еще некоторое время).
Дополнительные идеи по набору текста см. в разделе types-api.
Ответ №4:
метаданные широко используются компилятором для таких вещей, как хранение типа объекта.
вы используете это, когда даете подсказки по типу
(defn foo [ #^String stringy] ....
Я использовал его для таких вещей, как хранение количества отступов, добавленных к числу. Он предназначен для информации, которая «ортогональна» данным и не должна учитываться при принятии решения о том, совпадают ли ваши значения.