Quando usar uma linguagem de programação funcional?

90

Em que situações devo escolher usar uma linguagem de programação funcional em vez de uma linguagem orientada a objetos mais detalhada, como C ++, C # ou Java?

Eu entendo o que é programação funcional, o que eu realmente não entendo é para quais tipos de problemas ela é uma solução perfeita?

Alex Baranosky
fonte
Esta pergunta é respondida aqui stackoverflow.com/questions/381685/…
krosenvold
2
Sempre. Ou pelo menos nunca nunca.
Shelby Moore III
1
Com lambdas, C # é quase funcional.
JD de

Respostas:

51

As linguagens funcionais são, na minha opinião, boas principalmente para duas coisas: IAs de jogos e cálculos matemáticos. É bom em IAs de jogos por causa de suas belas manipulações de lista (pelo menos em Lisp e Scheme), e para cálculos matemáticos por causa de sua sintaxe. Scheme, Lisp e Haskell têm uma sintaxe que torna os cálculos matemáticos fáceis de ler. A última coisa que preciso acrescentar é que as linguagens funcionais são linguagens realmente divertidas. Meu curso Scheme foi um dos cursos com que me diverti mais.

Martiert
fonte
2
Depois que superei o fato de que meu cérebro queria explodir na minha primeira semana da aula de compilador que fiz no Scheme, também achei que era muito divertido (e eu fiquei muito melhor nisso hehe)
Alex Baranosky
1
Quais linguagens funcionais você usou para cálculos matemáticos?
Jules
8
Além disso, compiladores! Já ouvi pessoas que escreveram compiladores em Haskell dizer que "nunca mais escreverão um compilador em uma linguagem imperativa".
ShreevatsaR
1
julesjacobs: Usei um pouco de haskell e Scheme para resolver cálculos matemáticos simples. Não sou nada bom nesses idiomas, então tenho um caminho a percorrer para resolver problemas mais complexos. Eu simplesmente não consigo torná-los rápidos o suficiente agora.
martiert
96

Eu mesmo fiz algumas pesquisas sobre isso e pensei em adicionar CONCURRENCY à lista de razões para usar uma linguagem funcional. Veja em algum ponto no futuro próximo a velocidade do processador não será capaz de aumentar usando a mesma tecnologia de CPU. A física da arquitetura não permite.

Então é aí que entra o processamento simultâneo.

Infelizmente, a maioria das linguagens OOP não pode tirar proveito de vários processadores ao mesmo tempo por causa das interdependências entre os dados.

Em linguagens de programação puramente funcionais, o computador pode executar duas (ou muitas mais) funções ao mesmo tempo, porque essas funções não alteram as informações de estado externo.

Aqui está um excelente artigo sobre programação funcional de que você pode gostar.

Alex Baranosky
fonte
38
Eu não diria que a maioria das linguagens OO não pode tirar proveito de um número arbitrariamente grande de processadores. Eu diria que para um programa tirar proveito de muitos processadores ao mesmo tempo de maneira eficiente e confiável, esse programa deve ser organizado de forma que a maioria das unidades de código de computação intensiva se comportem como funções puras. É possível organizar um programa dessa forma na maioria dos idiomas. É mais fácil fazer isso em linguagens funcionais do que em linguagens imperativas (incluindo orientadas a objetos).
Zak
2
Obrigado por vincular esse artigo. Isso realmente ajudou a explicar as coisas para mim.
abc123
13

Um amigo meu citou um de seus professores universitários dizendo algo como o seguinte:

Desenhe uma grade com tipos de dados na parte superior e operações nesses tipos de dados no lado esquerdo. Se você fatiar a grade verticalmente, estará fazendo OO; se você cortar a grade horizontalmente, estará fazendo FP.

Minha resposta é que o FP é uma abordagem completamente viável para a programação com uma gama de aplicações tão ampla quanto OO. Como acontece com qualquer discussão sobre escolha de linguagem de programação, acho que as questões mais importantes são:

  1. Você tem tempo para investir no aprendizado de uma nova notação e uma nova maneira de pensar?
  2. Qual das linguagens que você está considerando tem bibliotecas suficientemente ricas para que você não fique preso a reinventar alguma roda?

Quanto à primeira pergunta, se você está fazendo isso principalmente pelo valor do aprendizado, sugiro que olhe para Haskell , por causa da ampla variedade de materiais de suporte (livros, artigos, comunidade ativa, etc.)

