Programação funcional vs programação orientada a objetos [fechada]

784

Fui exposto principalmente à programação OO até agora e estou ansioso para aprender uma linguagem funcional. Minhas perguntas são:

  • Quando você escolhe a programação funcional em vez de orientada a objetos?
  • Quais são as definições típicas de problemas em que a programação funcional é uma escolha melhor?
Olivier Lalonde
fonte
isso é relevante programmers.stackexchange.com/questions/9730/…
kirill_igum
1
A questão semelhante cs.se também fechou o que é exemplo em que a programação funcional fornece melhores resultados do que o estilo imperativo . a sabedoria convencional parece ser que um não é superior ao outro, ou que não são comparáveis ​​em critérios simples, ou que são usados ​​para propósitos diferentes ... a programação funcional tem mais origens e usos científicos / acadêmicos e é menos comum na indústria , portanto, a questão também cria um ponto de vista / conflito não resolvido "indústria versus academia". um ref clássico que sytle mostra OOP na programação funcional, SICP livro / MIT
vzn
" OO torna o código compreensível, encapsulando as partes móveis. O FP torna o código compreensível, minimizando as partes móveis. " - Micheal Feathers, 2010
jaco0646 17/03

Respostas:

1193

Quando você escolhe a programação funcional em vez de orientada a objetos?

Quando você antecipa um tipo diferente de evolução de software:

  • Linguagens orientadas a objeto são bons quando você tem um conjunto fixo de operações sobre as coisas , e como seus evolui de código, você adiciona principalmente coisas novas. Isso pode ser conseguido adicionando novas classes que implementam métodos existentes, e as classes existentes são deixadas em paz.

  • Os idiomas funcionais são bons quando você tem um conjunto fixo de coisas e, à medida que seu código evolui, você adiciona principalmente novas operações às coisas existentes. Isso pode ser conseguido adicionando novas funções que computam com tipos de dados existentes, e as funções existentes são deixadas em paz.

Quando a evolução segue o caminho errado, você tem problemas:

  • Adicionar uma nova operação a um programa orientado a objetos pode exigir a edição de muitas definições de classe para adicionar um novo método.

  • Adicionar um novo tipo de coisa a um programa funcional pode exigir a edição de muitas definições de funções para adicionar um novo caso.

Esse problema é bem conhecido há muitos anos; em 1998, Phil Wadler o chamou de "problema de expressão" . Embora alguns pesquisadores pensem que o problema da expressão pode ser resolvido com recursos de linguagem como mixins, uma solução amplamente aceita ainda não foi atingida.

Quais são as definições típicas de problemas em que a programação funcional é uma escolha melhor?

Linguagens funcionais se destacam na manipulação de dados simbólicos em forma de árvore. Um exemplo favorito é de compiladores, onde os idiomas de origem e intermediários raramente mudam (principalmente as mesmas coisas ), mas os escritores do compilador estão sempre adicionando novas traduções e aprimoramentos ou otimizações de código (novas operações). Geralmente, compilação e tradução são "aplicativos matadores" para idiomas funcionais.

Norman Ramsey
fonte
119
Há algum zen sério por trás dessa resposta. Eu acho que isso ilustra o fato de que certos padrões de design de OOP (Visitor) são na verdade hacks que tentam superar o problema de adicionar novas operações.
Jacobs Data Solutions
54
Em JavaScript, você pode ter todas as coisas.
Erik Reppen
61
@ErikReppen em que ponto surge a pergunta, quando você escolhe usar os recursos funcionais e quando escolhe usar os recursos orientados a objetos?
Norman Ramsey
7
@NormanRamsey Não é incomum misturar tudo em JS e funções de primeira classe estão ligadas a muitos recursos relacionados ao JS OOP. A classificação da matriz do JS assume funções como um argumento que pode produzir algumas estruturas de dados poderosas. Closures + uma função passada é usada para manter objetos jquery muito leves para falar com a memória, já que a maioria dos métodos são apenas referências. Etc ...
Erik Reppen
9
@ NormanRamsey: Resposta muito boa, na linha do SICP. De acordo com essa classificação, a programação funcional e processual são agrupadas no lado oposto da programação orientada a objetos. Isso poderia explicar o boom do POO no final dos anos 80: quando as GUIs se tornaram populares OOP provou ser uma boa abordagem para modelá-las, porque você normalmente tem um conjunto fixo de operações (pintar, abrir, fechar, redimensionar) e um número crescente de widgets. Obviamente, isso não significa que o POO seja melhor do que o procedimento para qualquer aplicativo, como você ilustrou.
Giorgio
177

