erlang -progamaçãosequencial-luis/orgc/slides/erlang/sequencial.pdfintroduc¸ao˜ linguagem...

38
Erlang - Progamação Sequencial - Lu´ ıs Nogueira [email protected] Departamento Engenharia Inform ´ atica Instituto Superior de Engenharia do Porto Erlang – p. 1

Upload: duongtu

Post on 20-Jan-2019

216 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Erlang- Progamação Sequencial -

Luıs Nogueira

[email protected]

Departamento Engenharia Informatica

Instituto Superior de Engenharia do Porto

Erlang – p. 1

Page 2: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Introducao

• Linguagem funcional para sistemas concorrentes edistribuídos

• Desenvolvida pela Ericsson• Necessidade de encontrar uma linguagem para grandes

sistemas de telecomunicações◦ Distribuída◦ Concorrente◦ Tolerante a falhas◦ Substituição de código em run time

Erlang – p. 2

Page 3: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Principais caracterısticas

• Sintaxe declarativa - livre de efeitos colaterais (ex: variáveisglobais)

• Concorrente - processos requerem pouca memória• Soft real-time - tempos de resposta na ordem dos

milisegundos• Operação contínua - substituição de código em run time• Robusta - detecção de erros em run time• Gestão de memória - garbage collection em tempo real• Distribuída - processos comunicam por passagem de

mensagens• Integração - facilidade de usar/ser usada com outras

linguagens

Erlang – p. 3

Page 4: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Linguagem funcional

• Trata a computação como a avaliação de funçõesmatemáticas

• Funções como caixas negras◦ Para o mesmo input, sempre o mesmo output◦ Podemos “esquecer” o seu interior◦ Facilita a reutilização de código

• Variáveis não alteram o seu valor após instanciação• Funções de ordem superior - aceitam funções como

parâmetro

Erlang – p. 4

Page 5: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Conselho para as aulas praticas

• Erlang tem uma sintaxe declarativa

• MAS NÃO É PROLOG :)◦ Não há backtracking◦ Todas as variáveis passadas a uma função devem estar

instanciadas◦ Uma função devolve sempre um valor

Erlang – p. 5

Page 6: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Tipos de dados

• Números - inteiros e vírgula flutuante

• Átomos• Tuplos• Listas• Records• Pids (Process Identifier)• Ports• Referências• Binários

Erlang – p. 6

Page 7: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Numeros

• Inteiros

◦ 234◦ 16#ab10f◦ 2#11010101011◦ $A◦ Base#Valor representa um dado valor numa dada

base◦ $Char representa o valor Ascii do caracter

• Vírgula flutuante◦ 45.543◦ 12.34E-10

Erlang – p. 7

Page 8: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Atomos

• São constantes literais• O seu valor é o próprio átomo• Começam com uma letra minúscula• Entre plicas podem conter qualquer caracter• Fora de plicas usar apenas letras “normais”, dígitos e

underscore• Exemplos

◦ abcef23◦ comecam_com_uma_letra_minuscula◦ ’podem ter espaços e outros caracteresdentro de plicas’

Erlang – p. 8

Page 9: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Tuplos

• Agrupar um número fixo de elementos• Sem tamanho máximo para número de elementos ou níveis• Exemplos

◦ {x,’elemento 2’}◦ {a, b,{c,d,[1,2,3,4]},{e,[{x,y,z},f,g]}}

• Funções auxiliares◦ element(N,T) devolve elemento na posição N

• element(2,{a,b,c})→b◦ setelement(N,T,V) atribui a elemento na posição N

valor V• setelement(2,{a,b,c},x)→{a,x,c}

Erlang – p. 9

Page 10: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Listas

• Agrupar um número variável de elementos• Número de elementos constitui o comprimento da lista• Cabeça e cauda ( [H|T])• Exemplos

◦ []◦ [1|[]] → [1]◦ [1,2,3]◦ [1|[2|[3|[]]]] → [1,2,3]◦ [[1,2,3]|[4,5,6]] → [[1,2,3],4,5,6]

