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.