Quanto mais programação funcional eu faço, mais eu sinto que ela adiciona uma camada extra de abstração que parece como a camada de uma cebola é - tudo abrangendo as camadas anteriores.
Eu não sei se isso é verdade, de acordo com os princípios de OOP com os quais trabalhei há anos, alguém pode explicar como funcional representa ou não com precisão qualquer um deles: Encapsulamento, Abstração, Herança, Polimorfismo
Eu acho que todos podemos dizer, sim, ele tem encapsulamento via tuplas, ou tuplas contam tecnicamente como fato de "programação funcional" ou são apenas uma utilidade da linguagem?
Eu sei que Haskell pode atender ao requisito "interfaces", mas novamente não tenho certeza se o método é um fato funcional? Eu estou supondo que o fato de que os functores tenham uma base matemática, você poderia dizer que esses são definitivamente construídos na expectativa do funcional, talvez?
Por favor, especifique como você acha que funcional cumpre ou não os 4 princípios do POO.
Edit: Eu entendo muito bem as diferenças entre o paradigma funcional e o paradigma orientado a objetos e percebo que existem muitas linguagens multiparadigmas nos dias de hoje que podem fazer as duas coisas. Estou realmente procurando definições de como o fp (pense purista, como o haskell) pode fazer uma das quatro coisas listadas ou por que não pode fazer nenhuma delas. ie "O encapsulamento pode ser feito com fechamentos" (ou, se eu estiver errado nessa crença, indique o motivo).
fonte
Respostas:
A programação funcional não é uma camada acima do POO; é um paradigma completamente diferente. É possível fazer POO em um estilo funcional (o F # foi escrito exatamente para esse propósito) e, do outro lado do espectro, existem coisas como Haskell, que rejeita explicitamente os princípios da orientação a objetos.
Você pode fazer o encapsulamento e a abstração em qualquer idioma avançado o suficiente para suportar módulos e funções. OO fornece mecanismos especiais para encapsulamento, mas não é algo inerente ao OO. O ponto de OO é o segundo par que você mencionou: herança e polimorfismo. O conceito é formalmente conhecido como substituição de Liskov, e você não pode obtê-lo sem o suporte no nível da linguagem para programação orientada a objetos. (Sim, é possível falsificá-lo em alguns casos, mas você perde muitas das vantagens que o OO traz para a mesa.)
A programação funcional não se concentra na substituição de Liskov. Ele se concentra em aumentar o nível de abstração e em minimizar o uso de estados e rotinas mutáveis com "efeitos colaterais", que é um termo que programadores funcionais gostam de usar para criar rotinas que realmente fazem algo (em vez de simplesmente calcular algo) som assustador. Mas, novamente, eles são paradigmas completamente separados, que podem ser usados juntos ou não, dependendo da linguagem e da habilidade do programador.
fonte
Acho a seguinte intuição útil para comparar OOP e FP.
Em vez de considerar o FP como um superconjunto do OOP, pense em OOP e FP como duas maneiras alternativas de olhar para um modelo de computação subjacente semelhante no qual você tem:
No POO, isso é capturado por
No FP, isso é capturado por
Com essa interpretação, um objeto pode ser visto como uma coleção de fechamentos (seus métodos), todos capturando as mesmas variáveis não locais (as variáveis de membro do objeto comuns a todos os fechamentos na coleção). Essa visão também é suportada pelo fato de que, em linguagens orientadas a objetos, os fechamentos geralmente são modelados como objetos com exatamente um método.
Penso que os diferentes pontos de vista se originam do fato de que a visão orientada a objetos está centrada nos objetos (os dados), enquanto a visão funcional está centrada nas funções / fechamentos (as operações).
fonte
Depende de quem você pede uma definição de POO. Pergunte a cinco pessoas e você provavelmente terá seis definições. A Wikipedia diz :
Portanto, sempre que alguém der uma resposta definitiva, leve-a com um pouco de sal.
Dito isto, há um bom argumento a ser dito que, sim, FP é um superconjunto de POO como paradigma. Em particular, a definição de Alan Kay do termo programação orientada a objetos não contradiz essa noção (mas a de Kristen Nygaard ). Tudo o que Kay estava realmente preocupado era que tudo é um objeto e essa lógica é implementada passando mensagens entre objetos.
Talvez o mais interessante seja a sua pergunta: classes e objetos podem ser pensados em termos de funções e fechamentos retornados por funções (que atuam como classes e construtores de uma só vez). Isso se aproxima muito da programação baseada em protótipo e, de fato, o JavaScript permite fazer exatamente isso.
(É claro que o JavaScript permite a mutação de valores que são ilegais na programação puramente funcional, mas nem é necessária em uma definição estrita de OOP.)
A questão mais importante, porém, é: esta é uma classificação significativa de OOP? É útil pensar nisso como um subconjunto de programação funcional? Eu acho que na maioria dos casos, não é.
fonte
FP como OO não é um termo bem definido. Existem escolas com definições diferentes, às vezes conflitantes. Se você considera o que eles têm em comum, você se resume a:
programação funcional é programação com funções de primeira classe
A programação OO é a programação com polimorfismo de inclusão combinado com pelo menos uma forma restrita de sobrecarga resolvida dinamicamente. (Uma observação: nos círculos OO, o polimorfismo é geralmente considerado como polimorfismo de inclusão , enquanto nas escolas de FP geralmente significa polimorfismo paramétrico .)
Tudo o resto está presente em outro lugar ou ausente em alguns casos.
FP e OO são duas ferramentas de construção de abstrações. Cada um deles tem seus próprios pontos fortes e fracos (por exemplo, eles têm uma direção de extensão preferida diferente no problema de expressão), mas nenhum é intrinsecamente mais poderoso que o outro. Você pode criar um sistema OO sobre um kernel FP (o CLOS é um desses sistemas). Você pode usar uma estrutura OO para obter funções de primeira classe (veja como as funções lambda são definidas no C ++ 11, por exemplo).
fonte
std::function
, ao qual os ponteiros de função e lambdas podem ser atribuídos, é decididamente genérico, não orientado a objetos. Isso não é surpresa, porque o tipo limitado de polimorfismo da orientação a objetos (polimorfismo de subtipo) é estritamente menos poderoso que o polimorfismo paramétrico (mesmo Hindley-Milner, e muito menos o Sistema F-ômega).Não; OOP pode ser visto como um superconjunto de programação procedural e difere fundamentalmente do paradigma funcional porque possui estado representado nos campos de instância. No paradigma funcional, as variáveis são funções que são aplicadas nos dados constantes para obter o resultado desejado.
Na verdade, você pode considerar a programação funcional um subconjunto de OOP; se você tornar todas as suas classes imutáveis, poderá considerar que possui algum tipo de programação funcional.
fonte
Responda:
A Wikipedia tem um ótimo artigo sobre Programação Funcional com alguns dos exemplos que você solicita. @ Konrad Rudolph já forneceu o link para o artigo da OOP .
Não acho que um paradigma seja um superconjunto do outro. São perspectivas diferentes sobre programação e alguns problemas são melhor resolvidos de uma perspectiva e alguns de outra.
Sua pergunta é ainda mais complicada por todas as implementações de FP e OOP. Cada idioma possui suas próprias peculiaridades, relevantes para qualquer boa resposta à sua pergunta.
Divagações cada vez mais tangenciais:
Gosto da ideia de que uma linguagem como Scala tente oferecer o melhor dos dois mundos. Eu me preocupo que isso lhe dê as complicações dos dois mundos também.
Java é uma linguagem OO, mas a versão 7 adicionou um recurso "try-with-resources" que pode ser usado para imitar um tipo de fechamento. Aqui, ele imita a atualização de uma variável local "a" no meio de outra função, sem torná-la visível para essa função. Nesse caso, a primeira metade da outra função é o construtor ClosureTry () e a segunda metade é o método close ().
Saída:
Isso pode ser útil para o objetivo de abrir um fluxo, gravar no fluxo e fechá-lo de forma confiável ou simplesmente emparelhar duas funções de uma maneira que você não se esqueça de chamar a segunda depois de fazer algum trabalho entre elas. . Obviamente, é tão novo e incomum que outro programador possa remover o bloco try sem perceber que está quebrando alguma coisa; portanto, atualmente é um tipo de antipadrão, mas interessante que isso possa ser feito.
Você pode expressar qualquer loop nas linguagens mais imperativas como uma recursão. Objetos e variáveis podem ser imutáveis. É possível escrever procedimentos para minimizar os efeitos colaterais (embora eu argumentasse que uma função verdadeira não é possível em um computador - o tempo necessário para executar e os recursos de processador / disco / sistema que consome são efeitos colaterais inevitáveis). Algumas linguagens funcionais podem ser feitas para realizar muitas, senão todas, operações orientadas a objetos. Eles não precisam ser mutuamente exclusivos, embora alguns idiomas tenham limitações (como não permitir nenhuma atualização de variáveis) que impedem certos padrões (como campos mutáveis).
Para mim, as partes mais úteis da programação orientada a objetos são a ocultação de dados (encapsulamento), o tratamento de objetos semelhantes o suficiente (polimorfismo) e a coleta de dados e métodos que operam nesses dados juntos (objetos / classes). A herança pode ser o carro-chefe da OOP, mas para mim é a parte menos importante e menos usada.
As partes mais úteis da programação funcional são imutabilidade (tokens / valores em vez de variáveis), funções (sem efeitos colaterais) e fechamentos.
Não acho que seja orientado a objetos, mas devo dizer que uma das coisas mais úteis na ciência da computação é a capacidade de declarar uma interface e, em seguida, ter várias peças de funcionalidade e dados para implementar essa interface. Também gosto de ter alguns dados mutáveis para trabalhar, então acho que não me sinto totalmente à vontade em linguagens exclusivamente funcionais, mesmo que tente limitar a mutabilidade e os efeitos colaterais em todos os meus projetos de programas.
fonte