Erlang – p. 10

Page 11: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Variaveis

• Usadas para guardar termos Erlang• Uma vez instanciadas não podem mudar o seu valor• Começam por letra maiúscula• underscore pode tomar qualquer valor• Não é necessário declarar variáveis• Exemplos

◦ UmaVariavel◦ Outra_variavel

Erlang – p. 11

Page 12: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Pattern matching

• Atribuição◦ A=2

• Extracção de dados◦ {Nome,Conteudo} = {lista,[1,2,3]}

• Teste◦ Valor = 1, {Valor,X} = {Y,termo_erlang}◦ {A,B,C} = {1,2,3} (sucesso: A=1,B=2,C=3)◦ {A,A,C} = {1,2,3} (falha:A=1!)

Erlang – p. 12

Page 13: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Funcoes

• Cabeça◦ Nome da função◦ Número variável de parâmetros (pode não ter

argumentos)• Corpo

◦ Código a executar• Terminador

◦ Ponto final• Exemplo

soma(Op1, Op2) ->Op1 + Op2.

Erlang – p. 13

Page 14: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Funcoes

• Usada sempre que chamada pelo seu nome e número deparâmetros (aridade)

vezes(X,N) ->X * N.

dobro(X) ->vezes(2,X).

• Mesmo nome mas aridade diferente → funções diferentes!• Devolvem valor determinado pela última acção• Memória é alocada e libertada automaticamente• Todos os parâmetros devem ser conhecidos quando a

função é chamada

Erlang – p. 14

Page 15: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Funcoes com n clausulas

func(Padrao1,Padrao2,...,PadraoN) ->instrucao1,...,instrucaoN;

func(Padrao1,Padrao2,...,PadraoN) ->instrucao1,...,instrucaoN.

• As cláusulas são pesquisadas sequencialmente• Quando é encontrado o padrão correcto todas as variáveis

ficam instanciadas• As variáveis são locais a cada cláusula

Erlang – p. 15

Page 16: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Modulos

• Funções são agrupadas em módulos• Ficheiro deve ter o mesmo nome do módulo (teste.erl)

-module(teste).-export([dobro/1]).vezes(X,N) ->

X * N.dobro(X) ->

vezes(2,X).

• dobro/1 pode ser chamada de fora do módulo• vezes/2 é local ao módulo

Erlang – p. 16

Page 17: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Modulos

• Funções identificadas por módulo, nome e aridade

teste:dobro(5).

• Uma função tem que ser exportada para ser visível fora domódulo

• Dentro do mesmo módulo pode ser omitido nome domódulo◦ Se for usado tem significado especial: permite a

substituição do código em run time

Erlang – p. 17

Page 18: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Recursividade

• Se o valor de uma variável não pode ser alterado depois deter sido atribuído, como podemos fazer iterações?

• Usando recursividade

for(N) -> for(0) ->

for(1,N). ok;

for(N,N) -> for(N) ->

ok; for(N-1).

for(N,Max) ->

for(N+1,Max).

Erlang – p. 18

Page 19: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Recursividade

• A recursividade é muito comum em listas

media(L) ->soma(L) / comprimento(L).

soma([]) ->0;

soma([H|T]) ->H + soma(T).

comprimento([]) ->0;

comprimento([_|T]) ->1 + comprimento(T).

Erlang – p. 19

Page 20: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Recursividade

• Mais padrões comuns

dobro([]) ->[];

dobro([H|T]) ->[2*H|dobro(T)].

membro(X,[X|T]]) ->true;

membro(X,[H|T]) ->membro(X,T);

membro(X,[]) ->false.

Erlang – p. 20

Page 21: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Recursividade

• Usando acumulador

soma(L) ->soma(L,0).

soma([H|T],Soma) ->soma(T,Soma + H);

soma([],Soma) ->Soma.

