Diego Martins [email protected] Evilásio Vilar [email protected]
Erlang Tópicos Avançados de Linguagens de Programação Arthur Umbelino Alves...
Transcript of Erlang Tópicos Avançados de Linguagens de Programação Arthur Umbelino Alves...
Erlang
Tópicos Avançados de Linguagens de Programação
Arthur Umbelino Alves Rolim([email protected])Rodrigo Umbelino Alves Rolim([email protected])
14 de março de
2007
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
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
14 de março de
2007
História1984:Formadolaboratório deComputação da Ericsson
1984-86:ExperiênciasprogramandoPOTS com varias linguagens
1998:Open SourceErlang
1987:Prototipo doprojeto Erlang
1991:Primeira implementaçãorápida
1993:DistributedErlang
1995:Muitosnovos projetos
1996:Open Telecom Platform
Nenhuma linguagem para sistemas de telecomunicações
14 de março de
2007
Características
Concorrência Baseada em processos, com troca de mensagens
assíncronas. Utiliza pouca memória e poucos recursos computacionais.
Real-time 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 Real-time garbage collector
Distribuição 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
n! =1
n*(n-1)!
n = 0
n 1
Definição
-module(ex1).-export([factorial/1]).
factorial(0) -> 1;factorial(N) when N >= 1 -> N * factorial(N-1).
Implementação
Eshell V5.0.1 (abort with ^G)1> c(ex1).{ok,ex1}2> ex1:factorial(6).720
Programação seqüencial
14 de março de
2007
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 booleanos1> 2 =< 3true2> true or falsetrue
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 ordemforeach(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,
...
Programação concorrente
14 de março de
2007
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 Nó que se conecta com apenas um outro nó,
invés de todos C nodes
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 Sistema de registro global de nomes
global_group Grupos de registro global
net_adm Várias rotinas para administração de redes
net_kernel Kernel da rede Erlang
14 de março de
2007
Distribuição transparente
Erlang Run-Time SystemErlang Run-Time System Erlang Run-Time SystemErlang Run-Time System
B ! Msg
rede
C ! Msg
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 entre processos Sinais EXIT
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 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 0-
13-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
?