A Programação Funcional é possível em Java? [fechadas]

42

Eu estava navegando pela Livraria Amazon.com e me deparei com o livro "Programação Funcional para Desenvolvedores Java" .

Conheço algumas Programação Funcional muito básica e venho programando em Java há 3 anos.

Gostaria de saber se a Programação Funcional é possível em Java?

Vinoth Kumar CM
fonte
2
O estilo é possível, mas a sua verbosidade poderia ser demais para suportar dada a sintaxe do Java: functionaljava.org
Yuriy Zubarev
7
@nCdy Por que verificar o JRuby? forneça mais explicações.
Chiron
1
verifique groovy :-)
Ant's
6
Eu acho que esse é o tipo de pergunta que levanta a distinção entre Java, a linguagem, e Java, a plataforma.
Thomas Owens
2
@ ThorbjørnRavnAndersen: O que faz você pensar que "programação funcional" é definida por "avaliação lenta"? Parece um exemplo ímpar para escolher ...
John Bartholomew

Respostas:

70

Depende do que você quer dizer com "programação funcional" e "possível".

Obviamente, você pode implementar as coisas seguindo um paradigma funcional. No entanto, a linguagem Java não fornece o açúcar sintático para isso; portanto, algumas coisas serão tediosas na melhor das hipóteses e outras serão extremamente misteriosas.

Da mesma forma, você pode muito bem escrever código orientado a objetos em uma linguagem reconhecida como não OO, como C.

Bibliotecas Java

Existem bibliotecas que podem ajudá-lo a fazer isso, já fazendo o trabalho braçal para você e ocultando as coisas misteriosas:

Isso permitirá que você escreva código Java com uma abordagem mais funcional e, possivelmente, com sintaxe e semântica mais familiares, como seria de esperar de uma linguagem compatível com FP. Dentro da razão, é isso.

Idiomas da JVM

E, obviamente, você pode implementar uma linguagem funcional sobre Java. Para que você possa usá-lo como sua linguagem FP. O que é um nível de abstração um pouco mais alto do que o solicitado, mas relativamente dentro do contexto (embora eu esteja trapaceando um pouco aqui, sem dúvida).

Por exemplo, confira:

Idiomas da JVM mais ou menos funcionais

Embora eles possam não ser exatamente o que você deseja, existem várias outras linguagens que foram portadas para a plataforma Java e que podem libertá-lo da natureza relativamente não tão divertida (sim, trocadilhos) do Java e já oferecem mais flexibilidade. Candidatos notáveis ​​como JRuby , Jython e Rhino (respectivamente para Ruby , Python e JavaScript / ECMAScript ) também oferecem um potencial interessante para programação funcional, embora, sem dúvida, não sejam realmente linguagens de programação funcionais por natureza. Kotlin da JetBrains, embora reconheça claramente que não é uma linguagem funcional, suporta algumas construções funcionais e também merece uma olhada.

Leitura adicional

Você também pode ler ou assistir a estes artigos ou vídeos:

haylem
fonte
2
O código fonte do Clojure agora está hospedado no Github github.com/clojure/clojure
Chiron
@ The Legend of 1982: fui mais rápido que o seu comentário, já mudei o link para o site oficial do clojure.org :) Mas obrigado por pegá-lo tão rápido! É bom ver as pessoas reagirem rapidamente.
haylem
Há também o ABCL ( common-lisp.net/project/armedbear ), mas não tenho idéia de onde ele cai na escala madura / não madura e é uma implementação do Common Lisp.
Vatine 08/03/12
@Vatine: interessante, absolutamente nunca tinha ouvido falar disso. Vai dar uma olhada rápida e adicioná-lo.
haylem
1
Adoro o termo de Alan Perlis, "Turing Tarpit", por tentar fazer algo que um idioma pode fazer (porque está completo), mas apenas com tanta dor e complexidade que não deve ser tentado.
itsbruce
11

Estou lendo o livro que você mencionou. É realmente bom BTW.

Sim, é possível ser funcional em Java. Não sei até que ponto você pode alcançá-lo, mas você pode implementar muitos idiomas funcionais de programação.

Uma das coisas mais importantes é tentar codificar com a mentalidade "Não modifique estados".

