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 ().
public class ClosureTry implements AutoCloseable {
public static void main(String[] args) {
int a = 1;
try(ClosureTry ct = new ClosureTry()) {
System.out.println("Middle Stuff...");
a = 2;
}
System.out.println("a: " + a);
}
public ClosureTry() {
System.out.println("Start Stuff Goes Here...");
}
/** Interface throws exception, but we don't have to. */
public void close() {
System.out.println("End Stuff Goes Here...");
}
}
Saída:
Start Stuff Goes Here...
Middle Stuff...
End Stuff Goes Here...
a: 2
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.