Você não precisa necessariamente escolher entre os dois paradigmas. Você pode escrever software com uma arquitetura OO usando muitos conceitos funcionais. FP e OOP são ortogonais por natureza .

Tome, por exemplo, C #. Você poderia dizer que é principalmente OOP, mas existem muitos conceitos e construções de FP. Se você considerar o Linq , as construções mais importantes que permitem a existência do Linq são funcionais por natureza: expressões lambda .

Outro exemplo, F #. Você poderia dizer que é principalmente FP, mas existem muitos conceitos e construções de OOP disponíveis. Você pode definir classes, classes abstratas, interfaces, lidar com herança. Você pode até usar a mutabilidade quando isso torna seu código mais claro ou quando aumenta drasticamente o desempenho.

Muitas línguas modernas são multiparadigma.

Leituras recomendadas

Como estou no mesmo barco (experiência OOP, aprendendo FP), sugiro algumas leituras que realmente apreciei:

Bruno Reis
fonte
8
@duffymo: seu comentário, do jeito que você diz, é praticamente inútil. Ninguém quer uma comparação de idiomas, máquinas virtuais ou plataformas, obrigado.
Bruno Reis
6
@Bruno - uma resposta ao "poder do .NET". relaxar.
duffymo
6
Engraçado, não vejo você repreendendo Dykam por seu comentário inútil. Você foi indicado como moderador enquanto eu não estava olhando? Ninguém está em chamas aqui, exceto você. Vou dizer de novo - relaxe.
duffymo
4
Heh, desculpe se eu comecei a pegar fogo. Eu não quis dizer que outras plataformas são menos poderosas, apenas que o .NET não suporta apenas OOP. Por exemplo, possui otimização de chamada de cauda.
dykam
5
@nawfal, até que você possa apontar algumas características intrínsecas nos dois paradigmas e dizer que são incompatíveis, são ortogonais: esse é o cerne da discussão. FP é incompatível com programação imperativa por definição, mas OOP não se limita à programação imperativa. A razão pela qual temos palavras diferentes para esses conceitos é para podermos falar sobre eles: quando você os reúne, você apenas nos força a inventar desnecessariamente novas palavras.
DavidS
31

A Programação Orientada a Objetos oferece:

  1. Encapsulamento, para
    • controle de mutação do estado interno
    • limitar o acoplamento à representação interna
  2. Subtipagem, permitindo:
    • substituição de tipos compatíveis (polimorfismo)
    • um meio bruto de compartilhar a implementação entre classes (herança de implementação)

A programação funcional, em Haskell ou mesmo em Scala, pode permitir a substituição por meio de um mecanismo mais geral das classes de tipos. O estado interno mutável é desencorajado ou proibido. O encapsulamento da representação interna também pode ser alcançado. Veja Haskell vs OOP para uma boa comparação.

A afirmação de Norman de que "adicionar um novo tipo de coisa a um programa funcional pode exigir a edição de muitas definições de funções para adicionar um novo caso". depende de quão bem o código funcional empregou classes de tipo. Se a Correspondência de Padrões em um determinado Tipo de Dados Abstratos estiver espalhada por uma base de código, você realmente sofrerá com esse problema, mas talvez seja um projeto ruim para começar.

EDITED Removida referência a conversões implícitas ao discutir classes de tipos. No Scala, as classes de tipo são codificadas com parâmetros implícitos, não conversões, embora as conversões implícitas sejam outro meio de obter a substituição de tipos compatíveis.

2 rotações
fonte
3
As classes de tipos não são um mecanismo para conversão implícita em outros tipos. Eles são uma descrição de um conjunto de funções definidas para um tipo, a fim de fornecer uma forma de polimorfismo. O mais próximo do OOP no estilo Java seria as interfaces, embora as classes de tipo Haskell tenham algumas diferenças importantes.
Zak
25
  1. Se você estiver em um ambiente altamente concorrente, a programação funcional pura será útil. A falta de estado mutável torna a concorrência quase trivial. Veja Erlang.

  2. Em uma linguagem multiparadigm, você pode modelar algumas coisas funcionalmente se a existência de estado mutável for um detalhe de implementação e, portanto, FP é um bom modelo para o domínio do problema. Por exemplo, consulte as compreensões da lista em Python ou std.range na linguagem de programação D. Estes são inspirados pela programação funcional.

dsimcha
fonte