• Esta versão executa num espaço constante de memória!◦ Memória e velocidade do programa◦ Last call optimization

Erlang – p. 21

Page 22: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Recursividade

• Mais alguns exemplos

comprimento(L) ->comprimento(L,0).

comprimento([H|T],C) ->comprimento(T,C + 1);

comprimento([],C) ->C.

media(L) ->media(L,0,0).

media([H|T],S,C) ->media(T,S + H,C + 1);

media([],S,C) ->S / C.

Erlang – p. 22

Page 23: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Guards

• Condições que têm de ser satisfeitas antes de umacláusula ser escolhida

• Extensão do pattern matching• Apenas um teste ou uma sequência de testes

◦ separados por vírgulas (operador lógico and)◦ pontos e vírgulas (operador lógico or)

• Funções definidas pelo programador não podem serusadas como guards

• when introduz um guard

factorial(1) ->1;

factorial(N) when N > 1 ->N * factorial(N - 1).

Erlang – p. 23

Page 24: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Guards

• Todas as variáveis usadas num guard devem estarinstanciadas

• As cláusulas protegidas com guards podem serreordenadas

factorial(1) ->1;

factorial(N) when N > 1 ->N * factorial(N - 1).

◦ o mesmo que

factorial(N) when N > 1 ->N * factorial(N - 1);

factorial(1) ->1.

Erlang – p. 24

Page 25: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Guards

• Sem guards a ordem das cláusulas não pode ser trocada

factorial(N) ->N * factorial(N - 1);

factorial(1) ->1.

• Exemplos de guardsis_atom/1 is_binary/1 is_list/1

is_float/1 is_integer/1 is_number/1

is_pid/1 is_reference/1 is_record/1

length(List) size(Tuple) X > Y + Z

X == Y element(N,Tuple) hd(List)

Erlang – p. 25

Page 26: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Built-in Functions (BIFs)

• Funções do módulo erlang• Funcionalidades difíceis (ou ineficientes) de conseguir em

Erlang• São as únicas funções que podem ser usadas como guards• Exemplos

trunc(5.6) → 5round(5.6) → 6length([a,b,c,d]) → 4element(2,{a,b,c}) → bfloat(5) → 5.00000is_atom(hello) → truedate() → {2005,02,18}

Erlang – p. 26

Page 27: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Records

• Armazenar um número fixo de elementos• Tuplos apenas acedem aos elementos pela sua posição

◦ Alteração da ordem, remoção ou adição de elementosimplica alteração do programa!

• Records permitem aceder aos elementos pelo seu nome◦ Podemos ignorar a sua ordem

• Não são um tipo de dados nativo◦ São traduzidos para tuplos pelo compilador

Erlang – p. 27

Page 28: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Declaracao de um record

-record(nome_record,{campo1 [=Valor1],...,campoN [=ValorN]})

• Nome do record e dos campos deve ser um átomo• Pode ser dado um valor por omissão a cada campo

◦ Se não for especificado campo assume undefined

• Deve ser declarado antes do seu uso numa função• Exemplo

-record{pessoa,{nome, instituicao=’ISEP’, telefone})

Erlang – p. 28

Page 29: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Criar uma instancia de um record

#nome_record{ campo_1 = Valor1,..., campo_n = Valor_N}

• Os campos podem ser especificados em qualquer ordem• Podem ser omitidos campos

◦ É-lhes atribuído valor por omissão• Exemplo

P = #pessoa{nome=’Joao’}

{pessoa, ’Joao’, ’ISEP’, undefined}

Erlang – p. 29

Page 30: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Aceder a um campo de um record

Record#nome_record.Campo

• Retorna o valor do campo indicado• Record deve ser uma variável do tipo record• Posição do campo pode ser obtida

#nome_record.Campo

• Exemplo

Nome = P#pessoa.nome

Nome → ’Joao’

Erlang – p. 30

Page 31: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Actualizar um record

Novo = Record#nome_record{campo_i = Valor, ...}

