• Aprendendo F# - Apresentando

    07 de janeiro de 2018

O paradigma de programação funcional não é nenhuma novidade no mundo da Engenharia de Software, tão pouco as linguagens ditas funcionais, mas nos últimos anos temos visto uma ascensão desses princípios e linguagens tornando impossível ignorar essa tendência.

Dentro do universo Microsoft o F# nasceu como linguagem funcional oficial da plataforma .NET, derivada de uma tentativa mal sucedida de adaptar o Haskell para o CLR. Então nasceu esse novo idioma, fortemente inspirado pelo OCaml, uma das descendentes do Haskell. Esse é um exemplo clássico onde uma falha foi transformada em algo muito maior do que a idéia inicial.

A linguagem F# faz parte do primeiro escalão do .NET há muitos anos, mas eu sempre a ignorei por considerar o C#, linguagem mais da plataforma, uma das mais evoluídas e completas do mercado. Afinal, para que sair da zona de conforte de uma linguagem que já domino para me aventurar num terreno totalmente novo onde terei de re-aprender a fazer tarefas que já domino? Esse é o dilema que todo programador enfrenta quando é apresentando uma nova tecnologia ou um novo paradigma, e é o que vou tentar responder nessa série de artigos.

Por que o F# importa?

A linguagem F# esta longe de ser uma das mais conhecidas no mundo do desenvolvimento de software comercial, e seu berço na Microsoft certamente lhe rende uma certa (e infundada) resistencia dentro do meio academico. Quando surgiu o .NET Framework com o objetivo de ser a plataforma na qual todas as linguagens iriam compilar, os responsáveis por adaptar a linguagem Haskell encontraram grande dificuldade em adata-la. Nascia o F#, o projeto de linguagem funcional oficial do .NET, tirando proveito de todo o poder do CLR em uma linguagem super poderosa.

O que parecia uma brincadeira do time de pesquisadores da Microsoft, ganhou tração e importância, e hoje o desenvolvimento da linguagem é tratado com a mesma importância do C#, principal linguagem do universo .NET. Há muito tem me chamado atenção o crescimento da adoção e popularidade da linguagem, mas só recentemente dei a devida atenção e estou começando a entender porque há tantos olhares voltados para esse paradigma.

O F# é oficialmente suportado no .NET Core e na Plataforma Xamarin, os dois carros da Microsoft. Além disso tem recebido cada mais suporte dentro das ferramentas de desenvolvimento, crescendo em recursos e facilidades. Algumas das vantagens do F#:

  • Simplicidade e expressividade: a chave das linguagens funcionais esta em sua capacidade de executar tarefas extremamente comuns de programação com poucos comandos. Assim o foco fica no que e não no como.
  • Interoperabilidade completa com o .NET Framework: com o F# você tem acesso a todos os recursos disponíveis na plataforma .NET, o BCL e todo o ecossistema de pacotes e bibliotecas. Como todo o código F# é compilado para CLR ele também pode ser consumido em qualquer lugar na plataforma.
  • Concisão: a capacidade de expressar uma idéia de maneira mais concisa faz com que os programas fiquem menores, mais fáceis de ler, entender e dar manutenção.
  • Menos propenso a erros: na esteira das vantagens de concisão acabamos tendo um software menos propenso a erros já que reduzimos a complexidade acidental, aquela derivada das operações que não fazem parte do problema que precisamos (como gerencimaneto de memória por exemplo).

Mas mais do que tentar listar vantagens subjetivas, minha experiência com o F# tem um apelo muito prático: Ela torna meu trabalho mais simples, me deixa mais produtivo e acelera a velocidade de entrega! Esse para mim é o aspecto mais relevante a parte de qualquer discussão de preferência por uma vertente ou outra.

Show me the code!

Nenhum artigo que fale sobre uma linguagem de programação esta completo sem bons exemplos de código, então vamos entrar de cabeça no F# com alguns exemplos. A operação mais básica da linguagem é a criação de values (valores), feito através da expressão let:

Assim criamos um novo identificador para a string representando meu nome. Para quem vem do universo Orientado a Objeto é muito fácil fazer um paralelo entre essa declaração e a criação de variáveis, porém no F# um valor é imutável por padrão, o que significa que não pode ser modificado depois de criado:

A imutabilidade é um dos princípios básicos básicos da programação funcional. Eu sei que ele não faz muito sentido pra quem como eu veio do mundo dos objetos e da programação imperativa, mas com o tempo começa a fazer sentido e se torna natural. Futuramente vamos explorar melhor os por ques disso. Usando a mesma instrução também é bem fácil declarar uma lista de elementos:

O F# oferece uma série de construções que facilitam a criação de listas, sequências e arrays, os 3 tipos básicos de coleções de dados com que a linguagem trabalha. Note que no exemplo dos números usamos um recurso chamado comprehension, que permite usar uma função para gerar uma lista de elementos. Nesse caso usamos o operador range, que retorna uma lista de números de 1 a 10.

Note como nos exemplos anteriores não há uma nenhuma especificação de tipo de dado, o que pode confundir os iniciantes em achar que o F# é uma linguagem de tipos dinâmicos, o que não é o caso. Construída sobre o .NET Framework, ela é fortemente tipada como as demais linguagens da plataforma, porém sua inferência de tipo é muito mais sofisticada do que no C#. Se desejarmos explicitar o tipo podemos declarar os values da seguinte forma:

