Erlang
Tópicos Avançados de Linguagens de Programação
Arthur Umbelino Alves Rolim([email protected])
Rodrigo Umbelino Alves Rolim([email protected])
Conteúdo




Introdução
História
Características
A linguagem








Programação seqüencial
Programação concorrente
Programação distribuída
Compilação
Code Replacement
Tratamento de erros
Conclusão
Referências
14 de março de 2007
Introdução

O que é Erlang?




Linguagem de programação concorrente para
desenvolvimento de sistemas de controle, de
tempo real, distribuídos e em larga escala
Utilizada em diversos sistemas de
telecomunicações da Ericsson
A implementação mais popular é disponibilizada
como Open Source
Influência de linguagens funcionais, lógicas e de
sistemas de controle
14 de março de 2007
Introdução

Em que tipos de aplicações Erlang é util?


Sistemas concorrentes, soft real-time, distribuídos
e de controle
Sistemas de telecomunicações



Ex: Controlar um Switch, Conversão de protocolos
Aplicações de bancos de dados que requerem um
comportamento soft real-time
Servidores para aplicações da Internet

Ex: Servidor IMAP-4, servidor HTTP, WAP, etc.
14 de março de 2007
Quem usa Erlang de hoje






Ericsson: AXD 301, GPRS,
(NetSim), LCS
Nortel: SSL Accelerator, SSL
VPN gateway + others
TMobile: IN applications
Vail Systems: Computer
Telephony Apps Service Prov.
Erlang Financial Systems:
Banking & Lottery systems
Mobile Arts: Presence &
Messaging for GSM/UMTS







14 de março de 2007
Synap.se: Billing & device
configuration
Blue Position: Bluetooth
Location Information System
Motivity: Answer Supervision
Generator, Signalling Gateway
Telia: CTI Platform
Corelatus: Signalling gateways
& cross-connects
Bluetail/TeleNordia: Robust
SMTP Mail Server
Univ. of Coruña: VoD Cluster
História
1984:
Formado
laboratório de
Computação da
Ericsson
1984-86:
Experiências
programando
POTS com
varias linguagens
Nenhuma linguagem
para sistemas de
telecomunicações
1991:
Primeira implementação
rápida
1987:
Prototipo do
projeto Erlang
1996:
Open Telecom Platform
1993:
Distributed
Erlang
14 de março de 2007
1998:
Open Source
Erlang
1995:
Muitos
novos projetos
Características

Concorrência


Real-time


Baseada em processos, com troca de mensagens
assíncronas. Utiliza pouca memória e poucos
recursos computacionais.
Erlang é utilizada na programação de sistemas soft
real-time, onde o tempo de resposta é na ordem de
milissegundos
Linguagem funcional

Sintaxe declarativa livre de efeitos colaterais
14 de março de 2007
Características

Operação contínua
 Possui primitivas que permitem a substituição de código
sem necessidade de parar o sistema e permite que código
novo e antigo executem ao mesmo tempo
 Muito útil para fazer atualizações e correções de bugs em
sistemas que não podem parar

Robustez
 Possui várias primitivas de detecção de erros para a
estruturação de sistemas tolerantes a falhas
14 de março de 2007
Características

Gerenciamento de memória


Distribuição


Real-time garbage collector
Facilidade de construção de sistemas distribuídos
Integração


Erlang pode chamar ou utilizar programas escritos em
outras linguagens
Interface transparente
14 de março de 2007
A linguagem
%% Arquivo ex1.erl
Definição
1
n! =
n*(n-1)!
Implementação
n=0
n 1
-module(ex1).
-export([factorial/1]).
factorial(0) ->
1;
factorial(N) when N >= 1 ->
N * factorial(N-1).
Eshell V5.0.1 (abort with ^G)
1> c(ex1).
{ok,ex1}
2> ex1:factorial(6).
720
14 de março de 2007
Programação seqüencial
Tipos de dados

Constantes




Números
Átomos
Pids
Compostos



Tuplas
Listas
strings
14 de março de 2007
Constantes

Números


Inteiros
10
-234
16#AB10F
2#1101101101
$A
Floats
17.368
-56.654
12.34E-10
14 de março de 2007
Constantes

Átomos





Tamanho indefinido
São constantes literais
O seu valor é o próprio átomo
Começam com uma letra minúscula
Qualquer código de caractere é permitido entre aspas
friday unquoted_atoms_cannot_contain_blanks
'A quoted atom which contains several blanks'
'hello \n my friend'
14 de março de 2007
Compostos

Tuplas


Usadas para armazenar um número fixo de
elementos
São permitidas tuplas de qualquer tamanho
{123, bcd}
{123, def, abc}
{person, ‘Joe’, ‘Armstrong’}
{abc, {def, 123}, jkl}
{}
14 de março de 2007
Compostos

