Programação Funcional em C# — Parte 01
Fala pessoal, tudo joia 😁? Resolvi escrever este artigo como forma de compartilhar o que eu puder aprender no curso Aplicando Princípios Funcionais em C#, do professor Vladimir Khorikov, no Pluralsight 🤓.
Bom, vamos lá 🚀!
Programação funcional é mais um conceito de paradigma de desenvolvimento, assim como outros que já existem como Orientação a Objetos e Estruturada. Mas o que isso significa? Basicamente, paradigmas de desenvolvimento é uma forma de expressar como é organizado o código.
Bom, no paradigma funcional, em modo geral, quebramos nossos processamentos em várias funções menores onde cada uma é executada após outra, em sequência. Com isso, podemos dizer que esse paradigma se resume em consistir múltiplas funções, as quais trabalham de maneira unificada para a resolução de algum desafio.
🚨Mas não é apenas ter funções que você está aderindo este paradigma… programção funcional é uma programação com funções matemáticas!
Antes de continuarmos, vamos ver alguns conceitos deste paradigma 📚:
— Lembrando que ainda não entramos em nada com relação ao C#
Composição de Funções
Criação de uma nova função a partir da junção de outras, como:
Funções Puras
Também conhecido como funcões matemáticas. É quando uma função é transparente. Mas o que isso significa? Para uma mesma entrada sempre terá uma mesma saída.
Abaixo temos uma função matemática:
E nesta outra não temos. Devido que o valor data é mutável, com isso, para uma mesma entrada nem sempre teremos uma mesma saída:
Imutabilidade
Dados imutáveis são aqueles dados que não sofrem alteração durante o processamento do seu sistema. Muitas vezes chamamos isso de constantes, como o exemplo abaixo:
Mas, também, podemos estender esse conceito por todo nosso código. Como por exemplo, caso tenhamos algum objeto, o mesmo pode sofrer alterações durante o processamento. Nesse caso, nunca alteramos o estado original desse objeto, para cada alteração cria-se um novo objeto com o novo valor específico, conforme mostra abaixo:
Ao verificar se é uma idade legal, ou seja, se a pessoa/usuário possui maior de 18 anos, por exemplo, é atribuído esse valor/booleano na propriedade “IsLegalAge”, porém não alteramos o objeto original, sempre é criado um novo, mantendo todos os estados criados. Isso é uma vantagem, pois caso deseja-se verificar algum estado específico ou retornar a algum estado específico, é possível. No meu ponto de vista, esta ideia vai muito ao encontro de como o Redux (do React, para quem é mais familiarizado) funciona, a sua proposta, de controlar todo o estado da aplicação.
Uma maneira “errada” de realizar isso, é a forma que costumamos a ver no dia-a-dia, que seria:
Onde o estado original é alterado, com isso, perdemos a rastreabilidade de estados anteriores, o objeto em si mudou.
Com a imutabilidade você garante que o estado seja transparente, pois você consegue saber exatamente como tudo está, ver toda a linha cronológica de algum objeto e, ainda, te permite fazer o timeless debugging.
Estado compartilhado
Permitir acessar o valor de alguma variável em vários pontos da aplicação, mesmo em diferentes escopos.
Side Effects
Side Effects seria caracterizado por toda interação com o meio externo, como alteração no banco de dados e chamada de APIs.
Bom, contextualizando… em desenvolvimento de software, os dados mudam de maneira constante, mas uma das premissas da programação funcional é a imutabilidade, então como fica? Não há como fugir totalmente da imutabilidade, o que podemos fazer é tentar isolar o máximo possível e confinar os Side Effects. Com isso, podemos dizer que esses pontos de seu código são as funções impuras, onde lidão com a comunicação externa, manipulando dados mutáveis.
O que podemos concluir até agora?
Desvantagens:
- Em linguagens que não foram feitas para atender, especificamente, o paradigma funcional, podemos ter problemas de processamento e memória. Pois, no caso da imutabilidade, onde cada alteração gera um novo estado, para o C#, por exemplo, acarretaria em um novo objeto sendo criado na memória. Mas não se desespere, vamos ver como contornar isso, e tornar esse paradigma viável! 🤩
Vantagens:
- Como falamos que o paradigma funcional possui conceitos como imutabilidade e o estado compartilhado, tal situação pode nos ajudar a resolver diversos problemas, do dia-a-dia, com relação ao paralelismo. Onde podemos assumir que se você utiliza programação funcional, o seu código será Thread-Safe.
- Código funcional é mais conciso, simples e transparente, com isso podemos exaltar um aumento de produtividade tanto na escrita quanto na leitura de códigos.
- Por fim, consegue-se mitigar bugs. Com programação funcional, você consegue escrever testes mais concisos, sem ter a necessidade de escrever o mesmo teste para N casos distintos. Como as funções são funções matemáticas, um único teste consegue cobrir as funções e, consequentemente, seu código, garantindo uma confiabilidade maior e diminuindo as chances de haver bugs.
Agora que vimos alguns conceitos de Programação Funcional e um breve vislumbre de como utilizá-la em C#, vamos partir para o próximo capítulo, onde iremos aprofundar em alguns conceitos e já os colocar em prática! 🤓