¿Es posible la programación funcional en Java? [cerrado]

42

Estaba navegando por la librería Amazon.com y encontré el libro "Programación funcional para desarrolladores de Java" .

Conozco una programación funcional muy básica y he estado programando en Java durante 3 años.

Me gustaría saber si la programación funcional es incluso posible en Java.

Vinoth Kumar CM
fuente
2
El estilo es posible pero su verbosidad podría ser demasiado difícil de soportar dada la sintaxis de Java: functionaljava.org
Yuriy Zubarev
77
@nCdy ¿Por qué verificar JRuby? Por favor proporcione más explicaciones.
Quirón
1
cheque maravilloso :-)
Ant
66
Creo que este es el tipo de pregunta que plantea la distinción entre Java-the-language y Java-the-platform.
Thomas Owens
2
@ ThorbjørnRavnAndersen: ¿Qué te hace pensar que la "evaluación funcional" define la "programación funcional"? Parece un extraño ejemplo para elegir ...
John Bartholomew

Respuestas:

70

Depende de lo que entiendas por "programación funcional" y por "posible".

Obviamente, puede implementar cosas siguiendo un paradigma funcional. Sin embargo, el lenguaje Java no proporciona el azúcar sintáctico, por lo que algunas cosas serán tediosas en el mejor de los casos, y otras serán extremadamente arcanas.

Del mismo modo, puede escribir muy bien código orientado a objetos en un lenguaje reconocido como no OO, como C.

Bibliotecas Java

Hay bibliotecas que pueden ayudarlo a hacer esto, ya haciendo el trabajo por usted y ocultando las cosas arcanas:

Esto le permitirá escribir código Java con un enfoque más funcional y posiblemente una sintaxis y una semántica más familiares, como es de esperar de un lenguaje competente para FP. Dentro de lo razonable, eso es.

Idiomas JVM

Y, obviamente, puede implementar un lenguaje funcional sobre Java. Para que pueda usar ese como su lenguaje FP. Lo cual es un poco más alto nivel de abstracción de lo que pediste, pero relativamente dentro del contexto (aunque estoy engañando un poco aquí, por supuesto).

Por ejemplo, echa un vistazo a:

Lenguajes JVM más o menos funcionales

Si bien pueden no ser exactamente lo que desea, hay una serie de otros lenguajes que se han portado a la Plataforma Java y que podrían liberarlo de la naturaleza relativamente poco orientada a la diversión de Java (sí, juego de palabras) y ya le brindan más flexibilidad. Los contendientes notables como JRuby , Jython y Rhino (respectivamente para Ruby , Python y JavaScript / ECMAScript ) también ofrecen un potencial interesante para la programación funcional, aunque posiblemente no sean lenguajes de programación realmente funcionales por naturaleza. Kotlin de JetBrains, aunque reconoce claramente que no es un lenguaje funcional, admite algunas construcciones funcionales y también vale la pena echarle un vistazo.

Otras lecturas

También puede leer o mirar estos artículos o videos:

haylem
fuente
2
El código fuente de Clojure ahora está alojado en Github github.com/clojure/clojure
Chiron
@The Legend of 1982: Fui más rápido que tu comentario, ya cambié el enlace al sitio oficial clojure.org :) ¡Pero gracias por verlo tan rápido! Es bueno ver a la gente reaccionar rápido.
haylem
También hay ABCL ( common-lisp.net/project/armedbear ), pero no tengo idea de dónde cae en la escala madura / no madura y es una implementación de Common Lisp.
Vatine
@Vatine: interesante, nunca había oído hablar de él. Tendré un vistazo rápido y lo agregaré.
haylem
1
Me encanta el término de Alan Perlis "Turing Tarpit" por tratar de hacer algo que un lenguaje puede hacer (porque está completo) pero solo con tanto dolor y complejidad que no debería intentarse.
itsbruce
11

Estoy leyendo el libro que mencionaste. Es realmente bueno por cierto.

Sí, es posible ser funcional en Java. No sé hasta qué punto puede lograrlo, pero puede implementar muchos modismos de programación funcional.

Una de las cosas más importantes es tratar de codificar con la mentalidad "No mutar estados".

Por ejemplo, utiliza la palabra clave final para lograr la inmutabilidad. Si va a utilizar una estructura de datos, debe codificar en estructuras de datos inmutables. La biblioteca Google Guava ya está haciendo esto.

