programacion lambdas funciones expresiones ejemplos creador clojure

clojure - lambdas - macro-> con funciones anonimas



lambdas java (3)

(Esto se basa en la answer a la pregunta que publiqué en los comentarios).

la macro -> toma cada argumento, haciéndolo una lista si es necesario (aplicando funciones "brutas" a ningún argumento - convirtiendo myfunc a (myfunc) ), y luego inserta el primer argumento en -> como segundo argumento en cada una de esas listas.

así que (-> foo myfunc) convierte en (-> foo (myfunc)) convierte en (myfunc foo) , aproximadamente.

todo esto se describe en los documentos para -> .

El problema con las funciones anónimas es que son generadas por una macro lectora como se describe aquí (desplácese hacia abajo) . eso significa que #(...) se convierte ( antes de la expansión de macro normal) a (fn [...] ...) . que está bien, pero, críticamente, ya es una lista .

por lo que la macro cree que la función anónima ya se está aplicando, cuando en realidad está encontrando una definición de función (ambas son listas). y agregar los parens "extra", como se describe anteriormente en la otra respuesta, aplica la función anónima a ningún argumento.

la razón de este comportamiento no intuitivo es que la heurística dwim (do-what-i-mean, not dwim-witted, aunque ...) utilizada por la macro -> , agregó para permitirle proporcionar funciones "simples" en lugar de Luego de requerir que los aplique a ningún argumento al incluirlos en una lista, es solo una heurística (simplemente prueba una lista) y se confunde con la definición de función creada por la macro del lector.

[en mi opinión de mal humor, -> está mal implementado y debería rechazar todas las funciones "simples", en su lugar solo acepta aplicaciones de funciones; Entonces parecería más consistente. si no, al menos los documentos podrían ser más claros, explicando la semántica motivadora detrás de colocar las cosas en las listas.]

Entiendo que la macro -> in clojure está aplicando todas las funciones proporcionadas al argumento dado. Sin embargo, no parece funcionar con funciones anónimas (en clojure 1.3.0). Por ejemplo:

user> (-> 4 inc inc dec) 5

Pero:

user> (-> 4 #(+ % 1) #(- % 1) #(+ % 1))

Devuelve el error:

clojure.lang.Symbol cannot be cast to clojure.lang.IPersistentVector [Thrown class java.lang.ClassCastException]

Si alguien sabe de alguna manera sería útil. ¡Gracias!


Puedes tener funciones anónimas en macros de Clojure. Tienes problemas porque te faltan algunos paréntesis. :) Su ejemplo se edita a continuación.

(-> 4 (#(+ % 1)) (#(- % 1)) (#(+ % 1)))


Su caso específico podría haber sido resuelto simplemente usando:

(-> 4 (+ 1) (- 1) (+ 1))

donde la primera macro del hilo -> se encarga de insertar el resultado del paso anterior como primer argumento en la función "actual".

La confusión surge del hecho de que -> no es una función sino una macro y los argumentos se tratan de manera muy diferente en este caso como se explica en otras respuestas.