Ouvi muita conversa sobre o uso de linguagens funcionais como Haskell ultimamente. Quais são algumas das grandes diferenças, prós e contras da programação funcional versus programação orientada a objetos?
Ouvi muita conversa sobre o uso de linguagens funcionais como Haskell ultimamente. Quais são algumas das grandes diferenças, prós e contras da programação funcional versus programação orientada a objetos?
Respostas:
Eu diria que é mais Programação Funcional vs Programação Imperativa .
A maior diferença é que a programação imperativa é sobre fluxo de controle, enquanto a programação funcional é sobre fluxo de dados . Outra maneira de dizer isso é que a programação funcional usa apenas expressões, enquanto na programação imperativa são usadas expressões e instruções .
Por exemplo, na programação imperativa , variáveis e loops são comuns ao lidar com o estado, enquanto na programação funcional o estado é tratado através da passagem de parâmetros, o que evita efeitos colaterais e atribuições.
Pseudocódigo imperativo para uma função para calcular a soma de uma lista (a soma é mantida em uma variável):
int sumList(List<int> list) {
int sum = 0;
for(int n = 0; n < list.size(); n++) {
sum = sum + list.get(n);
}
return sum;
}
Pseudocódigo funcional para a mesma função (a soma é passada como parâmetro):
fun sumList([], sum) = sum
| sumList(v::lst, sum) = sumList(lst, v+sum)
Eu recomendo a apresentação Taming Effects with Functional Programming, de Simon Peyton-Jones, para uma boa introdução aos conceitos funcionais.
A programação funcional é baseada em um modelo declarativo e tem suas raízes no cálculo lambda. Ele oferece muitos conceitos excelentes que podem ser emprestados de linguagens mais importantes, como C ++ e C #.
Alguns exemplos incluem transparência referencial, funções lambda, funções de primeira classe, avaliação preguiçosa e ansiosa e imutabilidade.
Se por nada mais, aprender programação funcional é útil para os conceitos que ela contém. Isso mudará a maneira como você faz a programação e pensa em programação. E eu acho que no futuro a programação funcional será tão importante quanto a programação orientada a objetos.
Para começar, você pode optar por usar uma linguagem funcional pura como Haskell ou uma híbrida como F # .
A maioria das boas universidades cobrirá programação funcional e, se você for à escola, eu sugiro que você faça esse curso.
Quais são algumas das grandes diferenças, prós e contras da programação funcional versus programação orientada a objetos?
A programação orientada a objetos é boa, pois permite modelar seu problema complexo em hierarquias para simplificar o problema. Mas fica muito difícil quando você começa a considerar a programação multithread enquanto usa objetos mutáveis. Nesses casos, você precisa usar muito objetos de sincronização e é quase impossível aperfeiçoar um aplicativo grande.
É aí que entra a programação funcional. Por causa de coisas como a imutabilidade, a programação funcional realmente simplifica os programas multiencadeados. Torna quase trivialmente fácil paralelizar algo quando você sabe que, dada a entrada X para uma função, ela sempre gera Y. Além disso, você sabe que uma variável (ou valor na programação funcional) não pode alterar o uso intermediário de outro encadeamento.
(Esta resposta é adaptada de uma resposta para uma pergunta fechada no StackOverflow .)
Uma das grandes diferenças entre programação funcional e programação orientada a objetos é que cada uma é melhor em 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 o seu Código evolui, 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.
Linguagens funcionais são boas quando você tem um conjunto fixo de coisas e, à medida que seu código evolui, você adiciona novas operações principalmente à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.
Não há real versus. Eles podem ser perfeitamente complementares. Existem idiomas FP, que suportam OOP. Mas as comunidades diferem na maneira como lidam com a modularidade.
Usuários de linguagens FP tendem a obter modularidade através de leis matemáticas. E prefira provas para mostrar conformidade com suas leis.
Em operações imperativas de POO, os usuários tendem a capturar o comportamento do objeto nos casos de teste, que podem ser executados novamente se o objeto tiver sido alterado e alcançar desta maneira a modularidade.
É apenas um aspecto pequeno, mas acho que vale a pena mencionar.
Uma analogia:
Você recebeu uma solicitação de emprego. Você preenche seu nome, informações de contato e histórico de trabalho. Quando terminar, você não terá mais um aplicativo em branco.
Agora imagine agora que, antes de escrever, você o cobre com uma folha clara de celofane. Você escreve seu nome. Você adiciona outra folha de celofane. Você escreve suas informações de contato. Mais celofane. Você escreve seu histórico de trabalho. Quando terminar, você ainda terá o aplicativo em branco intocado. Você também tem três folhas de celofane, cada uma capturando o efeito de uma única mudança discreta.
O primeiro (OOP) abraça a idéia de mudar as coisas no lugar, enquanto o último (FP) evita. Ambos são paradigmas de gerenciamento de estado. Ambos podem, usando estratégias diferentes, capturar o efeito de concluir uma solicitação de emprego. OOP altera o instrumento de partida diretamente, enquanto FP sobrepõe o que veio antes para afetar a aparência da mudança .