/ csharp-programming

Functional Programming with C# - part 2

Dando continuação ao tópico anterior, vamos prosseguir tratando o asunto da programação funcional em ambiente DotNet com a principal linguagem de programação dele!

Batendo na tecla: Segurança de tipos

Lembra que tivemos um bom bate-papo sobre isso, se bem me recordo no segundo item da postagem, pois bem, vamos entender agora na prática os tipos de coisas que podem acontecer quando não temos uma segurança de tipos, especialmente em sistemas paralelos, para fixar, vem comigo nesse script lá no REPL:

Deu pra entender né? Bom, aqui nós temos aquele clássico exemplo de que o estado mutante de processos concorrentes produz resultados imprevisíveis, o motivo disso tudo? Começando, vamos dissecar o código dos sinppets utilizados na declaração dos valores e consumo de algumas funções.

Caso você não tenha nada de familiaridade com script em C#, fica tranquilo, é literalmente a mesma coisa, só que em uma interface REPL, que você pode consumi-la com dotnet-script, como foi te instruído na postagem anterior.

No começo temos as clássicas diretivas using apontando com um modificador de acesso estático para os namespaces que vamos consumir, que basicamente é as funções estáticas que System.Line.Enumerable possui, junto da função WriteLine() de System.Console.

Com tudo definido, podemos começar a criar os valores que vamos precisar, se você conhece um pouco de Python, já deve ter feito alguma estrutura de repetição for com a linguagem, a função Range(), faz um papel similar a de range() do Python, nesse caso geramos todos os inteiros entre 10000 e -10000. Cuja sua soma logicamente é 0.

O código que vem seguido, aquelas expressões de extensão, servem somente para ordenação dos valores para firmeza do estado da coleção de inteiros, que nesse momento deve ser algo como:

List<int>(20001) { 10000, 9999, 9998, [...]}

Até aqui imagino que você não deve ter notado nenhum problema com o código, porque de fato não é, porém, agora vamos adicionar o elemento que destrói a segurança de uma aplicação, juntamente a mutabilidade de um sistema de tipos.

Quando declaramos task1 e task2, e logo em seguida, as invocamos de maneira paralela com Parallel.Invoke(), temos dois objetos consumindo outro de tipo genérico (List<T>), e não algo definido de forma estática, gerando algo totalmente inesperado: O resultado da soma sempre variando, que no exemplo da imagem, obtivemos um resultado de 86131842!

Resumidamente temos duas estrutura de dados fixas, consumindo uma outra ao mesmo tempo, que é dinâmica e volátil, dai temos esse resultado do capiroto no código!

Mas calma ai, mesmo utilizando algo genérico, que tem uma assinatura de tipo forte, que é List, podemos percorrer o mesmo objeto sem problemas com a approach correta, utilizando uma função pura com LINQ, vamos voltar aquele script e adicionar uma terceira tarefa para ser invocada:

Action task3 = () => WriteLine(nums.OrderBy(x => x).Sum());

Vamos executar esse cara agora (com algumas modificações na verbrosidade da saída):

E vai por mim, não tem macumba ai não, é basicamente o poder de não interferir no que não é seu, isso ai meus amigos, é o que chamamos de função pura, ela não precisa sujar outro objeto (quando estamos no C# vamos ter esse crossover foda entre OOP e FP) com funções que desordenam uma estrutura de tipos mutável, como a função Sort() consumida pela task2.

And...

Vamos agora pensar um pouco, no melhor estilo TeleCurso 2000, não podemos nos limitar em um estilo imperativo, que muda, brinca, faz o que diabos quer com o estado do seu programa, e como se isso não fosse o suficiente, injetam ao código paralelo seu lixo (como a ordenação). Sabe aquelas paradas de ter uma feature sem custo, usando programação funcional desde o inicio do desenvolvimento da sua aplicação em C#, você vai ter algo sem, ou praticamente nulo, em consumo adicional de recursos do sistema hospedeiro!

Genericamente, mesmo no pior dos casos, seu código sempre vai ter um custo menor que o imperativo!

Vamos terminar por aqui mais um capitulo da série, bom, se você gostou, deixa um comentário, compartilha... Se manifeste! Sua opinião é muito importante para mim! Então, até mais senhores!