También para la programación concurrente, puede confiar en el marco de Akka (el modelo de actor).

Vale la pena mencionar que el bytecode de JVM no admite (al menos todavía) la optimización de llamadas de cola, una característica muy importante para los lenguajes de programación funcionales.

Quirón
fuente
"Vale la pena mencionar que el bytecode de JVM no admite (al menos todavía) la optimización de llamadas de cola, una característica muy importante para los lenguajes de programación funcionales": ¿Qué quieres decir? Scala tiene TCO.
Giorgio
@Giorgio: Scala hace TCO en tiempo de compilación.
scrwtp
@scrwtp: ¿Hay una penalización de rendimiento debido a eso? ¿O cuáles son las desventajas del TCO en tiempo de compilación?
Giorgio el
@Giorgio: Lo que quise decir es que el bytecode de Java no lo admite de forma nativa, tal como Chiron declaró originalmente. Los lenguajes funcionales funcionan a su alrededor, compilando llamadas recursivas de cola en bucles, pero es una característica del compilador language-> bytecode, no la JVM.
scrwtp
@scrwtp: La respuesta de Chiron dice "Vale la pena mencionar que el código de bytes JVM no admite (al menos todavía) la optimización de llamadas de cola, una característica muy importante para los lenguajes de programación funcionales". hacer que suene como una implementación de un lenguaje funcional en la JVM está penalizado pero (y parece que estamos de acuerdo en esto) esto no es cierto ya que la optimización de la cola de llamadas puede simularse en el código compilado. Así que estoy de acuerdo con la declaración de Chiron, pero me parece un poco engañosa.
Giorgio el
6

Sí, definitivamente es posible , de la misma manera que es posible en cualquier combinación de entorno de ejecución / lenguaje completo. Incluso puede lograr que funcione bastante bien si sabe lo que está haciendo.

Sin embargo, no estoy seguro de lo sensato que es. En particular, tenga en cuenta que no es particularmente idiomático (es decir, se verá muy extraño, tendrá que hacer algunas cosas poco convencionales y confundir a las personas que están acostumbradas a Java normal)

Terminará con un código de aspecto extraño, por ejemplo, para definir una nueva función:

Function twoStrings=new Function() {
  public Object apply(Object param1) {
    // do something to param1 and return a result
  }
}

Para hacer una programación funcional, normalmente necesita:

  • Funciones de primera clase : fáciles de crear en Java definiendo una clase o interfaz abstracta que representa su "Función" y tiene un método "aplicar" que aplica la función a uno o más parámetros.
  • Cierres : cree una instancia de su objeto de función arriba con los valores cerrados almacenados en los campos finales. Puede usar una clase interna anónima para esto.
  • Una biblioteca de funciones estándar de orden superior : esto es más complicado, sin embargo, aún puede escribir el suyo para arrancar un lenguaje funcional simple en unas pocas horas. Si desea algo más elegante, puede consultar otras bibliotecas funcionales que las personas han creado en Java.

Por lo tanto, es posible como ejercicio e incluso como un interesante proyecto de pasatiempo. Pero realmente desea hacer una programación funcional seria mientras mantiene las ventajas de JVM / acceder a las bibliotecas de Java, entonces Clojure es, con mucho, su mejor opción en mi opinión.

ps ya que el núcleo de Clojure está escrito en Java, en realidad es un ejemplo de caso muy interesante de cómo hacer programación funcional en Java mientras se esconden los detalles desordenados detrás de una nueva y agradable sintaxis de lenguaje moderno. El código fuente de Clojure está en GitHub para aquellos interesados.

mikera
fuente
Curiosamente, he notado que la última versión de IntelliJ IDEA plegará estos anónimos en una forma más compacta para mostrar en el editor. Hace un buen trabajo decente para ocultar la ruft redundante. Por supuesto, todo esto será irrelevante en Java 8.
Ben Hardy
4

Es posible ser algo funcional en Java. Hacerlo es muy doloroso . En lugar de

myList.each { doSomething(it); }

Tienes algo como:

myList.each(new Function() { public void do(Object arg) { something(); }})

Y si desea una verdadera programación funcional, con cierres y funciones como objetos de primera clase, elija otro idioma. Scala, Clojure, Groovy se ejecutan en la JVM y pueden interactuar con las clases de Java heredadas. .

