Подтвердить что ты не робот

Обобщенный макрос Threading в Clojure

Примечание: это НЕ о concurrency. Речь идет о макросе потока.

Я знаю, что -> помещает объект во вторую позицию, а ->> помещает аргумент в последнюю позицию.

Теперь, мне любопытно, очень похоже на короткую нотацию для #( ... % ) для функций, есть ли короткая нотация для потоков, которая позволяет мне разместить аргумент в произвольном месте?

Цель заключалась бы в том, что вместо того, чтобы иметь фиксированное местоположение для потока, который должен выполняться... Я могу писать произвольные формы и вставлять %% в специальные места, а %% - туда, где поток вставлен.

Спасибо!

4b9b3361

Ответ 1

"Бриллиантовая палочка" из Библиотека Swiss Arrows будет делать то, о чем вы просите:

(-<> 0
 (* <> 5)
 (vector 1 2 <> 3 4))
; => [1 2 0 3 4]

Тем не менее, это не то, что вам нужно часто (или когда-либо в моем опыте Clojure)

Ответ 2

Теперь в 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" и ​​т.д.

Ответ 3

В случае, если кто-то еще сталкивается с этим, есть причина, по которой предоставленные макросы существуют, но произвольного места размещения нет: последний приведет к плохому дизайну API.

Макрос -> помещает аргумент в первую позицию. Это соответствует функциям, которые работают над каким-либо предметом аргумента, например, conj, assoc.

Макрос ->> помещает аргумент в последнюю позицию. Это соответствует функциям, которые работают над последовательностями, например, map, reduce.

Создайте свои API-интерфейсы хорошо, и вам вряд ли понадобится такой макрос.

Ответ 4

Там была библиотека, которая предоставила эту функцию, но я забыл, где. Возможно, это было в устаревшем 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

Технически вы можете использовать несколько $ в одной форме. Но эта реализация страдает от расширения одной и той же формы несколько раз (в обмен на простоту).