Olá pessoal, tudo bem? Dando continuidade aos meus estudos com Elixir, vamos hoje dar uma olhada em alguns Tipos, Operadores e entrar em contato com o IEx.

Disclaimer: Estudar algo novo, principalmente algo que envolva um novo paradigma, requer tempo. É possível que nos frustremos no caminho, uma dica importante (que eu tenho usado muito) é: tenha uma expectativa realista – quantidade de tempo livre (e descansado) que dispomos para os estudos, nosso ritmo de aprendizado, etc. Por mais bobo que isso pareça, é algo válido.

IEx – Interactive Elixir

Uma das melhores formas de aprender algo novo, é usando esse algo, realizando pequenos testes e experimentações. Diversas linguagens oferecem um ambiente REPL (Read, Evaluate, Print, Loop) onde podemos executar e criar código, obtendo feedbacks instantâneos sobre o que está acontecendo. Com Elixir isso não é diferente. A instalação padrão nos dá o IEx – Interactive Elixir, que é o nosso ambiente REPL. Para iniciar o IEx basta digitar iex no seu console 🙂

iex - Interactive Elixir

iex – Interactive Elixir

Reparem que o iex possui todo um sistema de help embutido. Para obtermos o help do próprio iex basta digitarmos h():

iex helpers

iex helpers

Todo esse help é feito dentro do próprio código Elixir (algo que veremos em outro momento), utilizando uma sintaxe de comentários para documentação, e ela aparece assim toda formatada.

Se quisermos obter o help para alguma função ou módulo específico, basta utilizarmos h antes do nome da função ou módulo, como por exemplo h String.split:

iex help para função String.split

iex help para função String.split


Ou então h String:
iex help para módulo String

iex help para módulo String

Para continuarmos a experimentar os Tipos e Operadores a seguir, vou assumir que o iex está rodando aí (se você estiver no Windows deve digitar iex.bat para iniciar o mesmo).

Tipos

A primeira coisa que precisamos ter em mente é que Elixir é uma linguagem dinamicamente tipada. Isto quer dizer que você não precisa ficar definindo tipos ao declarar variáveis, nem especificar tipos de parâmetros em funções (embora isso seja possível), os tipos serão inferidos em runtime.

Existem alguns tipos básicos em Elixir (além de alguns definidos pela própria VM do Erlang). Estes tipos geralmente estão bastante envolvidos com todo tipo de código e projeto que venhamos a escrever, então vamos ver alguns deles.

Números

Em Elixir podemos trabalhar com inteiros e valores de ponto flutuante, ou ints e floats.

iex(21)> 10 + 10
20
iex(22)> 10 + 10.0
20.0
iex(23)> 10 / 10
1.0

Na linha 1 temos a soma de dois ints, resultando também em um int. Na linha 3 temos a soma de um int e um float, resultando em um float. E na linha 5 temos uma divisão, que mesmo que seja entre dois ints sempre terá como resultado um float.
Em ambos os casos os resultados retornarão true se passados para a função is_number/1:

iex(26)> is_number 10 + 10 
true
iex(27)> is_number 10 / 10
true

Booleanos

Em Elixir temos true e false como booleans. E como veremos mais a seguir em operadores, Elixir trabalha com o conceito de truthy e falsy. Basicamente tudo é truthy exceto nil e false. Isto quer dizer que quando estivermos analisando algo, a menos que seja nil ou false, então será considerado truthy.

iex(33)> true
true
iex(34)> false
false
iex(35)> true == true
true
iex(36)> true == false
false
iex(39)> 1 == 2
false
iex(40)> 3 < 5
true

Atoms

Atoms são constantes cujo valor é o mesmo de seu nome. Em Ruby temos o mesmo conceito, com o nome de symbols. Curiosamente true e false são atoms 😉

iex(42)> :lambda3
:lambda3
iex(43)> :lambda3 == :lambda3
true
iex(44)> :lambda3 == "lambda3"
false
iex(45)> :lambda3 == :"lambda3"
true
iex(46)> true == :true
true
iex(47)> false == :false
true

Strings

Strings em Elixir aparecem entre aspas duplas “desta forma”. Elas são codificadas em UTF-8, além de serem nada mais nada menos do que uma sequência binária (mas falaremos sobre isso no futuro).

iex(49)> "vinicius quaiato"
"vinicius quaiato"
iex(50)> "Elixir é sensacional"
"Elixir é sensacional"
iex(52)> "太棒了"    
"太棒了"

