O documento resume uma apresentação sobre programação funcional usando C#. Apresenta conceitos como value containers e como lidar com resultados e erros de forma funcional usando tipos como Option e Either. Demonstra como refatorar código imperativo para um estilo mais funcional com esses tipos.
1. Globalcode – Open4education
Trilha .NET – Programação funcional usando
C#
Gabriel Schade Cardoso
Microsoft MVP | Software Engineer | Mestre em Computação Aplicada |
Professor | Escritor
2. Globalcode – Open4education
Mestre em computação aplicada a IA
Microsoft MVP – Dev. Technologies
Desenvolvedor, Professor e Revisor
Autor dos livros
Gabriel Schade Cardoso
4. Globalcode – Open4education
Problemas comuns
Quem aqui sabe o que é isso?
ArgumentNullException
DomainException
Essa nem existe na linguagem, mas eu já vi TANTO
5. Globalcode – Open4education
Como essas duas coisas estão
conectadas?
Programação funcional é bem diferente de
programação orientada à objetos;
Podemos aprender muito com F#;
É um paradigma diferente;
6. Globalcode – Open4education
Como essas duas coisas estão
conectadas?
Ao aprender um novo paradigma, você aprende uma
nova forma de ver os problemas.
8. Globalcode – Open4education
Vamos ao problema do null
Ele é um método mentiroso;
A assinatura dele me diz que ele irá retornar um
usuário, mas se o Id for inválido?
10. Globalcode – Open4education
Vamos ao problema do null
Este é um método honesto, ele indica que talvez
ele retorne um usuário;
Ok, mas o que isso muda na nossa vida?
11. Globalcode – Open4education
Vamos ao problema do null
Mas isso não é só um null check obrigatório?
Quase, mas causa erro de compilação.
O erro acontece porque o tipo option é um value container, não o
valor em si.
13. Globalcode – Open4education
Um container pode ser visto como um envelope ou uma caixa
que circunda um objeto/valor, incluindo-o em algum contexto
específico.
Lidamos com este tipo de valor o tempo todo:
List;
Task;
Nullable.
Value Containers
14. Globalcode – Open4education
Imagine o seguinte cenário: você possui um dado do tipo
inteiro e precisa somá-lo com o valor 3.
Value Containers
16. Globalcode – Open4education
Não podemos realizar a soma com o mesmo valor, isso por
conta do contexto que o cerca.
Por isso, comumente temos uma função para remover o valor
de seu contexto.
Value Containers
17. Globalcode – Open4education
No caso do array podemos utilizar o indexador para remover
um valor do contexto.
Value Containers
18. Globalcode – Open4education
Geralmente utilizamos as funções Map/Filter/Reduce ou
Select/Where/Aggregate, mas também podemos utilizar uma
comparação de padrões (pattern matching).
Podemos nos aproveitar deste conceito para criar novos
objetos e classes que armazenam valores sob um determinado
contexto.
Value Containers
19. Globalcode – Open4education
Option<T>
Que tal criar um Option para o C#?
1. O tipo não pode assumir o valor null;
2. Precisamos de uma maneira de extrair a informação do
contexto;
3. Não deixaremos o programador acessar a informação, caso ela
esteja no estado inválido;
26. Globalcode – Open4education
Value Containers
E se precisássemos de validações mais complexas?
Existem mais value containers além do Option!
Either<TLeft, TRight>
...
Vamos refatorar uma funcionalidade que atualiza um usuário
34. Globalcode – Open4education
Atualizando um usuário
Como as exceções não estão sendo tratadas, acabamos
sempre retornando um erro 500.
Este HTTP code não deve ser utilizado para isso, precisamos
retornar um 400 (bad request).
Onde colocar esse tratamento?
36. Globalcode – Open4education
Atualizando um usuário
Algo deu errado, o código não deveria ficar assim estranho.
Vamos tentar produzir esse resultado, mas sem try-catches:
38. Globalcode – Open4education
Atualizando um usuário
Precisamos continuar enviando o resultado para frente, mesmo
se algo deu errado, dessa forma não quebramos o fluxo de
código.
Vamos fazer mais um container, dessa vez para representar
um resultado para a continuação de uma operação.
40. Globalcode – Open4education
Atualizando um usuário
Notem que as propriedades de nossa classe só possuem um
método get, ou seja, todas elas são readonly;
Precisamos de construtores!
42. Globalcode – Open4education
Com nosso novo container já é possível retornar um resultado!
Vamos começar adaptando a função Update!
Criando um novo tipo
43. Globalcode – Open4education
Return em dois locais diferentes?
Ainda usamos try-catch?
Vamos quebrar as validações do banco em métodos separados
Criando um novo tipo
57. Globalcode – Open4education
Atualizando um usuário
A solução ainda está bem estranha!
Esses If’s não estão legais...
E se a struct de continuação oferecer uma forma de
continuarmos a expressão?
58. Globalcode – Open4education
Atualizando um usuário
Vamos criar os métodos Then e Catch;
Eles recebem uma função por parâmetro e retornam uma
estrutura de continuação!
63. Globalcode – Open4education
Atualizando um usuário
Neste ponto você já deve ter percebido que estamos sempre
atualizando o continuation, certo?
Mas como o próprio método já o retorna, podemos utilizar
uma sintaxe encadeada!
Além disso, podemos utilizar um match para finalizar e
retornar o resultado!