• Retorna uma cópia do record com os valores alterados• Record deve ser uma variável do tipo record• Exemplo

P2 = P#pessoa{telefone=12345679}

P2 → {pessoa,’Joao’,ISEP’,123456789}

Erlang – p. 31

Page 32: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Records em guards

• Aceder aos valores dos campos nos guards◦ Exemplo

handle(Msg,State) whenState#state.running == true ->

• BIF is_record(Term, RecordType)◦ Permite determinar tipo do record◦ Exemplo

is_person(P) when is_record(P, pessoa) ->true;

is_person(_P) ->false.

Erlang – p. 32

Page 33: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Records

• Records usados em vários módulos devem ser definidosnum ficheiro .hrl

• Módulos acedem à sua definição com

-include(ficheiro.hrl)

• Durante a compilação é adicionada informação sobre osrecords◦ record_info(fields,Record) devolve lista dos

campos presentes em Record◦ record_info(size,Record) devolve tamanho do

record Record

Erlang – p. 33

Page 34: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Compreensao de listas

• Notação sucinta para gerar elementos de uma lista• “Set Compreension” na teoria dos conjuntos de

Zermelo-Frankel• Similares ao setof e findall do Prolog

[Expr || Condicao1, ..., CondicaoN]

• Expr é aplicado a todos os elementos da lista• Condicao é um gerador ou um filtro

◦ Gerador: Padrao <- ListaTermos◦ Filtro: qualquer expressão que retorne true ou false

Erlang – p. 34

Page 35: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Compreensao de listas

[X||X<-Lista, Condicao1, ..., CondicaoN]

• Lê-se X tal que X pertence a Lista e Condição1, ...• Resultado é uma nova lista com os elementos de Lista

que respeitam as condições• Exemplo

L = [X||X<-[1,2,a,3,4,b,5,6], X>3]

L → [a,4,b,5,6]• Podemos adicionar mais filtros

L = [X||X<-[1,2,a,3,4,b,5,6], X>3, is_integer(X)]

L → [4,5,6]

Erlang – p. 35

Page 36: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Compreensao de listas - Regras

• Variáveis usadas num gerador devem ser “novas”• Variáveis instanciadas antes da compreensão de listas

usadas como filtros mantêm o seu valor• Não é possível exportar nenhuma variável

• Exemplo

select(X,L) -> [Y||{X,Y} <- L]

◦ Objectivo: Construir uma lista com os elementos emque X é o primeiro elemento do tuplo

◦ Resultado ao compilar:Warning: Variable ’X’ shadowed in generate

◦ Problema: X no gerador não é o mesmo X que nocabeçalho da função!

Erlang – p. 36

Page 37: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Compreensao de listas - Regras

• Resultado:

L = select(b,[{a,1},{b,2},{c,3},{b,4}])

L → [1,2,3,4]• Gerador deve conter variáveis não instanciadas• Teste deve ser feito no filtro

select(X,L) -> [Y||{X1,Y} <- L,X1==X]

L = select(b,[{a,1},{b,2},{c,3},{b,4}])

L → [2,4]

Erlang – p. 37

Page 38: Erlang -ProgamaçãoSequencial-luis/orgc/slides/erlang/sequencial.pdfIntroduc¸ao˜ Linguagem funcional para sistemas concorrentes e distribuídos Desenvolvida pela Ericsson Necessidade

Compreensao de listas - mais exemplos

• Combinar geradores para obter produto cartesiano de duaslistas

L = [{X,Y}||X <- [1,2,3], Y <- [a,b]]

L → [{1,a},{1,b},{2,a},{2,b},{3,a},{3,c}]• Concatenar duas listas

L = [1,2,3] ++ [4,5,6]

L → [1,2,3,4,5,6]• Subtracção de listas

L = [1,2,3,4,1] -- [1,4]

L → [2,3,1]◦ Retira apenas a primeira ocorrência de cada elemento

da 2a lista

Erlang – p. 38