(espero ter escrito algo parecido com “awesome” em Chinês)

Elixir também dá suporte para interpolação de strings e strings multiline:

iex(55)> "vinicius
...(55)> quaiato
...(55)> esteve 
...(55)> aqui"
"vinicius\nquaiato\nesteve \naqui"
iex(58)> "I like #{:elixir}"
"I like elixir"

Reparem como na linha 6 interpolamos um atom ?

Anonymous Functions

E é claro, estando em uma linguagem funcional, temos funções como tipos. Elas podem ser passadas como parâmetros para outras funções, assim como qualquer outro tipo. Funções anônimas serão bastante utilizadas, por isso é interessante nos acostumarmos à elas. Se você vem de um background C# então provavelmente já tem lidado bastante com elas usando Linq. Podemos definir funções anônimas da seguinte forma:

iex(65)> do_something = fn num, func -> func.(num) end
#Function<12.54118792/2 in :erl_eval.expr/5>

iex(66)> do_something.(10, (fn n -> n*n end))
100

iex(67)> do_something.(10, (fn n -> n/2 end))
5.0

Ainda que este exemplo não faça nada grandioso, na linha 1 definimos uma função anônima e colocamos ela em uma variável. A definição de uma função anônima é feita assim: fn parametros -> corpo end

Esta função recebe 2 parâmetros: num e func, sendo que o primeiro deles é um número e o segundo uma função. Então aplicamos essa função informada ao número informado.
Na linha 4 executamos nossa função anônima informado o número 10 e uma outra função que multiplica um número por ele mesmo. Neste caso resultando em 100.
Na linha 6 o que fazemos é passar uma segunda função anônima que desta vez divide o número por 2, resultando em 5.0 (divisões retornam float, lembram?)

Notem que para invocar uma função anônima utilizamos um . após seu nome e antes dos parâmetros.

Operadores

Agora que vimos alguns dos tipos básicos, vamos ver alguns operadores que o Elixir nos oferece.

Aritmética

Já vimos alguns deles, e como não tem muito segredo ou mistério, vou apenas exibir abaixo:

iex(69)> 1 + 1
2
iex(70)> 2 - 1
1
iex(71)> 3 * 3
9
iex(72)> 10 / 5
2.0

Boolean

Quando lidamos com valores booleanos temos os seguintes operadores em Elixir: and, or e not. Um detalhe bem importante é que estes três operadores só aceitam os valores true ou false.

iex(79)> true and true
true
iex(80)> true and false
false
iex(81)> true or false
true
iex(82)> false or false
false
iex(83)> not true
false
iex(84)> not false
true

Já nossos velhos conhecidos: &&, || e !, em Elixir, aceitam quaisquer valores que sejam truthy ou falsy.

iex(89)> 1 && 3
3
iex(90)> false && 1
false
iex(91)> true && 10
10
iex(92)> 1 || false
1
iex(93)> false || 100
100
iex(94)> ! 10
false
iex(95)> ! false
true

Operadores de comparação

Os operadores de comparação ==, !=, ===, !==, <=, >=, < e >, como vemos abaixo:

iex(107)> 1 == 1
true
iex(108)> 1 != 2
true
iex(109)> 1.0 === 1
false
iex(110)> 1.0 !== 1
true
iex(111)> 1.0 < 1
false
iex(112)> 1 > 1.0
false
iex(113)> 1 >= 1.0
true
iex(114)> 1 <= 1.0
true

A diferença entre == e === é que quando comparando números o operador === é mais restritivo, por isso 1.0 == 1 é verdadeiro e 1.0 === 1 é falso.

Também é possível comparar tipos diferentes em Elixir. Para isso existe uma ordem predefinida:
number < atom < reference < functions < port < pid < tuple < maps < list < bitstring

Uma lista completa com todos os operadores do Elixir pode ser encontrada aqui.

Resumo

Ufa! Parece que o posto foi longo, mas tirando as linhas de código e imagens ele até que foi bem curto. E agora temos um pouco mais de conhecimento sobre Elixir pra nos virarmos em testes e experimentos simples no IEx. Já sabemos como definir funções anônimas e brincar com operações booleanas e aritméticas.

Um próximo passo, bem importante, será entendermos como trabalhar com Lists e Tuples, que eu deixei de fora propositalmente. Se você não quer esperar, corre lá no Getting Started do Elixir que ele é quase um livro, bem completinho.

Quaisquer dúvidas ou sugestões, deixem nos comentários. Eu também estou começando meus estudos.

Vinicius Quaiato