Estou dando uma olhada no F#, e uma das primeiras coisas que você percebe é a inferência de tipos. Que é muito legal. Vejam esse código:

let quadrado x = x * x

let somaDosQuadrados nums =
    let mutable total = 0
    for x in nums do
        total <- total + quadrado x
    total

Esse código apresenta uma função que faz o quadrado de um número, na primeira linha. Na terceira linha em diante há uma função que soma quadrados a partir de uma sequência de números.

Atenção: Em nenhum lugar há o tipo do número a ser somado ou elevado ao quadrado, ou que a lista de números, descrito. São inteiros? São doubles? São floats?

Respondendo então: São inteiros. Aqui a prova:

São inteiros!

Recebe uma sequência de inteiros (seq<int>) e retorna um inteiro (-> int).

Eu executo isso na console interativa do F#, e ele me dá o resultado:

image

Inteiros mais uma vez.

Atenção: O F# não é uma linguagem dinâmica. Ele é fortemente tipado com static dispatch. Tudo isso é inferência de tipo.

Como ele sabe? Ele faz a inferência do tipo lendo a função ao contrário. Ele percebe que minha variável “total” é um inteiro, e portanto o retorno da função (dado na última linha, que só tem escrito “total”) só pode ser um inteiro. E para somar na variável total com o resultado da função quadrado, essa função deve retornar também um inteiro. E se ela retorna um inteiro, ela recebe um inteiro também (vejam que a função quadrado recebe x, e retorna x vezes x). E se x, dentro do meu “for”, é um inteiro, a variável nums só pode ser uma sequência de inteiros. Portanto, a função recebe uma sequência de inteiros e retorna um inteiro.

Uau!!!

Se eu mudar isso para:

let quadrado x = x * x

let somaDosQuadrados nums =
    let mutable total = 0.0
    for x in nums do
        total <- total + quadrado x
    total

(Só mudei a variável “total” de “0” para “0.0”.)

Tudo muda, e “x” passa a ser um double (chamado de float no F#), e nums uma lista de doubles (pulei algumas linhas para mostrar que mudei a variável total):

Agora são doubles

A função quadrado também passa a trabalhar com doubles:

Aqui também são doubles

Uma mudança na função somaDosQuadrados afetou a função quadrado. Uau de novo!

Está clara a influência desse tipo de construção sobre o C#, principalmente na construção de lambdas e do LINQ, não está? Bem legal que algo que tenha iniciado nas universidades, em algum momento foi parar no Microsoft Research, e foi incorporado ao C# mesmo antes do lançamento do F#, previsto só para o Visual Studio 2010 no fim deste ano, começo do ano que vem. Aliás, lambdas são consideradas o “lado funcional” do C#, e são um dos motivos que o C# é chamado de uma linguagem de múltiplos paradigmas.

Antes de terminar, eu só queria dizer que essa não é a maneira correta de fazer uma função com F#. Programar F# assim é como usar C# para fazer programação estruturada, sem OO, algo que devia dar cadeia. Esse programa, altamente imperativo, vai contra tudo o que o F# propõe, que é uma programação funcional, não imperativa. Mas isso fica para outro post.

Giovanni Bassi

Arquiteto e desenvolvedor, agilista, escalador, provocador. É fundador e CSA da Lambda3. Programa porque gosta. Acredita que pessoas autogerenciadas funcionam melhor e por acreditar que heterarquia é mais eficiente que hierarquia. Foi reconhecido Microsoft MVP há mais de dez anos, dos mais de vinte que atua no mercado. Já palestrou sobre .NET, Rust, microsserviços, JavaScript, TypeScript, Ruby, Node.js, Frontend e Backend, Agile, etc, no Brasil, e no exterior. Liderou grupos de usuários em assuntos como arquitetura de software, Docker, e .NET.