Quanto à segunda pergunta, Haskell tem uma boa variedade de bibliotecas (embora algumas sejam mais maduras do que outras), mas Scala (uma linguagem OO funcional híbrida em execução na JVM) tem as vantagens de que você pode fazer uma transição mais gradual para o estilo funcional , e você tem uma gama completa de bibliotecas acessíveis por Java disponíveis para você.

joel.neely
fonte
Aprendi Scheme na faculdade, então não quero aprender programação funcional apenas por experiência. Prefiro aprender alguma linguagem funcional por razões práticas.
Alex Baranosky
9

Praticamente tudo que você pode fazer no PP pode ser feito no FP, e a mesma coisa ao contrário. É apenas outra maneira de codificar algo - outra perspectiva do problema e uma maneira diferente de resolvê-lo.

No entanto, como poucas pessoas usam FP, o problema é mais sobre a falta de boas bibliotecas, portabilidade / manutenção (uma vez que o mantenedor tem uma chance melhor de entender algo escrito em C ++ do que Scheme), e a falta de documentação e comunidade. Eu sei que existem alguns documentos, no entanto, compare isso com C ++, C # ou Java e você entenderá o que quero dizer.

No entanto, se você realmente deseja fazer FP, pode usar este estilo mesmo em C ++ e C #. Claro, não será um 100% FP se você usar a biblioteca padrão. Infelizmente, não acho que o C # seja otimizado para ser usado com programação funcional e provavelmente criará muitos problemas de desempenho.

Esse é mais um post subjetivo, o que eu acho do FP. Não é uma declaração rigorosa.

usuário35978
fonte
8
“Praticamente tudo que você pode fazer em PP pode ser feito em FP” - Na verdade, é exatamente tudo.
BlueRaja - Danny Pflughoeft
2
@BlueRaja - você está se referindo à Completude de Turing? Nesse caso, o que você diz não segue. Por exemplo, o Game of Life de Conway é Turing Complete, mas você não pode usá-lo para escrever um driver de placa de vídeo como faria em C. Da mesma forma, não vejo nenhum dos jogos mais recentes escritos em Haskell. Pode fazer em FP! = Poderia teoricamente fazer em um FP teórico.
Luigi Plinge
@Luigi Plinge Eu teria que concordar com BlueRaja. Haskellers discutindo alguns drivers Linux escritos em Haskell. Não tenho um link, mas também ouvi que um sistema operacional foi escrito em Haskell (outras linguagens funcionais possíveis também). Quanto aos jogos, não vejo os jogos mais recentes sendo escritos em C # ou Java. Você está insinuando que eles não podem ser usados ​​para tal? Enfim, um exemplo de jogo sendo escrito em FP. Além disso, tenha em mente que a maioria dos meus links são Haskell, uma linguagem PURAMENTE funcional.
austinprete
@PardonMyRhetoric Obviamente, você pode escrever jogos em Haskell e fazer qualquer cálculo, mas a velocidade será várias vezes mais lenta e o uso de memória mais alto. Portanto, um contra-exemplo à afirmação de BlueRaja seria que você não pode escrever "um jogo que é tão rápido e usa tanta memória quanto em C" no FP. Esta é uma questão prática real, não um truque pedante (e não estou a fim de criticar FP - estou programando Scala agora!).
Luigi Plinge
1
@PardonMyRhetoric Também precisa ser FP idiomático. Os benchmarks que você vê que fornecem desempenho de Haskell próximo ao de C são escritos em um estilo unidiomático de "baixo nível" que a maioria dos programadores de Haskell não poderia escrever. Por exemplo, você pode obter um desempenho semelhante simplesmente fazendo sua saída de código Haskell e compilando o código C. Embora inútil. Uma questão prática relacionada é o que "você pode fazer" versus o que "pode ​​/ poderia ser feito". Se algo é muito difícil, realmente não importa muito se é possível em teoria (e "possível" para quem?).
Luigi Plinge
4

Linguagens funcionais são boas em muitas situações. Depende das bibliotecas de uma linguagem funcional específica.

Como você responderia à pergunta "Quando usar uma linguagem de programação orientada a objetos?"?

