Ответ 1
"Бриллиантовая палочка" из Библиотека Swiss Arrows будет делать то, о чем вы просите:
(-<> 0
(* <> 5)
(vector 1 2 <> 3 4))
; => [1 2 0 3 4]
Тем не менее, это не то, что вам нужно часто (или когда-либо в моем опыте Clojure)
Примечание: это НЕ о concurrency. Речь идет о макросе потока.
Я знаю, что ->
помещает объект во вторую позицию, а ->>
помещает аргумент в последнюю позицию.
Теперь, мне любопытно, очень похоже на короткую нотацию для #( ... % )
для функций, есть ли короткая нотация для потоков, которая позволяет мне разместить аргумент в произвольном месте?
Цель заключалась бы в том, что вместо того, чтобы иметь фиксированное местоположение для потока, который должен выполняться... Я могу писать произвольные формы и вставлять %% в специальные места, а %% - туда, где поток вставлен.
Спасибо!
"Бриллиантовая палочка" из Библиотека Swiss Arrows будет делать то, о чем вы просите:
(-<> 0
(* <> 5)
(vector 1 2 <> 3 4))
; => [1 2 0 3 4]
Тем не менее, это не то, что вам нужно часто (или когда-либо в моем опыте Clojure)
Теперь в Clojure имеется обобщенный макрос потоковой передачи, так как он называется as- > .
Этот твит дает пример того, как он работает: https://twitter.com/borkdude/status/302881431649128448
(as-> "/tmp" x
(java.io.File. x)
(file-seq x)
(filter (memfn isDirectory) x)
(count x))
Сначала "x" привязан к "/tmp", и из него делается файл. "x" снова возвращается к результирующему файлу, а через функцию "file-seq" и т.д.
В случае, если кто-то еще сталкивается с этим, есть причина, по которой предоставленные макросы существуют, но произвольного места размещения нет: последний приведет к плохому дизайну API.
Макрос ->
помещает аргумент в первую позицию. Это соответствует функциям, которые работают над каким-либо предметом аргумента, например, conj
, assoc
.
Макрос ->>
помещает аргумент в последнюю позицию. Это соответствует функциям, которые работают над последовательностями, например, map
, reduce
.
Создайте свои API-интерфейсы хорошо, и вам вряд ли понадобится такой макрос.
Там была библиотека, которая предоставила эту функцию, но я забыл, где. Возможно, это было в устаревшем clojure -contrib. Это был макрос -$>
.
Но вы можете получить один из clojure core - > macro, чтобы создать тот, который вы ищете:
(defmacro -$>
([x] x)
([x form] (if (seq? form)
(with-meta (map #(if (= %1 '$) x %1) form) (meta form))
(list form x)))
([x form & more] `(-$> (-$> ~x ~form) [email protected])))
И используйте $для указания точки вставки:
user=> (-$> 2 str (identity $) (println $))
2
nil
Технически вы можете использовать несколько $
в одной форме. Но эта реализация страдает от расширения одной и той же формы несколько раз (в обмен на простоту).