Скрытые функции Clojure
Какие менее известные, но полезные функции Clojure вы найдете сами? Не стесняйтесь делиться небольшими трюками и идиомами, но пытайтесь ограничить себя Core и Contrib.
Я нашел очень интересную информацию в ответах на эти похожие вопросы:
Есть много вопросов "Скрытая функция" для других языков, поэтому я подумал, что было бы неплохо иметь один для Clojure тоже.
Ответы
Ответ 1
Clojure имеет неизменный, постоянный тип данных очереди, PersistentQueue, но он еще не имеет литературного синтаксиса или Clojure обертки, поэтому вам нужно создать его через Java-вызов. Queues conj (push) на задней панели и поп с фронта с хорошей производительностью.
user> (-> (clojure.lang.PersistentQueue/EMPTY)
(conj 1 2 3)
pop)
(2 3)
Выводит список на фронт и поп спереди. Векторы соединяются сзади и поп сзади. Таким образом, очереди иногда нужны именно вам.
user> (-> ()
(conj 1 2 3)
pop)
(2 1)
user> (-> []
(conj 1 2 3)
pop)
[1 2]
Ответ 2
(defn foo [a & [b c]] ...)
Вы можете разрушить аргумент rest.
Update:
Последняя фиксация в git repo (29389970bcd41998359681d9a4a20ee391a1e07c) позволила выполнить ассоциативное деструктурирование следующим образом:
(defn foo [a & {b :b c :c}] ...)
Очевидное использование этого - для аргументов ключевого слова. Обратите внимание, что этот подход не позволяет смешивать аргументы ключевого слова с аргументами отдыха (не для того, чтобы что-то очень часто нужно было).
(defn foo [a & {:keys [b c] :or {b "val1" c "val2"}] ...)
Если вам нужны значения по умолчанию для аргументов ключевого слова.
Ответ 3
Макрос чтения чтения: #=
(read-string "#=(println \"hello\")")
Этот макрос может представлять угрозу безопасности, если read
используется для ввода пользователем (что, пожалуй, является плохой идеей). Вы можете отключить этот макрос, установив *read-eval*
в false
.
Ответ 4
Вы можете apply
использовать бесконечные последовательности аргументов. Например
(apply concat (repeat '(1 2 3)))
создает ленивую последовательность 1,2,3,1,2,3... Конечно, для этого для работы функция также должна быть ленивой относительно своего списка аргументов.
Ответ 5
Из все более и более хорошего сайта ClojureDocs используется идиома с использованием juxt
http://clojuredocs.org/clojure_core/clojure.core/juxt
;juxt is useful for forking result data to multiple termination functions
(->> "some text to print and save to a file"
((juxt
println
(partial spit "useful information.txt"))))