Executando verificação de segurança...
13

Elixir - Uma breve introdução a linguagem por trás do Whatsapp, Nubank, Brex e tantas outras!

Nota do Autor: "Olá pessoal, o objetivo deste artigo, como o título sugere, não é apresentar todos os aspectos do paradigma da programação funcional, mas sim demonstrar a utilidade da linguagem Elixir e qual o seu diferencial em relação a outras linguagens de programação. Tive contato com essa linguagem na disciplina de Sistemas Distribuídos e, inicialmente, não fazia muito sentido para mim o professor abordar essa linguagem. No entanto, depois compreendi sua importância para sistemas que podem ser facilmente escaláveis e resilientes. Muitas empresas modernas utilizam a linguagem para a construção de sistemas com serviços críticos."

Introdução

Elixir é uma linguagem de programação funcional. Com linguagens funcionais como Elixir, podemos fazer melhor uso de nossos multinúcleos de CPU e escrever códigos mais curtos e explícitos. Para entender melhor a programação funcional, devo primeiro apresentar os seguintes princípios fundamentais: imutabilidade, funções e código declarativo.

Na programação funcional, todos os valores criados no programa são imutáveis. Por padrão, cada função possui um valor estável, o que significa que mecanismos de bloqueio não são necessários. Isso simplifica o trabalho paralelo. A imutabilidade está aparecendo mais nas linguagens de programação convencionais. Essas linguagens normalmente fornecem o mecanismo imutável, fornecendo uma alternativa de tipo de dados imutável ou um método para tornar um valor imutável.

A sintaxe Elixir compartilha muitas semelhanças com a sintaxe Ruby e é amplamente usada para construir aplicativos tolerantes a falhas, escaláveis ​​e de fácil manutenção. A linguagem fornece escalabilidade, simultaneidade, tolerância a falhas e baixa latência.

A linguagem também possui um conjunto sólido de ferramentas de desenvolvimento web, como:

Mix: Mix é uma ferramenta de construção que permite criar projetos, executar testes, gerenciar tarefas e muito mais.
IEx: IEx, o shell interativo do Elixir, oferece muitos recursos como preenchimento automático, depuração, recarregamento de código e muito mais.
Phoenix: Phoenix é conhecido por ser um dos melhores frameworks web. É baseado na arquitetura MVC, assim como Ruby on Rails.

Importância do Elixir

Elixir é fundamental se você quiser construir um sistema que possa atuar de forma distribuída. Além disso, é uma ótima escolha para desenvolver microserviços. O Facebook Messenger inicialmente foi construído utilizando a base do Elixir, Erlang. No entanto, ele foi reescrito em outra linguagem anos depois. Mesmo assim, o WhatsApp ainda possui partes desenvolvidas com Erlang e Elixir.

O Nubank fez a compra de uma empresa chamada "Plataformatec", onde um dos fundadores é o criador da linguagem Elixir. O paradigma funcional também ajuda no processo de internacionalização do Nubank. "Como é um paradigma imutável, não precisamos mudar tudo desde o começo", afirma Bruno, o tech manager da Nubank. "A lógica do sistema financeiro de um país pode ser diferente do de outro, mas conseguimos usar a mesma base para todos".

A Brex, uma empresa de tecnologia em pagamentos bancários fundada por dois brasileiros, adotou o Elixir como uma forma de criar sistemas consistentes para operações de pagamento. Em um artigo escrito por um dos fundadores, ele pontuou o seguinte: "Depois de usar o Elixir por 18 meses, temos uma forte compreensão de como a plataforma se comporta no mundo real. Uma observação é que, apesar do Elixir ser uma linguagem relativamente de nicho, os novos contratados que nunca tiveram contato com o Elixir antes são produtivos em três semanas. Há uma quantidade razoável de livros e documentação disponíveis na linguagem que aceleram o processo de aprendizado

Uma breve introdução

Tipos Primitivos

Strings

Elixir usa o padrão UTF-8 para codificação de Strings. As Strings são iguais em qualquer outra linguagem. No exemplo abaixo temos uma saída de uma string no terminal.

  IO.puts("Hello, World!")

Átomos

Átomos são constantes cujo o valor é são seus propios nomes. Em outras linguagens, como ruby por exemplo, Átomos são chamados de símbolos.


iex> :cat
:cat
iex> :dog
:dog
iex> :fish
:fish

Booleanos

Booleanos são valores que podem assumir verdadeiro ou falso

true

true==false

KeyWord List

Quando temos uma lista de tuplas e o primeiro item da tupla possui um átomo chamamos essa estrutura de Keyword List. Abaixo vemos um exemplo de KeyWord List

list = [{:c, 1}, {:d, 2}]
[c: 1, d: 2]
iex> list == [c: 1, d: 2]
true

Módulos e funções

No elixir as funções são agrupadas em módulos, no exemplo abaixo vemos chamadas de funções e uma função simples:

String.length("elixir")
defmodule Playground do
  #Normal Function
  def area(a, b) do
    a * b
  end
end

