Funções em Elixir

Adolfo Neto
3 min readFeb 5, 2018

--

Todo semestre tenho que relembrar a definição de função para meus alunos de primeiro ano de Engenharia de Computação e de Sistemas de Informação:

Uma função f: A→B associa a cada elemento de um conjunto A um elemento do conjunto B.

Por exemplo, sejam os seguintes conjuntos A e B:

A = {a, b, c}

B = {1, 2, 3}

Posso definir f:A→B como sendo

f(a)=1

f(b)=2

f(c)=3

E se A for o conjunto vazio? Neste caso, temos uma função que sempre retorna o mesmo valor. Por exemplo, podemos dizer que pi (π) é uma função de aridade zero.

A aridade de uma função é a quantidade de argumentos que uma função recebe.

Vamos escrever a função pi em Elixir com precisão de 4 casas decimais.

A definição de uma função em Elixir é assim

def <NOME DA FUNÇÂO> [<ARGUMENTOS>] do

<CORPO DA FUNÇÃO>

end

No caso da função pi acima, como não temos argumentos, o retorno será sempre o mesmo. Isto acontece com funções puras.

Elixir também permite definir funções impuras, isto é, que não obedecem a definição matemática. Um exemplo:

A função sorteia_numero_1_a_10 vai retornar um valor entre 1 e 10. A cada vez que é chamada pode retornar um valor diferente.

Uma convenção em Elixir, que acredito ter vindo de Prolog e de Erlang, é, ao escrever os nomes das funções, indicar a quantidade de argumentos. Por exemplo, as funções usadas acima foram pi/0, sorteia_numero_1_a_10/0 e Enum.random/1.

Outra convenção (definição?) em Elixir é colocar o nome do módulo (em outro post falaremos mais sobre módulos, mas considere como sendo uma biblioteca de funções) e depois o nome da função, separados por um ponto.

E se A foi o produto cartesiano (representamos aqui pelo símbolo “x”) de dois ou mais outros conjuntos?

Lembra o que é produto cartesiano?

Se

A = {c, d}

B = {5, 6}

então

AxB = {(c,5), (c,6), (d,5), (d,6)}

BxA = {(5,c), (5,d), (6,c), (6,d)}

AxA = {(5,5), (5,6), (6,5), (6,6)}

Neste caso, em linguagens de programação, em vez de dizer que temos uma função que recebe um elemento de um produto cartesiano como entrada, simplificamos e dizemos que a função recebe mais de um argumento.

Na matemática seria algo como:

A = {a, b, c}

B = {1, 2, 3}

Posso definir f: AxA→B como

f(a,a)=1

f(a,b)=2

f(a,c)=3

f(b,a)=1

f(b,b)=3

f(b,c)=2

f(c,a)=1

f(c,b)=3

f(c,c)=2

E, claro, posso definir também f:AxB→ C onde:

A = {a, b, c}

B = {d, e}

C = {1, 2, 3, 4}

como:

f(a,d)=1

f(a,e)=1

f(b,d)=4

f(b,e)=1

f(c,d)=3

f(c,e)=4

Voltando ao Elixir, vamos definir uma função de aridade 1:

Ops, só agora percebi que já definimos três funções ( pi/0, sorteia_numero_1_a_10/0 e identidade/1) e não testamos nenhuma!

Não vou usar ainda testes automatizados. Vou deixar para depois. Não acho produtivo quando estamos aprendendo. Em primeiro lugar, se ainda não tem Elixir em suam máquina, instale o Elixir.

Depois faça, na linha de comando do Linux:

Obs.: Estou usando o atom como editor de código.

Com o atom, altere o conteúdo de aula1.ex para (o ideal é que você digite e não copie e cole apenas):

Depois de salvo dê, no seu shell:

mix format

Depois de salvo mais uma fez, faça:

iex -S mix

E teste no IEx (Interactive Elixir) o REPL do Elixir, como na figura abaixo:

Todas as funções funcionaram como esperado.

OK, agora sabemos como escrever funções bem simples de zero e um argumento em Elixir. Futuramente veremos funções que recebem mais argumentos e outras questões não discutidas aqui.

--

--

Adolfo Neto

Associate Professor at UTFPR. Interested in programming (Elixir), logic and Deep Work.