Funções auxiliares

element(N,T) devolve elemento na posição N da
tupla


element(2,{a,b,c}) → b
setelement(N,T,V) atribui ao elemento na posição
N o valor V

setelement(2,{a,b,c},x) →{a,x,c}
14 de março de 2007
Compostos

Listas



Armazenam um número variável de elementos
Número de elementos constitui o comprimento da
lista
Exemplos





[]
[1 | [] ] → [1]
[1,2,3]
[1 | [2 | [3 | [] ] ] ] → [1,2,3]
[[1,2,3] | [4,5,6]] → [[1,2,3],4,5,6]
14 de março de 2007
Compostos

Estruturas complexas
[ { {person,'Joe', 'Armstrong'},
{telephoneNumber, [3,5,9,7]},
{shoeSize, 42},
{pets, [{cat, tubby},{cat, tiger}]},
{children,[{thomas, 5},{claire,1}]}},
{ {person,'Mike','Williams'},
{shoeSize,41},
{likes,[boats, beer]},
...
14 de março de 2007
Strings e booleans


Não são tipos de dados em Erlang
Átomos true e false são utilizados para
denotar os valores booleanos
1> 2 =< 3
true
2> true or false
true

Strings são listas

“hello” equivale a [$h,$e,$l,$l,$o], que por sua vez
equivale a [104,101,108,108,111] e “” a [].
14 de março de 2007
Variáveis

Atribuição única



Valor nunca pode ser modificado depois do bind
Iniciam com letra maiúscula
Armazenam valores de estruturas de dados
Abc
A_long_variable_name
14 de março de 2007
Pattern Matching
> {A, B} = {[1,2,3], {x,y}}.
> A.
[1,2,3]
> B.
{x,y}
> [a,X,b,Y] = [a,{hello, fred},b,1].
> X.
{hello,fred}
> Y.
1
> {_,L,_} = {fred,{likes, [wine, women, song]},{drinks, [whisky,
beer]}}.
> L.
{likes,[wine,women,song]}
14 de março de 2007
Pattern Matching - Continuação
[A, B | C] = [1, 2, 3, 4, 5, 6, 7]
OK, A = 1, B = 2, C = [3, 4, 5, 6, 7]
[H | T] = [1, 2, 3, 4]
OK, H = 1, T = [2, 3, 4]
[H | T] = [abc]
OK, H = abc, T = []
[H | T] = []
Erro
{A, _, [B | _], {B}} = {abc, 23, [22, x], {22}}
A = abc, B = 22
14 de março de 2007
Chamada de função
modulo : func(Arg1, Arg2, ..., Argn)
func(Arg1, Arg2, ..., Argn)





Arg1 ... Argn são estruturas de dados Erlang
Os nomes das funções e dos módulos devem ser
átomos
Funções podem não ter argumentos (ex: date())
Funções são definidas dentro de módulos
Devem ser exportadas antes de serem chamadas
fora do módulo onde foram definidas
14 de março de 2007
Sistema de módulos
-module(demo).
-export(double/1)
double(X) -> times(X, 2).
times(X, N) -> X * N.


double pode ser chamado de fora do módulo
times é local ao módulo, não pode ser chamado
de fora
14 de março de 2007
Built-in functions (BIFs)
date()
time()
length([1, 2, 3, 4, 5])
size({a, b, c})
atom_to_list(atom)
list_to_tuple([1, 2, 3, 4])
integer_to_list(2234)
tuple_to_list({})
apply(Mod, Func, ArgList)
apply({Mod, Func}, ArgList)
...
 Estão no módulo erlang
 Fazem o que é difícil ou impossível em Erlang
14 de março de 2007
Sintaxe de Funções
func(padrao1, padrao2, ...) -> ... ;
func(padrao1, padrao2, ...) -> ... ;
func(padrao1, padrao2, ...) -> ... .

Regras de avaliação




Cláusulas são lidas sequencialmente até que ocorra um
match
Quando ocorre um match, são feitos os binds
Variáveis são locais a cada cláusula, e são alocadas e
desalocadas automaticamente
O corpo da função é avaliado sequencialmente
14 de março de 2007
Funções
-module(mathStuff).
-export([factorial/1, area/1]).
factorial(0) -> 1;
factorial(N) -> N * factorial(N-1).
area({square, Side}) -> Side * Side;
area({circle, Radius}) -> % almost :-) 3 * Radius * Radius;
area({triangle, A, B, C}) -> S = (A + B + C)/2,
math:sqrt(S*(S-A)*(S-B)*(S-C));
area(Other) -> {invalid_object, Other}.
14 de março de 2007
Guards
factorial(0) -> 1;
factorial(N) when N > 0 -> N * factorial(N - 1).
 Condições que têm de ser satisfeitas antes de uma
cláusula ser escolhida
 A palavra reservada when introduz um guard.
 Cláusulas com guards podem ser reordenadas.
factorial(N) when N > 0 -> N * factorial(N - 1);
factorial(0) -> 1.
 Não equivale a:
factorial(N) -> N * factorial(N - 1);
factorial(0) -> 1.
 (incorreto!!)
14 de março de 2007
Guards - Exemplos
number(X)
integer(X)
float(X)
atom(X)
tuple(X)
list(X)
length(X) == 3
size(X) == 2
X>Y+Z
X == Y
X =:= Y
14 de março de 2007
Compreensão de listas
[Lista || Gerador, Filtro]
[X || X <- [1,2,a,3,4,b,5,6], X > 3].




A lista de X na qual X é retirado da lista [1,2,a,...]
e X é maior que 3.
[a,4,b,5,6]
X <- [1,2,a,...] é um gerador
X > 3 é um filtro
14 de março de 2007
Compreensão de listas
Quick Sort
sort([Pivot|T]) ->
sort([ X || X <- T, X < Pivot]) ++
[Pivot] ++
sort([ X || X <- T, X >= Pivot]);
sort([]) -> [].

14 de março de 2007
Funções de alta ordem
foreach(Fun, [First|Rest]) ->
Fun(First),
foreach(Fun, Rest);
foreach(Fun, []) -> ok.
map(Fun, [First|Rest]) ->
[Fun(First)|map(Fun,Rest)];
map(Fun, []) -> [].
92> Add_3 = fun(X) -> X + 3 end.
#Fun<erl_eval.5.123085357>
93> lists:map(Add_3, [1,2,3]).
[4,5,6]
14 de março de 2007
If e Case
case lists:member(a, X) of
true -> ... ;
false -> ...
end,
...
if
integer(X) -> ... ;
tuple(X) -> ...
end,
...
14 de março de 2007
Programação concorrente
Programação concorrente


Erlang foi projetada para suportar
concorrência massiva
Processos são leves




Crescem e diminuem dinamicamente
Pouco consumo de memória
São inicializados e terminados de forma rápida
Scheduling possui pouco overhead
14 de março de 2007
Criando um processo



Pid – Identificador único de um processo
spawn(Module, Name, Args) cria um novo
processo e retorna seu Pid
O novo processo criado irá iniciar
executando em Module:Name(Arg1, Arg2, ...)
14 de março de 2007
Criando um processo
Antes:
Depois:
Pid2 = spawn(Mod, Func, Args)
Pid2 é o identificador de processo do novo processo,
apenas conhecido pelo processo Pid1.
14 de março de 2007
Registro de processos
register(Nome, Pid)
 Regista o processo Pid com o nome global
Nome
 Nome tem que ser um átomo
 Envio de mensagens através do nome
registado
nome_registado ! Msg
14 de março de 2007
Registro de processos - Continuação

Algumas primitivas



unregister(Nome) - Remove a associação
whereis(Nome) - devolve Pid associado a Nome
ou undefined
registered() - devolve lista dos processos
registados
14 de março de 2007
Envio de mensagens



Sender ! Msg – Operador de envio de mensagens
receive – Bloco que trata o recebimento de
mensagens
self() – Retorna o Pid do processo que executou
esta função
14 de março de 2007
Envio de mensagens - Continuação


Mensagens podem carregar dados e serem
seletivamente desempacotadas
Envio de mensagens é assíncrono e seguro

A mensagem sempre chega, dado que o receptor existe
14 de março de 2007
Programação distribuída

Distributed Erlang System




Conjunto de máquinas virtuais Erlang
comunicando entre si
Cada máquina virtual é um nó
Envio de mensagens, links e monitores entre
diferentes nós é transparente quando Pids são
usados
Mecanismo de distribuição é implementado via
sockets TCP/IP
14 de março de 2007
Nó


Toda máquina virtual Erlang é dada um
nome, usando os flags –name (nomes
longos) ou –sname (nomes curtos) na linha
de comando
nome@host



Para nomes longos, host é o nome do host
completo
Para nomes curtos, apenas parte do host é usada
node() – Retorna o nome do nó
14 de março de 2007
Nó - Exemplo

Um nó com nome longo não pode se
comunicar com um nó de nome curto
14 de março de 2007
Conexão entre nós

Na primeira vez que o nome de um nó remoto é
utilizado, é feita uma conexão com o mesmo

spawn(Node, M, F, A) ou net_adm:ping(Node) –
Cria um processo no nó remoto
Conexões são transitivas



Para desativar: -connect all false
Se um nó cai, todas as conexões com ele são
removidas

Erlang:disconnect(Node) – Força a disconexão de um nó
14 de março de 2007
Distribuição - Continuação

Hidden nodes


C nodes


Nó que se conecta com apenas um outro nó,
invés de todos
Um programa escrito em C que age como um
Hidden Node
Magic cookies

Mensagens trocadas entre nós para garantir
segurança
14 de março de 2007
Módulos de distribuição

global


global_group


Grupos de registro global
net_adm


Sistema de registro global de nomes
Várias rotinas para administração de redes
net_kernel

Kernel da rede Erlang
14 de março de 2007
Distribuição transparente
B ! Msg
C ! Msg
Erlang Run-Time System
Erlang Run-Time System
rede
14 de março de 2007
Compilação


Códigos Erlang são compilados para códigos
de objeto
BEAM - Bogdans's Erlang Abstract
Machine


.beam
O compilador também gera binários
14 de março de 2007
Compilação - Continuação
compile:file(Module)
compile:file(Module, Options)

No Erlang shell


c(Module)
Compila e carrega o módulo
14 de março de 2007
Code Replacement





Suporta a mudança de código em um
sistema em execução
Ideal para sistemas que não podem parar
para serem feitas atualizações e correções
de bugs
Feita ao nível de módulo
Old e current
Código atual é sempre referenciado usando
chamadas completas modulo:nome
14 de março de 2007
Code Replacement- Exemplo
-module(m).
-export([loop/0]).
loop() ->
receive
code_switch ->
m:loop();
Msg ->
...
loop()
end.
14 de março de 2007
Tratamento de erros

Programas podem conter erros lógicos



Não detectáveis pelo compilador
Erlang fornece mecanismo de detecção e
tratamento de erros em run time
Primitivas catch e throw


Proteger o código de erros (catch)
Tratamento de excepções (catch e throw)
14 de março de 2007
Proteção contra erros
catch Expressão
 Se não existir falha retorna o valor de Expressão
 Se existir falha retorna {’EXIT’,Razão}



Razão contém a explicação para o erro
Processo não termina devido ao erro
Exemplos



catch 1 + 3 → 4
catch 1 + a → {’EXIT’,{badarith,: : :}}
catch somar(A,B) → depende dos valores de A e B
14 de março de 2007
Tratamento de exceções
throw(Exceção)
 Retorna uma exceção a um catch associado



Mesmo que lançada vários níveis abaixo
Exceção propaga-se até ser encontrado um
catch
Se não existir um catch ocorre um erro de
execução
14 de março de 2007
Tratamento de exceções – Cont.
test(X) ->
catch test1(X),
’processo nao morreu’.
test1(X) ->
...,
test2(X).
test2(X) when list(X)->
throw({erro,’nao sei processar listas’});
test2(X) ->
processar(X).

Processo trata as excepções e não termina

Sem catch é gerado erro de execução se for lançada a
excepção

Processo termina!
14 de março de 2007
Monitorização de processos

Erlang permite monitorizar processos



Ligações podem ser estabelecidas



Na criação do novo processo
spawn_link(Modulo,Função,Lista de argumentos)
Durante a execução link(Pid)
Ligações são bidireccionais



Ligações entre processos
Sinais EXIT
A estabelece uma ligação com B
B é automaticamente ligado a A
Ligações podem ser removidas com unlink(Pid)
14 de março de 2007
Sinais


Quando um processo falha, sinais de término são
propagados para todos os processos associados
a ele através de Link
Sinal - {’EXIT’,Pid,Razão}
14 de março de 2007
Propagação de sinais de término

Regra da propagação de erros

Se um processo que recebe sinal de término, causado por
um erro, não está fazendo error trapping, o mesmo
morrerá e enviará sinais de término para todos os
processos ligados a ele
14 de março de 2007
Error trapping
receive
{'EXIT', P1, Why} ->
... Sinais de término ...
{P3, Msg} ->
... Mensagens normais ...
end
14 de março de 2007
Conclusão





Completa
Fácil aprendizado
Open Source
Inúmeras ferramentas
Apoio da Ericsson®
14 de março de 2007
Referências





Site oficial da Open Erlang – www.erlang.org
Concurrent Programming in Erlang, ISBN 013-285792-8
Erlang Reference manual
Curso sobre Erlang www.dei.isep.ipp.pt/~luis/orgc/slides/erlang/
http://en.wikipedia.org/wiki/Erlang_%28programming_language%29
14 de março de 2007
?
14 de março de 2007
Download

erlang