Erlang
Tags: erlang
Published: 2023-05-24 20:46:39

O **Erlang** é uma linguagem de programação de uso geral e um sistema para execução, também é uma linguagem declarativa para programar sistemas concorrentes e distribuídos que foi desenvolvida pela Ericsson e Ellemtel Computer Science Laboratories 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.

> **Hot swap** ou **Hot swapping** (A tradução literal é Troca quente) é a capacidade de retirar e de substituir componentes de uma máquina, normalmente um computador, enquanto opera (ou seja não é necessário reiniciar o computador). A tecnologia hot-swap presente em disco rígido e em controladoras SCSI permite que a troca de um disco defeituoso possa ser feita com o sistema operativo em execução. Os exemplos mais comuns são os dispositivos USB e FireWire tais como: mouse, teclado, impressoras e pen drive. Normalmente exige software do tipo "Ligar e Usar" (Plug-and-Play). 
> 
> Os discos RAID, de maior nível, são hot-swap, ou seja um disco com falha pode ser removido ou substituído sem perda de dados ou interrupções do servidor graças a controladora de hardware RAID e o carregador de disco. Com o hot-swap RAID, o sistema continua operando, enquanto o conteúdo do disco avariado é reconstruído em um disco sobressalente, usando informação redundante ou paridade.

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.

O desenvolvimento de Erlang começou como uma investigação sobre se os paradigmas modernos de programação declarativa poderiam ser usados para programar grandes sistemas de computação de telecomunicações industriais. Logo, se percebeu que as linguagens adequadas para a programação de sistemas de telecomunicações também eram adequadas para uma ampla gama de problemas de controle em tempo real embutidos na indústria.

Muitas das primitivas Erlang fornecem soluções para problemas que são comumente encontrados durante a programação de grandes sistemas simultâneos de tempo real:

- O sistema de módulos permite a estruturação de programas muito grandes em unidades conceitualmente gerenciáveis.
- Os mecanismos de detecção de erros possibilitam a construção de software tolerante a falhas.
- As primitivas de carregamento de código permitem que o código em um sistema em execução seja alterado sem parar o sistema.

Erlang tem um modelo de concorrência baseado em processo. A simultaneidade é explícita, e o usuário pode controlar com precisão quais cálculos são executados sequencialmente e quais são executados em paralelo.

> A passagem da mensagem entre os processos é assíncrona, ou seja, o processo de envio continua assim que a mensagem é enviada.

O único método pelo qual os processos Erlang podem trocar dados é a passagem de mensagens. Isso resulta em aplicativos que podem ser facilmente distribuídos − um aplicativo escrito para um uniprocessador pode ser alterado para rodar em um multiprocessador ou rede de uniprocessadores. A linguagem possui mecanismos embutidos para programação distribuída, que torna mais fácil escrever aplicativos que podem ser executados em um único computador ou em uma rede de computadores.

Variáveis em Erlang têm a propriedade de atribuição única − uma vez que um valor foi atribuído a uma variável, esse valor nunca pode ser alterado. Essa propriedade tem consequências importantes ao depurar ou transformar um programa, que é escrito inteiramente em termos de funções. A seleção de função é feita por correspondência de padrões que leva a programas altamente sucintos.

O sistema Erlang tem uma noção embutida de tempo, ou seja, o programador pode especificar quanto tempo um processo deve esperar por uma mensagem antes de realizar alguma ação. Isso permite a programação de aplicativos em tempo real, tornando o Erlang adequado para a maioria das aplicações soft em tempo real nas quais os tempos de resposta são da ordem de milissegundos.

> **Comentário**: As técnicas de programação para sistemas simultâneos de tempo real ficaram, por muitos anos, atrás das técnicas usadas para programar aplicativos sequenciais. Quando o uso de linguagens como C ou Pascal era uma prática padrão para a programação de aplicativos sequenciais, a maioria dos programadores de sistemas de tempo real ainda lutava com as linguagens assembly. Os sistemas de tempo real atuais podem ser escritos em linguagens como Ada, Modula2, Occam etc., nas quais existem construções explícitas para simultaneidade de programação, ou em linguagens como C, que não possuem construções para simultaneidade.

O interesse em simultaneidade é motivado por um estudo de problemas que exibem alto grau de simultaneidade natural − essa é uma propriedade típica de problemas de controle em tempo real. O programador Erlang determina explicitamente quais atividades devem ser representadas como processos paralelos.

> **Atenção**: Essa visão de simultaneidade é semelhante à encontrada em Occam, CSP, Concurrent Pascal etc., mas diferente das linguagens concorrentes. Nestas, a principal motivação para introduzir a simultaneidade não é para modelar a simultaneidade do mundo real, mas para obter um desempenho superior, compilando programas para execução em um processador paralelo.

São características do Erlang:

- **SINTAXE DECLARATIVA**: Erlang tem uma sintaxe declarativa e é amplamente livre de efeitos colaterais.
- **SIMULTANEIDADE**: Erlang tem um modelo baseado em processo de simultaneidade com passagem de mensagem assíncrona. Os mecanismos de simultaneidade em Erlang são leves, ou seja, os processos requerem pouca memória, e a criação e a exclusão de processos, assim como a passagem de mensagens, requerem pouco esforço computacional.
- **TEMPO REA**L: Erlang destina-se à programação de sistemas soft em tempo real, nos quais os tempos de resposta da ordem de milissegundos são necessários.
- **OPERAÇÃO CONTÍNUA**: Erlang tem primitivas que permitem que o código seja substituído em um sistema em execução e que versões antigas e novas de código sejam executadas ao mesmo tempo. Isso é de grande utilidade em sistemas non stop, centrais telefônicas, sistemas de controle de tráfego aéreo etc., em que os sistemas não podem ser interrompidos para fazer alterações no software.
- **ROBUSTEZ**: A segurança é um requisito crucial em sistemas como o mencionado anteriormente. Existem três construções na linguagem para detectar erros de tempo de execução, que podem ser usadas para programar aplicativos robustos.
- **GERENCIAMENTO DE MEMÓRIA**: Erlang é uma linguagem de programação simbólica com um coletor de lixo em tempo real. A memória é alocada automaticamente quando necessário e desalocada quando não é mais usada. Não podem ocorrer erros de programação típicos associados ao gerenciamento de memória.
- **DISTRIBUIÇÃO**: Erlang não tem memória compartilhada, toda interação entre processos é por passagem de mensagem assíncrona. Os sistemas distribuídos podem ser facilmente construídos em Erlang, e os aplicativos escritos para um único processador podem, sem dificuldade, ser portados para rodar em redes de processadores.
- **INTEGRAÇÃO**: Erlang pode facilmente chamar ou usar programas escritos em outras linguagens de programação. Eles podem ser conectados ao sistema de forma que pareçam ao programador como se tivessem sido escritos em Erlang.
 
A aplicação mais famosa que fez uso do Erlang foram **os servidores do WhatsApp**. Uma equipe de apenas 50 engenheiros de software foi capaz de criar um aplicativo robusto, com 900 milhões de usuários, na época.

## Estruturas de dados do Erlang
A linguagem Erlang possui oito tipos de dados primitivos:

- **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.
- **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.