Por exemplo, você usa a palavra-chave final para obter imutabilidade. Se você for usar uma estrutura de dados, deverá codificar estruturas de dados imutáveis. A biblioteca do Google Guava já está fazendo isso.

Também para programação simultânea, você pode confiar na estrutura Akka (o modelo do ator).

Vale ressaltar que o bytecode da JVM não suporta (pelo menos ainda) a otimização de chamada de cauda, ​​um recurso muito importante para linguagens de programação funcionais.

Quíron
fonte
"Vale ressaltar que o bytecode da JVM não suporta (pelo menos ainda) a otimização de chamada de cauda, ​​um recurso muito importante para linguagens de programação funcionais.": O que você quer dizer? Scala tem TCO.
Giorgio
@Giorgio: Scala faz TCO em tempo de compilação.
scrwtp
@ scrwtp: Existe uma penalidade de desempenho por causa disso? Ou quais são as desvantagens do TCO em tempo de compilação?
Giorgio
@Giorgio: O que eu quis dizer é que o java bytecode não o suporta nativamente, assim como Chiron afirmou originalmente. Linguagens funcionais trabalham em torno dele, compilando chamadas recursivas de cauda em loops, mas é um recurso do compilador language-> bytecode, não da JVM.
scrwtp
@scrwtp: A resposta de Chiron declara "Vale ressaltar que o bytecode da JVM não suporta (pelo menos ainda) a otimização de chamada de cauda, ​​um recurso muito importante para linguagens de programação funcionais". fazer parecer que a implementação de uma linguagem funcional na JVM é penalizada, mas (e parece que concordamos com isso) isso não é verdade, pois a otimização da chamada de cauda pode ser simulada no código compilado. Por isso, concordo com a afirmação de Quíron, mas acho isso um pouco enganador.
Giorgio
6

Sim, é definitivamente possível , da mesma maneira que é possível em qualquer combinação completa de linguagem / ambiente de execução. Você pode até conseguir um bom desempenho se souber o que está fazendo.

Não tenho certeza de como é sensato. Em particular, esteja ciente de que não é particularmente idiomático (isto é, parecerá muito estranho, você terá que fazer algumas coisas não convencionais e confundir as pessoas que estão acostumadas a Java comum)

Você terminará com algum código de aparência estranha, por exemplo, para definir uma nova função:

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

Para executar a programação funcional, você normalmente precisa:

  • Funções de primeira classe - fáceis de criar em Java, definindo uma classe ou interface abstrata que representa sua "Função" e possui um método "aplicar" que aplica a função a um ou mais parâmetros.
  • Encerramentos - crie uma instância do seu objeto de função acima com os valores de fechamento armazenados nos campos finais. Você pode usar uma classe interna anônima para isso.
  • Uma biblioteca de funções padrão de ordem superior - isso é mais complicado, no entanto, você ainda pode escrever o seu próprio código para inicializar uma linguagem funcional simples em poucas horas. Se você quiser algo mais sofisticado, verifique outras bibliotecas funcionais que as pessoas construíram em Java.

Portanto, é possível como um exercício e até um projeto interessante de hobby. Mas você realmente deseja fazer uma programação funcional séria, mantendo as vantagens da JVM / acessando as bibliotecas Java; o Clojure é de longe a sua melhor opção na minha opinião.

ps Como o núcleo do Clojure é realmente escrito em Java, é realmente um exemplo de caso muito interessante de como fazer programação funcional em Java enquanto oculta os detalhes confusos por trás de uma nova e agradável sintaxe da linguagem moderna. O código fonte do Clojure está no GitHub para os interessados.

Mikera
fonte
Curiosamente, notei que a versão mais recente do IntelliJ IDEA dobrará esses macacões anônimos em um formato mais compacto para exibição no editor. Faz um trabalho decente de esconder o lixo redundante. Claro que tudo isso será irrelevante vêm Java 8.
Ben Hardy
4

É possível ser um pouco funcional em Java. Fazer isso é seriamente doloroso . Ao invés de

myList.each { doSomething(it); }

Você tem algo como:

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