Importante ressaltar que no elixir não existe a palavra chave return, portanto, o retorno é baseado na saída da última linha. Embaixo tem um exemplo de função sem argumentos

  # Function with no arguments

  def run do
    area(10,20)
  end

Quando se tem um retorno de uma linha é possível fazer isso da seguinte maneira:

 # Clean Way to do one line function
    def area_of_circle(x, y) do: x * y
  end

Funções Anonimas

Tal como o nome indica, uma função anônima não tem nome. Como vimos na lição Enum, elas são frequentemente passadas para outras funções. Para definir uma função anônima em Elixir nós precisamos das palavras-chave fn e end. Dentro destes, podemos definir qualquer número de parâmetros e corpos separados por ->.

# Anon Function
    s = fn x -> x * x end
    s.(2)
    # Output: 4

sum = fn (a, b) -> a + b end
sum.(2, 3)

Pattern Matching

Pattern Matching é uma forma de associar uma expressão em elixir. Pattern Matching não pode ser limitado apenas a associação com variáveis, podemos executar isso com funções.

{name,age} = {"John", 25}
name #Output: "John"
age #Output: 25

Operador _ permite que você não faça associação diretas aos valores sendo bem útil quando você quer utilizar constantes. O operador _ também chamada de variável anonima

{_, x} = {11, "Hello"}

A utilidade de pattern matching com funções no permite criar múltiplas clausulas para a função. Elixir utiliza pattern matching para verificar todas as possíveis opções de match e identificar o primeiro conjunto de parâmetros associados para executar seu respectivo corpo.

handle_result = fn
  {:ok, result} -> IO.puts "Handling result..."
  {:ok, _} -> IO.puts "This would be never run as previous will be matched beforehand."
  {:error} -> IO.puts "An error has occurred!"
end

Nesse código, associamos uma função anonima a uma variável que pode retornar três tipos de resultados diferentes conforme a entrada da tupla. Abaixo vemos um outro exemplo de pattern matching aplicado em um função nomeada

defmodule Geometry do
  def area({:rectangle, a, b}) do
    a * b
  end

  def area({:square, a}) do
    a * a
  end

  def area(:circle, r) do
    r * r * 3.14159
  end

  def area(unknown) do
    {:error},{:unknow_shape, unknown}
  end

end

Dê a você uma variável/valor, você pode querer

  1. Verifique se o tipo de dados corresponde ao tipo de dados esperado
  2. Verifique se a estrutura dos dados corresponde à estrutura de dados esperada
  3. Atribuir parte correspondente dos dados a uma variável

exemplos

verificar se os dados são mapas

%{} = params

podemos, por exemplo, fazer três verificações: verificar se os dados são um mapa, tem a chave email e o valor email é corresponde a um determinado input

%{"email" => "[email protected]"} = params

Atribuição de variáveis. Nesse caso, ele ira fazer a verificação se existe a chave email na tupla, se possuir, o valor da chave email irá ser atríbuida a variável my_email

%{"email" => my_email} = params

Podemos fazer o mesmo caso com variáveis anonimas.

%{"email" => _} = params

verificação do tipo struct

%User{} = params

Verifique se os dados são tuplas e têm valor específico

{:ok, data} = result
# you use this most of time

Funções nomeada

Nós podemos definir funções com nomes para referir a elas no futuro, estas funções nomeadas são definidas com a palavra-chave def dentro de um módulo. Nós iremos aprender mais sobre Módulos nas próximas lições, por agora nós iremos focar apenas nas funções nomeadas. Abaixo vemos um exemplo de função nomeada que retorna o tamanho de uma lista

defmodule Length do
  def of([]), do: 0
  def of([_ | tail]), do: 1 + of(tail)
end

Referências

https://news.ycombinator.com/item?id=21111662
https://medium.com/brexeng/why-brex-chose-elixir-fe1a4f313195
https://elixir-lang.org/docs.html
https://github.com/samsepiol1/study_elixir

Correção

Aparentemente a Brex resolveu mudar sua base de código de elixir para Kotlin, apesar de ainda reconhecer que elixir foi de grande importância para os estágio iniciais: https://medium.com/brexeng/building-backend-services-with-kotlin-7c8410795e4b

Carregando publicação patrocinada...
3

que introdução maneira cara! eu não sei porque mas no final do ano passado eu fiquei com uma "pulga atrás da orelha" de aprender elixir e golang kkk mas no momento tô muito em início de carreira e preciso focar em linguagens que podem me dar um emprego(e ainda não achei a resposta) então mês que vem vou estudar e fazer projetos em Java com spring boot e Nest.js e decidir qual vou focar mas ainda esse ano vou procurar fazer nem que seja um CRUD com Elixir! foi muito bom ver os conceitos e o conceito de atomos achei diferente de tudo que já vi kk

1

Bom que a introdução ajudou! Acabei não demonstrando na introdução, mas o elixir possui um framework web chamado Phoenix. Muitos conceitos do elixir são similares ao do Ruby: O ruby possui esses átomos, porém chamamos de símbolos.