Partilhar via


Programação funcional vs. programação imperativa (LINQ to XML)

Este artigo compara e contrasta a programação funcional com a programação imperativa (processual) mais tradicional.

Programação funcional vs. programação imperativa

O paradigma de programação funcional foi explicitamente criado para suportar uma abordagem funcional pura para a resolução de problemas. A programação funcional é uma forma de programação declarativa. Em contraste, a maioria das linguagens principais, incluindo linguagens de programação orientada a objetos (OOP), como C#, Visual Basic, C++ e Java, foram projetadas para suportar principalmente programação imperativa (processual).

Com uma abordagem imperativa, um desenvolvedor escreve código que especifica as etapas que o computador deve seguir para atingir o objetivo. Isto é por vezes referido como programação algorítmica . Em contraste, uma abordagem funcional envolve compor o problema como um conjunto de funções a serem executadas. Você define cuidadosamente a entrada para cada função e o que cada função retorna. A tabela a seguir descreve algumas das diferenças gerais entre essas duas abordagens.

Characteristic Abordagem imperativa Abordagem funcional
Foco no programador Como executar tarefas (algoritmos) e como controlar alterações no estado. Que informações são desejadas e que transformações são necessárias.
Alterações de estado Importante. Inexistente.
Ordem de execução Importante. Baixa importância.
Controlo do fluxo primário Loops, condicionais e chamadas de função (método). Chamadas de função, incluindo recursão.
Unidade de manipulação primária Instâncias de estruturas ou classes. Funciona como objetos de primeira classe e coleções de dados.

Embora a maioria das linguagens tenha sido projetada para suportar um paradigma de programação específico, muitas linguagens gerais são flexíveis o suficiente para suportar vários paradigmas. Por exemplo, a maioria das linguagens que contêm ponteiros de função pode ser usada para suportar de forma credível a programação funcional. Além disso, C# e Visual Basic incluem extensões de linguagem explícitas para suportar programação funcional, incluindo expressões lambda e inferência de tipo. A tecnologia LINQ é uma forma de programação declarativa e funcional.

Programação funcional usando XSLT

Muitos desenvolvedores XSLT estão familiarizados com a abordagem funcional pura. A maneira mais eficaz de desenvolver uma folha de estilos XSLT é tratar cada modelo como uma transformação isolada e compostável. A ordem de execução é completamente desvalorizada. XSLT não permite efeitos colaterais (com a exceção de que escapar de mecanismos para executar código de procedimento pode introduzir efeitos colaterais que resultam em impureza funcional). No entanto, embora o XSLT seja uma ferramenta eficaz, algumas de suas características não são ideais. Por exemplo, expressar construções de programação em XML torna o código relativamente detalhado e, portanto, difícil de manter. Além disso, a grande dependência da recursão para o controle de fluxo pode resultar em código difícil de ler. Para obter mais informações sobre XSLT, consulte Transformações XSLT.

No entanto, o XSLT provou o valor de usar uma abordagem funcional pura para transformar XML de uma forma para outra. A programação funcional pura com LINQ to XML é semelhante em muitos aspetos ao XSLT. No entanto, as construções de programação introduzidas pelo LINQ para XML, C# e Visual Basic permitem que você escreva transformações funcionais puras que são mais legíveis e fáceis de manter do que XSLT.

Vantagens das funções puras

A principal razão para implementar transformações funcionais como funções puras é que as funções puras são compostas: isto é, autocontidas e apátridas. Estas características trazem uma série de benefícios, incluindo os seguintes:

  • Maior legibilidade e manutenção. Isso ocorre porque cada função é projetada para realizar uma tarefa específica, dados seus argumentos. A função não depende de nenhum estado externo.
  • Desenvolvimento reiterativo mais fácil. Como o código é mais fácil de refatorar, as alterações no design geralmente são mais fáceis de implementar. Por exemplo, suponha que você escreva uma transformação complicada e, em seguida, perceba que algum código é repetido várias vezes na transformação. Se você refatorar através de um método puro, você pode chamar seu método puro à vontade sem se preocupar com efeitos colaterais.
  • Testes e depuração mais fáceis. Como as funções puras podem ser testadas mais facilmente isoladamente, você pode escrever código de teste que chama a função pura com valores típicos, casos de borda válidos e casos de borda inválidos.

Pelas razões descritas acima, a programação funcional é adequada ao estilo arquitetônico de microsserviços.

Transição para desenvolvedores OOP

Na programação orientada a objetos tradicional (OOP), a maioria dos desenvolvedores está acostumada a programar no estilo imperativo/processual. Para passarem a desenvolver-se num estilo puramente funcional, têm de fazer uma transição no seu pensamento e na sua abordagem ao desenvolvimento.

Para resolver problemas, os desenvolvedores OOP projetam hierarquias de classe, concentram-se no encapsulamento adequado e pensam em termos de contratos de classe. O comportamento e o estado dos tipos de objeto são primordiais, e os recursos de linguagem, como classes, interfaces, herança e polimorfismo, são fornecidos para resolver essas preocupações.

Em contraste, a programação funcional aborda problemas computacionais como um exercício na avaliação de transformações funcionais puras de coletas de dados. A programação funcional evita dados mutáveis e de estado e, em vez disso, enfatiza a aplicação de funções.

Felizmente, C# e Visual Basic não exigem o salto completo para a programação funcional, porque eles suportam abordagens de programação imperativa e funcional. Um desenvolvedor pode escolher qual abordagem é mais apropriada para um cenário específico. Na verdade, os programas geralmente combinam ambas as abordagens.

Consulte também