Saltar para o conteúdo

Erlang (linguagem de programação)

Origem: Wikipédia, a enciclopédia livre.
Erlang
Paradigma multi-paradigma: concorrente e funcional
Surgido em 1986 (37–38 anos)
Última versão R26.2 (13 de dezembro de 2023; há 12 meses[1])
Criado por Ericsson
Estilo de tipagem dinâmica, forte
Influenciada por Prolog, ML
Influenciou F#, Clojure, Rust, Scala, Opa, Reia, Elixir
Licença MPL modificada
Extensão do arquivo .erl, .hrl
Página oficial www.erlang.org
LYME baseia Erlang e fornece uma alternativa para LAMP

Erlang é uma linguagem de programação de uso geral e um sistema para execução. Foi desenvolvida pela Ericsson para suportar aplicações distribuídas e tolerantes a falhas a serem executadas em um ambiente de tempo real e ininterrupto. Ela suporta nativamente hot swapping, de forma que o código pode ser modificado sem a parada do sistema. Originalmente uma linguagem proprietária da Ericsson, foi desenvolvida por Joe Armstrong, Robert Virding, e Mike Williams em 1986; foi lançada em código aberto em 1998.[2]

A implementação da Ericsson executa um código interpretado em uma máquina virtual, mas também inclui um compilador para código nativo (ainda que não suportado para todas as plataformas).

Criar e gerenciar processos é uma tarefa trivial em Erlang; de forma geral, threads são consideradas complicadas e fontes de muitos erros de programação em linguagens. A comunicação entre processos é feita por troca de mensagens ao invés de variáveis compartilhadas, o que remove a necessidade de mecanismos explícitos de exclusão mútua[3].

O nome "Erlang", atribuído a Bjarne Däcker, foi compreendido tanto como uma referência ao matemático e engenheiro Agner Krarup Erlang e também como uma abreviação de "Ericsson Language".[4][5]

Erlang foi desenvolvido com o objetivo de melhorar o desenvolvimento de aplicações de telefonia. A versão inicial foi implementada em Prolog e foi influenciada pela linguagem de programação PLEX usada em centrais da Ericsson. De acordo com o co-inventor Armstrong, a linguagem saiu do laboratório para aplicações reais após descontinuarem a central AXE, chamada AXE-N em 1995. Como resultado, Erlang foi escolhido para o próximo modelo chamado AXD.[4]

Em 1998, a Ericsson anunciou a central AXD301 contendo mais de um milhão de linhas de código de Erlang, com relatos de atingir confiabilidade superior a nove "9"s[6]. Logo a seguir o Erlang foi banido na Ericsson Radio System para novos produtos devido a uma preferência pelo uso de linguagens não proprietárias, e Armstrong e outros 14 funcionários deixaram seus cargos por esse motivo, e fundaram uma companhia chamada Bluetail, direcionada a utilizar a tecnologia Erlang em outros produtos. A Ericsson voltou atrás mais tarde e Armstrong foi re-admitido em 2004.[7]

Em 2006, o suporte a multiprocessamento simétrico foi adicionado na máquina virtual e no runtime.[4]

Estruturas de dados

[editar | editar código-fonte]

A linguagem Erlang possui oito tipos de dados primitivos[8]

  • Inteiros: Inteiros são escritos como sequências de dígitos decimais, por exemplo, 12, 12375 e -23427 são inteiros. A aritmética de inteiros é exata e de precisão arbitrária, limitada apenas pela memória disponível ao programa.
  • Átomos: Átomos são usados nos programas para denotar valores distintos. São escritos como sequências de caracteres alfanuméricos, sendo o primeiro uma letra minúscula. Átomos podem conter qualquer caractere se forem fechados entre apóstrofos.
  • Ponto flutuante: Números de ponto flutuante na representação IEEE 754 em 64 bits.
  • Referências: Referências são símbolos globalmente únicos cuja única propriedade é a comparação para igualdade. São criadas avaliando a primitiva make_ref().
  • Binários: Um binário é uma sequência de bytes. Binários proveem um meio que utiliza o espaço de maneira eficaz para armazenar dados binários. Há primitivas em Erlang para compor e decompor binários bem como fazer a entrada e saída deles.
  • Pids: Pid é uma abreviatura de Process Identifier (identificador de processo). São criados pela primitiva spawn(...). Pids são referências para processos Erlang.
  • Portas: Portas são utilizadas para se comunicar com o mundo externo. São criadas pela sub-rotina open_port. A comunicação é realizada por mensagens enviadas e recebidas pelas portas segundo o protocolo de portas do Erlang.
  • Funs: Funs são fechamento de funções. Funs são criadas por expressões da forma: fun(...) -> ... end.

