macros clojure

macros - Macro Roscado General en Clojure



(4)

Nota: esto NO se trata de concurrencia. Esto es sobre la macro de hilo.

Sé que -> coloca el objeto en la segunda posición y ->> pone el argumento en la última posición.

Ahora, tengo curiosidad, al igual que la notación de mano corta de #( ... % ) para funciones, ¿hay una notación de mano corta para hilos que me permite colocar el argumento en una ubicación arbitraria ?

El objetivo sería que, en lugar de tener una ubicación fija para la ejecución del hilo ... Puedo escribir formularios arbitrarios e insertar %% en lugares especiales, y el %% es donde se inserta el hilo.

¡Gracias!


Ahora hay una macro de subprocesamiento generalizada en Clojure desde 1.5 llamada as-> .

Este tweet da un ejemplo de cómo funciona: https://twitter.com/borkdude/status/302881431649128448

(as-> "/tmp" x (java.io.File. x) (file-seq x) (filter (memfn isDirectory) x) (count x))

Primero ''x'' está obligado a "/ tmp" y se crea un archivo. ''x'' vuelve a rebotar en el archivo resultante y se pone a través de la función ''archivo-seq'', etc.


En caso de que alguien más se dé cuenta de esto, existe una razón por la cual existen las macros proporcionadas, pero una ubicación arbitraria no existe: esto último llevaría a un diseño de API deficiente.

La macro -> coloca el argumento en la primera posición. Esto corresponde a las funciones que trabajan en algún argumento de tema, por ejemplo, conj , assoc .

La macro ->> coloca el argumento en la última posición. Esto corresponde a funciones que funcionan en secuencias, por ejemplo, map , reduce .

Diseña bien tus API, y es menos probable que necesites ese macro.


Había una biblioteca que proporcionaba esta característica, pero olvidé dónde. Podría haber estado en el obsoleto clojure-contrib. Era la macro -$> .

Pero podría derivar una de la macro de clojure -> macro para hacer la que está buscando:

(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) ~@more)))

Y usa $ para indicar el punto de inserción:

user=> (-$> 2 str (identity $) (println $)) 2 nil

Técnicamente, podría usar varios $ en una forma. Pero esta implementación sufre de expandir la misma forma varias veces (a cambio de simplicidad).


La ''varita de diamante'' de la biblioteca Swiss Arrows haría lo que estás pidiendo:

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

Dicho esto, no es algo que termines necesitando a menudo (o nunca en mi experiencia Clojure)