E se você deseja uma verdadeira programação funcional, com fechamentos e funções como objetos de primeira classe, escolha outro idioma. Scala, Clojure, Groovy são executados na JVM e podem interagir com as classes Java herdadas. .

Kevin Cline
fonte
A programação funcional não é sobre o uso de blocos em vez de classes anônimas. O Java 8 possui blocos, portanto, seu código postado ficará mais elegante, mas não será uma programação funcional.
Quíron
@ Legend: Eu entendo isso, mas evidentemente não o explicava bem.
kevin Cline
isso é supervisão / insights. em qualquer idioma, você precisa definir a função EM ALGUM LUGAR, você não pode pular essa parte. Portanto, o Java é quase tão conciso, tudo que você precisa fazer é tornar o objeto Function anônimo. Você pode fazer isso: Função f = new Function () {public void do () {}}; .... então ... chame essa função .... myMethodToCallAFunction (Function f) {f.do ()} ... é isso, bros e brolinis. lide com isso.
Alexander Mills
3

A resposta é um retumbante "sim, é claro", mas, na minha opinião, uma das características mais importantes em muitas linguagens funcionais é o excelente sistema de tipos. Você nunca poderá gerenciar isso em Java sozinho.

Se você deseja escrever programas funcionais e ainda assim permanecer na JVM, posso recomendar entre os suspeitos comuns Scala e Clojure a olhar para Frege . O Frege possui um sistema de sintaxe e tipo muito próximo ao Haskell, mas os programas são traduzidos diretamente no código java e podem interagir com outro código java.

Ingo
fonte
2

Bem, todos os tipos de coisas são possíveis. É possível fazer programação orientada a objetos em C; simplesmente não é uma boa ideia.

O Java não foi projetado para FP, portanto, se você estiver tentando fazer tudo em um estilo puramente FP, terá problemas. Você estará lutando contra o idioma, em vez de trabalhar com ele. E não apenas a linguagem - também existem todas as maravilhosas bibliotecas Java gratuitas. Portanto, não use FP puro; pegue algumas das idéias por trás do FP e integre-as ao seu código Java, mas entenda que você não pode fazer isso com todas as idéias.

Mike Baranczak
fonte
0

Você é incentivado pela equipe do OpenJDK a baixar os binários mais recentes do OpenJDK 8 e a brincar com as novas expressões lambda e os novos idiomas funcionais introduzidos na API Collections (entre outros). Você pode programar em um estilo funcional claro. Consulte "Programação funcional em Java?" para uma comparação de coleções JDK8 com bibliotecas pré Java8 como Guava, FunctionalJava e LambdaJ.

JohanN
fonte
-3

Pode parecer possível, mas não será uma programação funcional pura. Pode resultar em programação imperativa.

Não há como perguntar por que ele entende por possível programação funcional, como mencionado por haylem. Aqui está:

Depende do que você quer dizer com "programação funcional" e "possível".

A programação funcional não pode ter definições ou significados diferentes, embora possa ter muitas explicações.
Como OOP, podemos perguntar "o que você quer dizer com OOP?".
Definitivamente, haverá muitas explicações, mas pertencerá apenas a um objetivo, o objetivo da OOP.
O mesmo se aplica à programação funcional .

Quando dizemos significado funcional, os programas consistem em funções.
O papel das funções é retornar um argumento / parâmetro avaliado (argumento é variável, a expressão surgiu ao chamar a função enquanto parâmetro é variável que faz parte da declaração da função).

As funções também sempre retornam o mesmo resultado quando os mesmos argumentos são passados. Dessa maneira, é mais fácil evitar erros ou depurar futuros. Pela programação funcional, podemos evitar efeitos colaterais, como modificar variáveis ​​globais.

exemplo em 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);

O incremento da função adiciona 1 valor a cada elemento dentro do objeto e retorna o resultado. O valor de myList não mudou, mas quando chamamos as funções, vimos o valor agregado aos elementos desse objeto.

Como minha resposta à Programação Funcional é possível em Java? , Acredito que não é possível ter verdadeira programação funcional em java. Porque o java é realmente projetado para ser OOP, no qual estende a programação imperativa e a aprimora para manutenção. Quando o estado de um objeto, variável etc, mudou, isso já é uma programação imperativa.

L34Rn3R
fonte