Há dois tipos de dados compostos:

  • Tuplas: Tuplas são recipientes para um número fixo de tipos de dados Erlang, descritas pela sintaxe {D1, D2, ... , Dn}, que denota uma tupla cujos argumentos são D1, D2, ... Dn. Os argumentos podem ser tipos de dados primitivos ou compostos. Os elementos das tuplas podem ser acessados em tempo constante.
  • Listas: Listas são recipientes para um número variável de tipos de dados Erlang. A sintaxe [Dh|Dt] denota uma lista cujo primeiro elemento é Dh, e os demais elementos são a lista Dt. O primeiro elemento da lista e chamado head (cabeça) da lista. O restante da lista quando sua head foi removida é chamada tail (cauda) da lista.

Há dois açúcares sintáticos:

  • Strings: Strings são escritos como uma lista de caracteres fechados entre aspas, como açúcar sintático para uma lista de inteiros com o código ASCII dos caracteres. Por exemplo, a string "gato" é na verdade a lista [103, 97, 116, 111]. Há suporte incompleto para strings Unicode[9].
  • Records: Records (registros) fornecem um meio conveniente para associar um nome a cada elemento de uma tupla. Isso permite se referir a um elemento de uma tupla por nome e não por posição. O pré-compilador substitui a definição dos registros e o substitui com as referências de tupla apropriadas.

Linguagem Funcional

[editar | editar código-fonte]

Veja o código abaixo:

 -module(fact).
 -export([fac/1]).

 fac(0) -> 1;
 fac(N) -> N * fac(N-1).

Abaixo está a implementação de um algoritmo Quicksort

 %% quicksort:qsort(List)
 %% Classificar uma lista de itens
 -module(quicksort).
 -export([qsort/1]).

 qsort([]) -> [];
 qsort([Pivot|Rest]) ->
     qsort([X || X <- Rest, X < Pivot]) ++ [Pivot] ++ qsort([Y || Y <- Rest, Y >= Pivot]).

O exemplo acima invoca a função recursiva qsort até que não reste nada a ser classificado. A expressão [X || X <- Rest, X < Pivot] é uma lista de abrangência, o que significa “construir uma lista de elementos X tal que X pertence ao Resto e X é menor que Pivot“.

Uma função de comparação pode ser usada, no entanto, a ordem em que se baseia o retorno do código Erlang (verdadeiro ou falso) precisa ser alterada. Se, por exemplo, queremos uma lista ordenada onde a < 1 seja verdadeiro (true).

O seguinte código pode classificar listas de acordo com o tamanho:

 -module(listsort).
 -export([by_length/1]).

  by_length(Lists) ->
     qsort(Lists, fun(A,B) when is_list(A), is_list(B) -> length(A) < length(B) end).

  qsort([], _)-> [];
  qsort([Pivot|Rest], Smaller) ->
      qsort([X || X <- Rest, Smaller(X,Pivot)], Smaller)
      ++ [Pivot] ++
      qsort([Y ||Y <- Rest, not(Smaller(Y, Pivot))], Smaller).

Distribuição e Linguagem Orientada a Concorrência

[editar | editar código-fonte]

A principal vantagem de Erlang é suporte a concorrência. Tem um pequeno, mas poderoso, conjunto de funções primitivas para criar processos e fazer com que eles se comuniquem. Processos são o principal meio de criar uma aplicação em Erlang.

Processos, como o sistema operacional (ao contrário de “Green threads” e threads do sistema operacional), não são compartilhadas entre si.

