Erlang Tópicos Avançados de Linguagens de Programação Arthur Umbelino Alves...

Post on 19-Apr-2015

133 views 0 download

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(auar@cin.ufpe.br)Rodrigo Umbelino Alves Rolim(ruar@cin.ufpe.br)

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

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

?