Resumo O Elixir é uma linguagem dinâmica e funcional projetada para criar aplicativos escalonáveis e de fácil manutenção. Ele aproveita a VM Erlang, conhecida por executar sistemas de baixa latência, distribuídos e tolerantes a falhas, além de ser usada com sucesso no desenvolvimento da Web e no domínio de software incorporado. Elixir é uma linguagem funcional e dinâmica construída sobre Erlang e a Erlang VM. Erlang é uma linguagem que foi originalmente escrita em 1986 pela Ericsson para ajudar a resolver problemas de telefonia como distribuição, tolerância a falhas e simultaneidade. Elixir, escrito por José Valim, estende Erlang e fornece uma sintaxe mais amigável na VM Erlang. Ele faz isso enquanto mantém o desempenho do mesmo nível que o Erlang. Palavras Chaves: VM Erlang, funcionais, tolerância e moderna;
Summary Elixir is a dynamic, functional language designed to create scalable and easy-tomaintain applications. It leverages VM Erlang, known for running low-latency, distributed, fault-tolerant systems, and is successfully used in Web development and embedded software. Elixir is a functional and dynamic language built on Erlang and Erlang VM. Erlang is a language that was originally written in 1986 by Ericsson to help solve telephony problems such as distribution, fault tolerance and concurrency. Elixir, written by José Valim, extends Erlang and provides a more friendly syntax in VM Erlang. It does this while maintaining performance at the same level as Erlang. key words: VM Erlang, functional, tolerance and Modern;
Introdução
Elixir é uma linguagem de programação funcional criada por José Valim que roda na Erlang Virtual Machine. A linguagem apareceu pela primeira vez em 2011 e já está sendo usada por algumas grandes corporações em produção. Bleacher Report, por exemplo, relatouum grande impulso no desempenho depois de mudar para o Elixir. O Pinterest também usa o Elixir extensivamente para lidar com spam. O Elixir promete e oferece escalabilidade. Com o Elixir, você pode executar centenas e até milhares de processos simultaneamente em um único sistema e em sistemas distribuídos, mantendo a comunicação entre eles. Como uma linguagem de programação funcional, é concisa. Outra vantagem para o Elixir é que ele é tolerante a falhas. A linguagem fornece um mecanismo para lidar com problemas de funcionamento, permitindo que um sistema seja restaurado para um estado de funcionamento conhecido. Histórico Escalabilidade - Todos os códigos Elixir são executados em processos leves isolados e trocam informações por meio de mensagens. Tolerância a falhas - O Elixir fornece supervisores que descrevem como reiniciar partes de seu sistema quando as coisas dão errado, voltando a um estado inicial conhecido que funcione com segurança. Isso garante que seu aplicativo / plataforma nunca esteja inativo. Programação Funcional - A programação funcional promove um estilo de codificação que ajuda os desenvolvedores a escrever códigos curtos, rápidos e de fácil manutenção. Ferramentas de construção - o Elixir é fornecido com um conjunto de ferramentas de desenvolvimento. O Mix é uma dessas ferramentas que facilita a criação de projetos, o gerenciamento de tarefas, a execução de testes, etc. Ele também possui seu próprio gerenciador de pacotes. Compatibilidade Erlang - Elixir roda na VM Erlang dando aos desenvolvedores acesso completo ao ecossistema Erlang. Paradigma Principais recursos Explore os paradigmas funcionais de programação com o Elixir através do uso de exemplos úteis Ferramentas passo a passo concisas para ensinar conceitos técnicos difíceis Faça uma ponte entre a programação funcional e o Elixir livro
de descrição Elixir, com base na máquina virtual e no ecossistema da Erlang, facilita a escalabilidade, Concorrência, tolerância a falhas e objetivos de alta disponibilidade que são perseguidos pelos desenvolvedores usando qualquer linguagem de programação ou paradigma de programação. Elixir é uma linguagem de programação moderna que utiliza os benefícios oferecidos pelo Erlang VM sem realmente incorporar as sintaxes complexas do Erlang. Ler um programa usando o Elixir ensinará muitas coisas que são muito benéficas para a programação como um ofício, mesmo que no final do dia , o programador não está usando o Elixir. Este livro ensinará conceitos e princípios importantes para qualquer aplicativo complexo, escalável e resistente. Principalmente, os aplicativos são historicamente difíceis de raciocinar, mas usando os conceitos deste livro, eles se tornarão fáceis e agradáveis. Ele ensinará os cabos de programação funcionais, para permitir que eles criem aplicativos melhores e mais escaláveis, e você explorará como o Elixir pode ajudá-lo a alcançar novas alturas de programação. Os paradigmas comuns de programação incluem: imperativo em que o programador instrui a máquina como mudar seu estado, processual que agrupa instruções em procedimentos, orientada a objetos que agrupa instruções junto com a parte do estado em que operam, declarativo em que o programador simplesmente declara propriedades do resultado desejado, mas não como calculá-lo funcional em que o resultado desejado é declarado como o valor de uma série de aplicativos de função, lógica na qual o resultado desejado é declarado como a resposta a uma pergunta sobre um sistema de fatos e regras, matemática na qual o resultado desejado é declarado como a solução de um problema de otimização.
Estruturas de Controle
Vamos agora escrever um loop simples usando recursão que imprime ola n vezes. Demonstração ao vivo defmodule Loop do def print_multiple_times(msg, n) when n <= 1 do IO.puts msg end def print_multiple_times(msg, n) do IO.puts msg print_multiple_times(msg, n - 1) end end Loop.print_multiple_times("Arraial", 10) Tratamento de Exceções Antes de podermos lidar com os erros, precisamos criá-los e a maneira mais simples de fazer isso é com o raise/1: iex> raise "Oh no!" ** (RuntimeError) Oh no! Se queremos especificar o tipo e mensagem, precisamos usar raise/2: iex> raise ArgumentError, message: "the argument value is invalid" ** (ArgumentError) the argument value is invalid Se sabemos que um erro pode ocorrer, podemos lidar com isso usando try/rescue e pattern matching:
iex> try do ...> raise "Oh no!" ...> rescue ...> e in RuntimeError -> IO.puts("An error occurred: " <> e.message) ...> end An error occurred: Oh no! :ok É possível combinar vários erros em um único rescue: try do opts |> Keyword.fetch!(:source_file) |> File.read!() rescue e in KeyError -> IO.puts("missing :source_file option") e in File.Error -> IO.puts("unable to read source file") end 1. Exemplos xii. Escopo e ambiente de referência. Para executar o Elixir, você precisa configurá-lo localmente no seu sistema. Para instalar o Elixir, primeiro você precisará do Erlang. Em algumas plataformas, os pacotes Elixir vêm com o Erlang. Instalando o Elixir Vamos agora entender a instalação do Elixir em diferentes sistemas operacionais. configuração do Windows
Para
instalar
o
Elixir
no
Windows,
baixe
o
instalador
em
https://repo.hex.pm/elixirwebsetup.exe e simplesmente clique em Avançar para prosseguir em todas as etapas. Você terá em seu sistema local. Se você tiver algum problema ao instalá-lo, poderá verificar esta página para mais informações. Mac Setup Se você tiver o Homebrew instalado, verifique se é a versão mais recente. Para atualização, use o seguinte comando brew update Agora, instale o Elixir usando o comando abaixo brew install elixir Ubuntu / Debian Setup Os passos para instalar o Elixir em uma configuração Ubuntu / Debian são os seguintes Adicionar repo da Erlang Solutions wget
https://packages.erlang-solutions.com/erlang-solutions_1.0_all.deb
&& sudo dpkg -i erlang-solutions_1.0_all.deb sudo apt-get update Instale a plataforma Erlang / OTP e todas as suas aplicações sudo apt-get install esl-erlang Instale o Elixir sudo apt-get install elixir Outras distribuições do Linux
Se você tiver alguma outra distribuição Linux, visite esta página para configurar o elixir em seu sistema local. Testando a instalação Para testar a configuração do Elixir em seu sistema, abra seu terminal e insira iex nele. Ele irá abrir o shell de elixir interativo como o seguinte Erlang/OTP 19 [erts-8.0] [source-6dc93c1] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] Interactive Elixir (1.3.1) - press Ctrl+C to exit (type h() ENTER for help) iex(1)> O Elixir agora está configurado com sucesso no seu sistema. É muito comum (e altamente recomendado) que o aplicativo mantenha seus valores de configuração separados de seu controle de versão. Uma maneira de fazer isso é usando ENV vars (variáveis de ambiente). Eles estão sendo usados para melhorias principalmente na manutenção. O app de doze fatores armazena o config em variáveis de ambiente (geralmente encurtado palavras env vars ou env). As variáveis de env são fáceis de alterar entre as implementações sem alterar nenhum código; Ao contrário dos arquivos de configuração, há pouca chance de eles serem verificados no repositório de código acidentalmente; e, ao contrário dos arquivos de configuração personalizados ou de outros mecanismos de configuração, como as propriedades do sistema Java, eles são um padrão independente de linguagem e sistema operacional. Em um projeto Elixir, a configuração vai em Mix.Configarquivos. Alguns exemplos são: config.exse arquivos ambiente de configuração ( dev.exs, test.exse prod.exs). Esses arquivos geralmente são usados por frameworks e bibliotecas.
xiii. Suporte a O.O (se for o caso). 1. Tudo é um objeto. Isso não diz muito, então vamos verificar isso mais tarde. 2. Objetos se comunicam enviando e recebendo mensagens (em termos de objetos). Os processos do Elixir se encaixam perfeitamente nessa definição. Então, a partir de agora, vamos supor que os processos sejam objetos no Elixir. 3. Objetos possuem sua própria memória (em termos de objetos). É claro que os processos possuem memória própria, mas a memória geralmente contém algo como números e mapas. Se considerarmos essas coisas que não são de processo como objetos que não podem se comunicar, elas se encaixam perfeitamente nessa definição. 4. Todo objeto é uma instância de uma classe (que deve ser um objeto). No Elixir, você tem módulos e estruturas. As estruturas podem ser vistas como "classes" para coisas que não são de processo, mas quais são as classes para processos? Vamos ver o próximo termo. 5. A classe mantém o comportamento compartilhado para suas instâncias (na forma de objetos em uma lista de programas) Os módulos geralmente contêm retornos de chamada GenServer iguais ou semelhantes, e esses retornos de chamada definem o protocolo de comunicação (ou seja, que tipo de mensagens um processo pode manipular). Você pode gerar quantos processos quiser usando um módulo, para que os módulos possam ser vistos como as “classes” de processos. 6. Para avaliar uma lista de programas, o controle é passado para o primeiro objeto e o restante é tratado como sua mensagem. Essa é exatamente a definição do aplicativo Elixir. Há um supervisor de raiz (o primeiro “objeto”) em um aplicativo e você passa alguns outros processos (“objetos”) para ele como mensagens (você pode não ver este procedimento) para que o supervisor de raiz possa supervisioná-los.
xiv. Carta Sintática (Com partes da BNF) Tipos e especificações Elixir é uma linguagem tipada dinamicamente, então todos os tipos no Elixir são inferidos pelo tempo de execução. Não obstante, o Elixir vem com typespecs , que são uma notação usada para: Declarar assinaturas de função tipadas (especificações); declarando tipos de dados personalizados. Especificações de função Por padrão, o Elixir fornece alguns tipos básicos, como integerou pid, assim como tipos mais complexos: por exemplo, a round/1função, que arredonda um float para o inteiro mais próximo, toma como um argumento ( integerou e float) e retorna um integer. Como você pode ver em sua documentação , round/1a assinatura digitada é escrita como: round(number) :: integer ::significa que a função no lado esquerdo retorna um valor cujo tipo é o que está no lado direito. Especificações de função são escritas com a @specdiretiva, colocadas logo antes da definição da função. A round/1função pode ser escrita como: @spec round(number) :: integer def round(number), do: # implementation... O Elixir também suporta tipos compostos. Por exemplo, uma lista de números inteiros tem tipo [integer]. Você pode ver todos os tipos internos fornecidos pelo Elixir nos documentos typespecs . Definindo Tipos Customizados Embora o Elixir forneça muitos tipos internos úteis, é conveniente definir tipos personalizados quando apropriado. Isso pode ser feito ao definir módulos por meio da @typediretiva. Digamos que tenhamos um LousyCalculatormódulo, que executa as operações aritméticas usuais (soma, produto e assim por diante), mas, em vez de retornar números, ele retorna as tuplas com o resultado de uma operação como o primeiro elemento e uma observação aleatória como o segundo elemento.
defmodule LousyCalculator do @spec add(number, number) :: {number, String.t} def add(x, y), do: {x + y, "You need a calculator to do that?!"} @spec multiply(number, number) :: {number, String.t} def multiply(x, y), do: {x * y, "Jeez, come on!"} end Como você pode ver no exemplo, as tuplas são um tipo composto e cada tupla é identificada pelos tipos dentro dele. Para entender por que String.tnão está escrito como string, dê outra olhada nos documentos typespecs . Definir especificações de função desta maneira funciona, mas rapidamente se torna irritante, já que estamos repetindo o tipo {number, String.t}várias vezes. Podemos usar a @typediretiva para declarar nosso próprio tipo personalizado. defmodule LousyCalculator do @typedoc """ Just a number followed by a string. """ @type number_with_remark :: {number, String.t} @spec add(number, number) :: number_with_remark def add(x, y), do: {x + y, "You need a calculator to do that?"} @spec multiply(number, number) :: number_with_remark def multiply(x, y), do: {x * y, "It is like addition on steroids."} end A @typedocdiretiva, da mesma forma que as diretivas @doce @moduledoc, é usada para documentar tipos personalizados. Os tipos personalizados definidos @typesão exportados e estão disponíveis fora do módulo em que estão definidos: defmodule QuietCalculator do @spec add(number, number) :: number def add(x, y), do: make_quiet(LousyCalculator.add(x, y)) @spec make_quiet(LousyCalculator.number_with_remark) :: number defp make_quiet({num, _remark}), do: num end
xv. Conclusões A programação funcional oferece técnicas úteis para a criação de software atualizável e escalável que resolve os problemas difíceis de hoje. A demanda por softwares escritos dessa maneira está aumentando - você não quer perder nada. O Elixir ainda é uma linguagem relativamente nova no que diz respeito às tecnologias da Web, portanto, a quantidade de recursos lá fora é pequena, mas crescente. xvi. Referência Bibliográficas «elixir / CHANGELOG.md na v1.7.3 · elixir-lang / elixir · GitHub» . GitHub El «elixir / LICENÇA no mestre · elixir-lang / elixir · GitHub» . GitHub Val José Valim. «Elixir» . Consultado em 26 de abril de 2017 «Elixir - Uma abordagem moderna de programação para o Erlang VM» . Consultado em 26 de setembro de 2016 a b c d «Elixir» . Consultado em 20 de julhol de 2018