Jules
fonte
1
"Quando usar uma linguagem de programação orientada a objetos?" Quando você quer modelar algo computacionalmente, por outro lado estou procurando um problema que fp seria a resposta intuitiva, continuo procurando, foi assim que encontrei este post.
Jimjim 01 de
@Arjang Eu acho que a programação funcional teria um uso tremendo em aplicativos de cálculo que só precisam de entrada para gerar saída. Sem mutabilidade e sem iteração
EdgeDev
3

Embora esta seja uma questão bastante subjetiva, eu gostaria apenas de acrescentar que as linguagens funcionais são muito usadas para analisar linguagens específicas de domínio ; a natureza funcional é adequada para analisar gramáticas.

csl
fonte
2
Analisando DSLs? Eu pensei que com macros Lisp e similares, DSLs são implementados como macros, não algo a ser analisado por programas Lisp. YMMV com linguagens não Lisp. :-P
Chris Jester-Young
1

Pelo que vi, é mais uma questão de gosto do que funcionalidade (sem trocadilhos). Na verdade, não há nada em qualquer estilo de linguagem que o torne inerentemente melhor ou pior em tarefas específicas.

TED
fonte
2
@JonHarrop - Importa-se de explicar melhor? Não acho isso tão óbvio, e seria uma pena se você deixasse a impressão de que estava votando contra o meu boosterisim.
TED de
1
A família de linguagens ML foi criada especificamente para metaprogramação com a adição de recursos sofisticados de linguagem, como correspondência de padrões para árvores de manipulação (por exemplo, árvores de expressão). Conseqüentemente, essa família de linguagens é inerentemente muito melhor nessa tarefa específica.
JD
1
@JonHarrop - Vou aceitar isso. No entanto, você está falando de ML, não de linguagens funcionais em geral. Sou um grande crente em DSLs, então certamente não vou argumentar contra o uso de uma linguagem específica para a tarefa exata para a qual foi projetada.
TED de
Hoje, a correspondência de padrões é encontrada em quase todas as linguagens funcionais, incluindo OCaml, F #, Scala, Haskell, Clojure e Erlang. Por exemplo, recentemente construí um mecanismo de regras de negócios sob medida para um cliente com foco em matemática. Isso é 1.000 linhas de F # e é predominantemente um intérprete. Lixar, analisar, verificar o tipo e interpretar a entrada são muito mais fáceis graças à correspondência de padrões.
JD de
@JonHarrop ..mas não todos. Não é uma característica inerente das linguagens funcionais, que é o que a pergunta estava perguntando.
TED de
1

Em geral, use a linguagem em que seja mais fácil expressar a solução para um problema. Para a programação funcional, é quando a solução para um problema é facilmente expressa em termos de funções , daí o nome. Geralmente é bom para operações matemáticas, IA, correspondência de padrões; em geral, qualquer coisa que possa ser decomposta em um conjunto de regras que devem ser aplicadas para obter uma resposta. Você só pode realmente determinar a "melhor" linguagem a ser usada depois de analisar suficientemente o problema. É aqui que o pseudo-código se torna útil. Se você está escrevendo pseudo-código que se parece com FP, use FP.

Claro, todas as linguagens de programação completas são funcionalmente equivalentes, então não importa realmente qual você escolher em termos de quais problemas você pode resolver. Os principais efeitos serão em termos de eficiência e precisão da codificação e facilidade de manutenção.

Observe também que é possível imitar o FP em linguagens OO por meio de APIs inteligentemente projetadas. Por exemplo, eu vi várias bibliotecas Java (JMock é um exemplo) que usam encadeamento de métodos para simular um FP DSL. Em seguida, você verá construções como:

logger.expects(once()).method("error") .with( and(stringContains(action),stringContains(cause)) );

Isso basicamente cria uma função que é avaliada para determinar se alguma sequência de chamada em um objeto simulado está correta. (exemplo roubado de http://www.jmock.org/yoga.html )

Outra sintaxe semelhante ao FP em outras linguagens OO é o uso de encerramentos, como em Ruby.

Phil
fonte
2
"... realmente não importa qual você escolher em termos de quais problemas você pode resolver". Somente se você tiver tempo e dinheiro infinitos para resolver seu problema.
JD
0

Acho que os posts anteriores estão corretos, aqui está uma pequena lista, a programação funcional é uma solução perfeita para o seguinte:

  • processamento sem estado
  • equações matemáticas, incluindo ML (aprendizado de máquina)
  • processos imutáveis
  • quando você quer simultaneidade escalonável
grepit
fonte