Linguagens funcionais não recebem esse nome por acaso. Funções são sua unidade estrutural básica, ou seja, pensamos nossos programas em termos de um conjunto de funções que transformam os nossos dados. Declarar uma função é tão simples quanto:

Note como para criação de funções usamos a mesma expressão let. Isso é porque em F# as funções são consideradas “cidadãos de primeira classe” da linguagem. Esse é um outro princípio básico de linguagens funcionais que traz benefícios importantes como a possibilidade de passar funções como argumentos. Isso será importante quando explorarmos High Order Functions, que são funções que recebem outras funções como parâmetro para personalizar seu comportamento. Um exemplo disso seria o uso de uma função para filtrar elementos em uma lista:

Nesse exemplo criamos a função isOddNumber como um predicate (uma função que retorna um valor booleano). Ela será passada como parâmetro da função List.filter que irá aplicá-la para cada elemento da lista numbers. Quando a função retorna verdadeiro o valor é inserido em uma nova lista. Ao final o valor oddNumbers contém uma nova lista apenas com os números ímpares. Por último usamos List.iter para executar uma função em cada elemento da lista, o que seria equivalente a um loop for…each nas linguagens tradicionais.

Também é bastante simples criar tipos para expressar modelos de dados complexos. Os Records são a estrutura básica do F# para isso. Podemos por exemplo declarar um tipo para representar um livro:

Criar uma lista de livros:

E filtrar apenas aqueles lançados antes do novo milênio:

Note como o F# foi capaz de determinar o tipo dos elementos da lista através da inferência, sabendo que um Book é constituido das propriedades Title, Author e Year e seus respectivos tipos. Também exemplificamos a construção for…in, mais familiar para programadores de linguagens orientadas a objeto (mas menos comuns em linguagens funcionais).

Não se preocupe se a sintaxe da linguagem não fizer sentido para você num primeiro momento. Trata-se de um paradigma completamente diferente e no qual a maioria dos desenvolvedores atuais não foi treinado. Estamos acostumados a olhar para nossos código da forma imperativa, onde estamos a todo momento instruindo a linguagem como fazer as coisas, passo a passo. O objetivo da programação funcional é descrever de maneira mais objetiva o que desejamos fazer, sem se preocupar tanto com cada passo necessário para que isso aconteça.

Eu prometo a você que se tiver um pouco de paciência e persevarança em muito pouco tempo a sintaxe funcional não só fará muito mais sentido como se tornará muito mais natural e desejável, o que provavelmente vai motivá-lo se não a migrar para uma linguagem como o F#, a pelo menos aplicar boa parte dos seus conceitos em outras linguagens imperativas que já suportam conceitos semelhantes.

Conclusão

Nesse artigo entramos de cabeça no F# e vimos alguns exemplos das construções mais triviais da linguagem. Nos próximos artigos vou me aprofundar no conhecimento da linguagem, nos conceitos funcionais e de como ela se relaciona com outras linguagens do universo .NET. Também pretendo mostrar aplicações práticas de como podemos usa-la no dia-a-dia para construir qualquer tipo de aplicação, especialmente mobile que é foco do nosso trabalho. 🙂

O código desse artigo esta disponível no GitHub.

Share

Desenvolvedor de aplicações, administrador de bancos de dados e gerente de projetos em uma ampla variedade de aplicativos de negócios, utilizando modernas metodologias e ferramentas de ALM e processos Agile. Me considero um entusiasta em tecnologia, com mais de 10 anos de experiência nesse mercado. Atualmente voltado para o mercado mobile, me especializei no desenvolvimento de aplicações para as principais plataformas do mercado (Android, iOS e Windows Phone), e em organizar e ministrar de treinamentos para desenvolvedores.

Leia também

Novidades do C# 7 – Out Variables
C#
27 de abril de 2017

Novidades do C# 7 – Out Variables

Nessa série de artigos vamos explorar as novidades introduzidas na versão 7 da linguagem C#. Lançada no último mês de março junto com o Visual Studio 2017, no qual a nova linguagem pode ser utilizada, também podendo ser testada com o Xamarin Workbooks tanto em Windows como em macOS, método que escolhi para escrever os […]

LEIA MAIS
Novidades do C# 7 – Tuplas
C#
26 de abril de 2017

Novidades do C# 7 – Tuplas

Nessa série de artigos vamos explorar as novidades introduzidas na versão 7 da linguagem C#. Lançada no último mês de março junto com o Visual Studio 2017, no qual a nova linguagem pode ser utilizada, também podendo ser testada com o Xamarin Workbooks tanto em Windows como em macOS, método que escolhi para escrever os […]

LEIA MAIS
Novidades do C# 7 – Local Functions
C#
05 de maio de 2017

Novidades do C# 7 – Local Functions

Nessa série de artigos vamos explorar as novidades introduzidas na versão 7 da linguagem C#. Lançada no último mês de março junto com o Visual Studio 2017, no qual a nova linguagem pode ser utilizada, também podendo ser testada com o Xamarin Workbooks tanto em Windows como em macOS, método que escolhi para escrever os […]

LEIA MAIS

Comentários