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 🙂
Reparem que o iex possui todo um sistema de help embutido. Para obtermos o help do próprio iex basta digitarmos h()
:
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
:
Ou então
h 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