Me preguntaba si hay alguna forma de sacar eso en Java. Creo que no es posible sin soporte nativo para cierres.
88
Me preguntaba si hay alguna forma de sacar eso en Java. Creo que no es posible sin soporte nativo para cierres.
Respuestas:
Java 8 (lanzado el 18 de marzo de 2014) admite currying. El código Java de ejemplo publicado en la respuesta por missingfaktor se puede reescribir como:
... lo cual es bastante agradable. Personalmente, con Java 8 disponible, veo pocas razones para usar un lenguaje JVM alternativo como Scala o Clojure. Proporcionan otras características de lenguaje, por supuesto, pero eso no es suficiente para justificar el costo de transición y el soporte más débil de IDE / herramientas / bibliotecas, en mi opinión.
fuente
(def adder5 (partial + 5)) (prn (adder5 4)) (prn adder5 6)
La aplicación parcial y currizada es absolutamente posible en Java, pero la cantidad de código requerido probablemente lo desanime.
Algún código para demostrar el curry y la aplicación parcial en Java:
FWIW aquí es el equivalente Haskell del código Java anterior:
fuente
Hay muchas opciones para Currying con Java 8. El tipo de función Javaslang y jOOλ ofrecen Currying listo para usar (creo que esto fue un descuido en el JDK), y el módulo Cyclops Functions tiene un conjunto de métodos estáticos para Currying JDK Functions y referencias de métodos. P.ej
'Currying' también está disponible para los consumidores. Ej. Para devolver un método con 3 params, y 2 de los ya aplicados hacemos algo similar a esto
Javadoc
fuente
currying
en elCurry.curryn
código fuente.EDITAR : A partir de 2014 y Java 8, la programación funcional en Java ahora no solo es posible, sino que tampoco es fea (me atrevo a decir que hermosa). Vea, por ejemplo, la respuesta de Rogerio .
Respuesta anterior:
Java no es la mejor opción si va a utilizar técnicas de programación funcional. Como escribió missingfaktor, tendrá que escribir una gran cantidad de código para lograr lo que desea.
Por otro lado, no está restringido a Java en JVM; puede usar Scala o Clojure, que son lenguajes funcionales (Scala es, de hecho, funcional y OO).
fuente
Curry requiere devolver una función . Esto no es posible con java (sin punteros de función) pero podemos definir y devolver un tipo que contiene un método de función:
Ahora vamos a curry en una simple división. Necesitamos un divisor :
y una DivideFunction :
Ahora podemos hacer una división al curry:
fuente
Bueno, Scala , Clojure o Haskell (o cualquier otro lenguaje de programación funcional ...) son definitivamente LOS lenguajes a utilizar para curry y otros trucos funcionales.
Habiendo dicho eso, es ciertamente posible curry con Java sin las super cantidades de repetición que uno podría esperar (bueno, tener que ser explícito sobre los tipos duele mucho, solo eche un vistazo al
curried
ejemplo ;-)).Las pruebas de abajo exhibir tanto, currying una
Function3
enFunction1 => Function1 => Function1
:así como la aplicación parcial , aunque no es realmente seguro en este ejemplo:
Esto está tomado de una prueba de concepto que acabo de implementar por diversión antes de JavaOne mañana en una hora "porque estaba aburrido" ;-) El código está disponible aquí: https://github.com/ktoso/jcurry
La idea general podría expandirse a FunctionN => FunctionM, con relativa facilidad, aunque la "seguridad de tipos real" sigue siendo un problema para el ejemplo de aplicación de partia y el ejemplo de currying necesitaría una gran cantidad de código repetitivo en jcurry , pero es factible.
En general, es factible, pero en Scala está listo para usar ;-)
fuente
Se puede emular el curry con Java 7 MethodHandles: http://www.tutorials.de/threads/java-7-currying-mit-methodhandles.392397/
fuente
Sí, mira el ejemplo de código por ti mismo:
Este es un ejemplo simple en el que curriedAdd es una función de curry que devuelve otra función, y esto se puede usar para la aplicación parcial de parámetros almacenados en curried, que es una función en sí misma. Esto ahora se aplica completamente cuando lo imprimimos en la pantalla.
Además, más adelante puede ver cómo puede usarlo en una especie de estilo JS como
fuente
Una versión más de las posibilidades de Java 8:
También puede definir métodos de utilidad como este:
Lo que le brinda una sintaxis posiblemente más legible:
fuente
Siempre es posible cursar un método en Java, pero no lo admite de forma estándar. Tratar de lograr esto es complicado y hace que el código sea bastante ilegible. Java no es el lenguaje apropiado para esto.
fuente
Otra opción está aquí para Java 6+
entonces podrías lograr curry de esta manera
fuente
Si bien puede hacer Currying en Java, es feo (porque no es compatible) En Java es más simple y rápido usar bucles simples y expresiones simples. Si publica un ejemplo de dónde usaría curry, podemos sugerir alternativas que hacen lo mismo.
fuente
2 * ?
En Java, haría esto con un bucle.Esta es una biblioteca para curry y aplicación parcial en Java:
https://github.com/Ahmed-Adel-Ismail/J-Curry
También admite la desestructuración de Tuples y Map.Entry en parámetros de método, como por ejemplo pasar un Map.Entry a un método que toma 2 parámetros, por lo que Entry.getKey () irá al primer parámetro y Entry.getValue () irá por el segundo parámetro
Más detalles en el archivo README
fuente
La ventaja de usar Currying en Java 8 es que le permite definir funciones de alto orden y luego pasar una función de primer orden y argumentos de función de una manera elegante y encadenada.
A continuación se muestra un ejemplo de Cálculo, la función derivada.
fuente
Sí, estoy de acuerdo con @ Jérôme, curring en Java 8 no es compatible de forma estándar como en Scala u otros lenguajes de programación funcional.
fuente