A sobrecarga mínima estimada para cada um é de 300 palavras (4 bytes por palavra sobre plataformas 32-bit, 8 bytes por palavra sobre plataformas 64-bit), e por isso muitas delas podem ser criadas sem degradar o desempenho (foi possível executar 20 milhões de processos[10]).Erlang suporta processamento simétrico na versão R11B desde maio de 2006.

O processo de comunicação é feito através de uma mensagem não-compartilhada em um sistema assíncrono: cada processo tem uma “caixa postal”, uma fila de mensagens enviadas por outros processos, que ainda não foram consumidos.

Um processo utiliza um meio primitivo para recuperar mensagens que correspondam aos padrões desejados.

Uma mensagem de rotina examina mensagens em cada turno, até que um deles seja correspondente. Quando a mensagem é consumida (retirada da caixa postal), o processo recomeça sua execução.Uma mensagem pode incluir qualquer estrutura de Erlang, incluindo funções primitivas (inteiros, ponto flutuante, caracteres,átomos), tuplas, listas e funções.

Exemplo de código:

 % cria um processo e chama a função web:start_server(Port, MaxConnections)
 ServerProcess = spawn (web, start_server, [Port, MaxConnections]),

 % cria um processo remoto e chama a função web:start_server(Port, MaxConnections) na máquina RemoteNode
 RemoteProcess = spawn(RemoteNode, web, start_server, [Port, MaxConnections]),

 % envia para {pause, 10} a mensagem (uma tupla com o átomo "pause" e um número "10") para ServerProcess (assincronamente)
 ServerProcess ! {pause, 10},

 % recebe as mensagens enviadas para este processo
 receive
         a_message -> do_something;
         {data, DataContent} -> handle(DataContent);
         {hello, Text} -> io:format("Ola tenho mensagem: ~s", [Text]);
         {goodbye, Text} -> io:format("Tenho mensagem de saídae: ~s", [Text])
 end.

Tal como mostra o exemplo, existe um suporte de processos distribuídos. Processos podem ser criados em nós (nodes, em inglês) remotos, e a comunicação com eles é transparente (ou seja, a comunicação com os processos remotos é feita exatamente como a comunicação entre os processos locais).

A Concorrência suporta o método primário para tratamento de erro em Erlang. Quando um processo falha, ele é fechado e envia uma mensagem para o processo controlador tomar alguma decisão.

Esta forma de controle de erros pode aumentar a durabilidade e reduzir a complexidade do código.

Referências

  1. Henrik Nord (13 de dezembro de 2023). «Erlang/OTP 26.2 Release». Consultado em 1 de fevereiro de 2024 
  2. Martin Brown (10 de maio de 2011). «Introduction to programming in Erlang, Part 1: The basics» (em inglês). IBM Developer Works. Consultado em 24 de junho de 2011 
  3. David R. Naugler (abril de 2008). «Learning the Erlang programming language» (em inglês). ACM Digital Library. Consultado em 24 de junho de 2011 
  4. a b c Joe Armstrong, "History of Erlang", em HOPL III: Proceedings of the third ACM SIGPLAN conference on History of programming languages, 2007, ISBN 978-1-59593-766-X
  5. «Erlang, the mathematician?». Erlang-questions -- General Erlang/OTP discussions. Consultado em 13 de janeiro de 2012 
  6. «Concurrency Oriented Programming in Erlang» (PDF). 2 de novembro de 2002. Consultado em 13 de janeiro de 2012 
  7. «question about Erlang's future». Erlang-questions -- General Erlang/OTP discussions. 6 de julho de 2010. Consultado em 13 de janeiro de 2012 
  8. «Erlang -- Data Types». Documentação do Erlang. Consultado em 13 de janeiro de 2012 
  9. «Página oficial para uso do Unicode no Erlang». Documentação do Erlang. Consultado em 13 de janeiro de 2012 
  10. Ulf Wiger (14 de novembro de 2005). «Stress-testing erlang». comp.lang.functional.misc. Consultado em 25 de agosto de 2006 

Ligações externas

[editar | editar código-fonte]