Kevin Cline
fuente
La programación funcional no se trata de usar bloques en lugar de clases anónimas. Java 8 tendrá bloques, por lo que su código publicado se verá más elegante pero no será una programación funcional.
Quirón
@Leyenda: Entiendo eso, pero evidentemente no lo expliqué bien.
Kevin Cline
esto es descuido / descuido. con cualquier idioma, debe definir realmente la función EN ALGUNA PARTE, no puede omitir esa parte. Entonces, Java es casi tan conciso, todo lo que tiene que hacer es hacer que el objeto Function no sea anónimo. Puede hacer esto: Función f = nueva Función () {public void do () {}}; .... entonces ... llame a esa función ... myMethodToCallAFunction (Función f) {f.do ()} ... eso es, bros y brolinis. tratar con él.
Alexander Mills
3

La respuesta es un rotundo "sí, por supuesto", sin embargo, en mi opinión, una de las características más importantes en muchos lenguajes funcionales es el excelente sistema de tipos. Nunca podrá administrar esto en Java usted mismo.

Si desea escribir programas funcionales y aún así quedarse con la JVM, puedo recomendarle a los sospechosos habituales Scala y Clojure que miren a Frege . Frege tiene un sistema de tipo y sintaxis que está muy cerca de Haskell, pero los programas se traducen directamente al código de Java y pueden interactuar con otro código de Java.

Ingo
fuente
2

Bueno, todo tipo de cosas son posibles. Es posible hacer programación orientada a objetos en C; Simplemente no es una muy buena idea.

Java no fue diseñado para FP, por lo que si está tratando de hacer todo en un estilo puramente FP, tendrá problemas. Estarás luchando contra el idioma, en lugar de trabajar con él. Y no solo el lenguaje, también hay todas las maravillosas bibliotecas gratuitas de Java. Así que no vayas por FP puro; tome algunas de las ideas detrás de FP e intégrelas en su código Java, pero comprenda que no puede hacer eso con todas las ideas.

Mike Baranczak
fuente
0

El equipo de OpenJDK lo alienta a descargar sus últimos binarios de OpenJDK 8 y jugar con las nuevas expresiones lambda y los nuevos modismos funcionales introducidos en la API de Colecciones (entre otros). Puede programar en un estilo funcional claro. Consulte "¿Programación funcional en Java?" para una comparación de colecciones JDK8 con bibliotecas pre Java8 como Guava, FunctionalJava y LambdaJ.

JohanN
fuente
-3

Puede parecer posible, pero no será una programación puramente funcional. Puede resultar en una programación imperativa.

No se pregunta por qué se refiere a la posible programación funcional mencionada por haylem. Aquí está:

Depende de lo que entiendas por "programación funcional" y por "posible".

La programación funcional no puede tener diferentes definiciones o significado, aunque puede tener muchas explicaciones.
Al igual que OOP, podemos preguntar "¿qué quieres decir con OOP?".
Definitivamente habrá muchas explicaciones, pero solo se referirá a un objetivo, el objetivo de OOP.
Lo mismo se aplica a la programación funcional .

Cuando decimos significado funcional, los programas consisten en funciones.
El papel de las funciones es devolver un argumento / parámetro evaluado (el argumento es variable, la expresión vino cuando se llamó a la función, mientras que el parámetro es variable, que es parte de la declaración de la función).

También las funciones siempre devolverán el mismo resultado cuando se pasan los mismos argumentos. De esa manera es más fácil evitar errores o depurar errores futuros. Mediante la programación funcional podemos evitar efectos secundarios como modificar la variable global.

ejemplo en JavaScript:

function increment(lis){
    return lis.map(
        function (x){
            return x+2;
        }
    );
}

var myList = [4, 7, 2, 3];
console.log(increment(myList));
console.log(myList);

El incremento de la función agrega 1 valor a cada uno de los elementos dentro del objeto y devuelve el resultado. El valor de myList no cambió, pero cuando llamamos a las funciones vimos el valor agregado a los elementos de ese objeto.

Como respuesta a mi es la programación funcional posible en Java? , Creo que no es posible tener una verdadera programación funcional en java. Porque Java está realmente diseñado para ser POO en el que extiende la programación imperativa y la mejora para mantenerla. Cuando el estado de un objeto, variable, etc., ha cambiado, eso ya es una programación imperativa.

L34Rn3R
fuente