erlang secuencial - ucmgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · lo que...
TRANSCRIPT
![Page 1: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/1.jpg)
Erlang Secuencial
Francisco Javier Lopez Fraguas
April 13, 2015
![Page 2: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/2.jpg)
Parte I - Erlang secuencial
Joe Armstrong – Programming Erlang
You can’t run until you can walk. Erlang programs are made
up from lots of small sequential programs running at the same
time. Before we can write concurrent code, we need to be able
to write sequential code.
![Page 3: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/3.jpg)
Erlang: primer contacto
Computos ≡ evaluacion de expresiones
En la shell de Erlang (interprete de comandos)
Lanzamos computos ; Evaluamos expresiones
Algunas expresiones pueden ser vistas como comandos, e.g:
> c(programa ): compilar un programa> cd(directorio ): cambiar de directorio> i(): informacion sobre procesos> help(): ayuda de la shell. . .
![Page 4: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/4.jpg)
![Page 5: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/5.jpg)
Algunas cosas sobre la Erlang shell
La shell ejecuta (como un proceso Erlang) un bucle eval-print
No olvidar el punto al final de las expresiones a evaluar!>1+2.
(si no se pone, se queda esperandolo y parece que el sistemase ha colgado)
Toda expresion (incluso las que ejecutan ’comandos’) devuelveun valor, salvo que la evaluacion no termine o genere un error.
Algunas soluciones cuando la shell se queda colgada
Crtl+C (Unix), Crtl+Break (Windows)Mejor, Crtl+G
Puede haber varias shells abiertas en la misma sesion
![Page 6: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/6.jpg)
Terminos y expresiones Erlang
Enteros
>20+30.
50
>33 div 5.
6
>33 rem 5.
3
Precision arbitraria> 111111111 * 2222222222* 333333333.
82304526576131687341563786
Podemos usar otras bases distintas de 10>16#11
17
>16#ba
186
Erlang tiene tipado dinamico> 1+true.
** exception error ...
![Page 7: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/7.jpg)
Terminos y expresiones Erlang
Reales en coma flotante
> 20+30.1.
50.1
> 33/5.
6.6
> math:pow(2,100).
1.2676506002282294e30
> trunc(math:pow(2,100)).
1267650600228229401496703205376
![Page 8: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/8.jpg)
Terminos y expresiones Erlang
Atomos
Representan valores constantes
Formados por: caracteres alfanumericos, , @
lunes rojo ok rojo claro paco@ucm
O bien por caracteres cualesquiera encerrados entre ’.’hola hola’ ’[email protected]’ ’1+2’
Un atomo se evalua a el mismo.
![Page 9: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/9.jpg)
Terminos y expresiones Erlang
Expresiones booleanas
true , false son dos atomos mas, pero con unainterpretacion especial: son valores booleanos y con ellos sepueden formar expresiones booleanas.
Expresiones booleanas:not e e1 and e2 e1 or e2 e1 xor e2donde ei son expresiones que se evaluan a un valor booleano.
> not true.
false
> (5>3) or (1<0).
true
> (5>3) and (1<0).
false
> (5>3) or (1<1/0).
** exception
![Page 10: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/10.jpg)
Expresiones booleanas cortocircuitadas
e1 andalso e2 e1 orelse e2
No siguen el regimen de evaluacion impaciente:se evalua e1 y solo si hace falta se evalua e2.
> (5>3) orelse (1<0).
true
> (5>3) andalso (1<0).
false
> (5>3) orelse (1<1/0).
true
![Page 11: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/11.jpg)
BIFs (Built In Functions) para reconocimiento de tipos
> is integer(3).
true
> is integer(3.0).
false
> is float(3).
false
> is float(3.0).
true
> is number(3).
true
> is number(3.0).
true
> is number(1+1.2).
true
> is atom(ok).
true
> is boolean(1>0).
true
Otras BIFs de ese estilo:is tuple is list is function is pid is record . . .
![Page 12: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/12.jpg)
Variables
Formados por: caracteres alfanumericos, , @, empezandopor una mayuscula o por
X X1 X 1 Hola
Lo que nunca encontraremos: X=X+1
No hay variables asignables a un valor que va cambiando+ no hay estado mutable
Las variables aparecen para representar parametros formalesen las definiciones de funciones.
Tambien aparecen en expresiones de ajuste de patrones(pattern matching), en las que una variable puede quedarligada a un valor que ya no puede cambiar.+ variables de asignacion unica .
![Page 13: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/13.jpg)
Expresiones de ajuste de patrones: e1 = e2
No son un test de igualdad (para eso tenemos e1 =:= e2 oe1 =:= e2)
El valor de e1 = e2 es:
El valor de e2 si e1 y e2 se evaluan al mismo valorEl valor de e2 si e1 es una variable no ligada X, que quedaentonces ligada al valor de e2
Este la situacion interesanteMas adelante veremos mas posibilidades para ligaduras devariables por ajuste de patrones
Un error en otros casos (valores no coincidentes, variables noligadas en e2, . . . )
![Page 14: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/14.jpg)
Expresiones de ajuste de patrones: e1 = e2
> 1+1=2+0.
2
> +1=2+2.
error: no match
> X=2+2.
2
> X.
4
> Y.
error: Y unbound
> Y=1+X.
5
> Y.
5
> Y=X.
error: no match
> Y=Y+1.
error: no match
> f(Y).
ok
> X=Y.
error: Y unbound
> Y=X.
4
![Page 15: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/15.jpg)
Expresiones secuencia: e1, e2, . . . , en
Para evaluarla se evaluan (en ese orden) e1, e2, . . . ,en, pero elvalor devuelto es el valor de en.
Tiene sentido usarlas cuando la evaluacion de e1,. . . producealgun efecto lateral.
> 1,2,3.
3.
> R=3.5,math:pi()*R*R.
38.484510006.
> R=3.5,math:pi()*R*R.
38.484510006.
> io:format("abc\n"),timer:sleep(1000),X=2*3,X+4.abc
10
![Page 16: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/16.jpg)
Tuplas
Agrupacion de datos de tamano fijo
Sintaxis: {} Tupla vacıa{e1,e2,...,en} Tupla de n elementos
{1,3} {paco,56} dos tuplas de tamano 2
{persona, {nombre,’Paco’},{apellidos,{’Lopez’,’Fraguas’}},{edad,56}
}Una tupla de tamano 4 formada por otras tuplas
![Page 17: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/17.jpg)
Ajuste de patrones con tuplas
> P = {punto,3,4}.{punto,3,4}
> {punto,X,Y} = P.
{punto,3,4}
> D = math:sqrt(X*X+Y*Y).
5.0
> {Tag,A,A} = {punto,3,3} , {Tag,A}.{punto,3}
> { ,B, } = P , B.
3
> {1,2} =:= {2,1}.false
![Page 18: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/18.jpg)
Algunas BIFs sobre tuplas
> tuple size({punto,3,4}).3
> tuple size({}).0
> element(2,{punto,3,4}).3
> setelement(2,{punto,3,4},10).{punto,10,4}
Muchas BIFs devuelven tuplas como resultado
> time().
{19,22,40}> date().
{2014,10,6}
![Page 19: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/19.jpg)
Listas
Secuencia de datos de tamano arbitrario
Sintaxis: [] Lista vacıa[e1,e2,...,en] Lista de n elementos• e1 es la cabeza de la lista• [e2,...,en] es el resto de la lista
> [1+2,true or false,{ok,3}][3,true,{ok,3}]
+ los elementos pueden ser de tipos distintos
![Page 20: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/20.jpg)
Algunas BIFs (y funciones de librerıas) sobre listas
> hd([1,a,3]).
1
> tl([1,a,3]).
[a,3]
> tl([3]).
[]
> hd([]).
error: bad argument
> length([1,2,3]).
3
> ([1,2,3]++[4,5]).
[1,2,3,4,5]
> ([1,2,3,1]--[3,1,4]).
[2,1]
> lists:reverse([a,b,c])
[c,b,a]
> lists:nth(2,[a,b,c])
[b]
> lists:append([[1,2,3],[4,5],[a,b]]).
[1,2,3,4,5,a,b]
![Page 21: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/21.jpg)
La constructora de listas [ | ]
[h|t] ; lista de cabeza h y resto t
[a,b,c] es lo mismo que [a|[b|[c|[]]]]
[a,b,c] ≡ [a|[b|[c|[]]]] ≡ [a|[b,c]] ≡ [a,b|[c]] ≡[a,b|[c|[]]] ≡ [a,b,c|[]]
La notacion [h|t] sera esencial para expresar el ajuste depatrones al definir funciones sobre listas.
![Page 22: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/22.jpg)
Ajuste de patrones con listas
> X = [1,2,3].
[1,2,3]
> Y = [a|X].
[a,1,2,3]
> [A,B,2,C] = Y,{A,B+C}.{a,4}
> [U|V] = Y , {U,V}.{a,[1,2,3]}
![Page 23: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/23.jpg)
Strings
No hay strings propiamente dichos, son listas de enteros(listas de codigos Unicode)
Pero tenemos un azucar sintactico: ”caracteres”> "Hola".
"Hola"
> "Hola"++",amigo".
"Hola,amigo"
> hd("Hola").
72
> tl("Hola").
"ola"
> [1|"Hola"].
[1,72,111,108,97]
> [72,111,108,97].
"Hola"
> [A,B|C] = "Hola",{A,B,C}.{72,111,"la"}
![Page 24: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/24.jpg)
Convesiones entre tipos
> atom to list(hello).
"hello"
> list to atom("hello").
hello
> integer to list(77).
"77"
> list to integer("77").
77
> tuple to list({a,b,c}).[a,b,c]
> list to tuple([a,b,c]).
{a,b,c}> ...
![Page 25: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/25.jpg)
Modulos y funciones
Modulos
Unidades basicas de codigo
Ficheros con extension .erl
Al compilarlos generan .beam
Constan de directivas y definiciones de funciones
Se pueden compilar desde el SO o desde la shell.
![Page 26: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/26.jpg)
factorial.erl
-module(factorial).
-export([fac/1]). % /1 indica aridad 1
fac(0) -> 1; % Primera clausula de fac
fac(N) -> N * fac(N-1). % Segunda
> c(factorial).
ok,factorial
> fac(7).
** exception error: undefined shell command fac/1
> factorial:fac(7).
5040
![Page 27: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/27.jpg)
El orden de las clausulas es importante
-module(factorial).
-export([fac/1]).
fac(N) -> N * fac(N-1); % mal asunto ...
fac(0) -> 1.
factorial.erl con recursion de cola (last call optimization)
-module(factorial).
-export([fac/1]).
fac(0) -> 1;
fac(N) -> N * fac(N-1). % No hay LCO
facc(0,Acc) -> Acc;
facc(N,Acc) -> facc(N-1,N*Acc). % Hay LCO
![Page 28: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/28.jpg)
Programas con tuplas: paso de parametros por ajuste de patrones
-module(medidas).
-export([area/1,perimetro/1]).
area({cuadrado,L}) -> L*L;
area({rectangulo,X,Y}) -> X*Y;
area({circulo,R}) -> math:pi()*R*R.
perimetro({cuadrado,L}) -> 4*L;
perimetro({rectangulo,X,Y}) -> 2*X+2*Y;
perimetro({circulo,R}) -> 2*math:pi()*R.
% Aqui el orden de las clausulas no importa
![Page 29: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/29.jpg)
Programas con listas: ajuste de patrones, recursion
-module(listas).
-compile(export_all).
% length(Xs)= longitud de la lista Xs
length([]) -> 0;
length([X|Xs]) -> 1+length(Xs).
% O bien, con LCO
length1(Xs) -> length1(Xs,0).
length1([],N) -> N;
length1([X|Xs],N) -> length1(Xs,N+1).
![Page 30: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/30.jpg)
% append(Xs,Ys) = concatenacion de Xs e Ys
append([],Ys) -> Ys;
append([X|Xs],Ys) -> [X|append(Xs,Ys)].
% hd(Xs) = cabeza de Xs ; tl(Xs) = resto de Xs
hd([X|_]) -> X.
tl([_|Xs]) -> Xs.
% nth(N,Xs) = elemento N-simo de Xs, numerando desde 1
nth(1,[X|_]) -> X;
nth(N,[_|Xs]) -> nth(N-1,Xs).
length/1,tl/1,append/2,nth/2 recorren la lista (costelineal)
length/1,hd/1,tl/1 son BIF, append/2,nth/2 estan enlists
append(X,Y) se escribe mejor como X++Y
![Page 31: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/31.jpg)
Patrones con variables repetidas: expresan igualdad
% member(X,Xs) = true si X es elemento de Xs; false e.o.c.
member(X,[]) -> false;
member(X,[X|_]) -> true;
member(X,[_|Ys]) -> member(X,Ys).
% seq(N,M) = [N,N+1,...,M]
seq(N,N) -> [N];
seq(N,M) -> [N|seq(N+1,M)]
member/2 es BIF, seq/2 en lists
![Page 32: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/32.jpg)
¿Cual es la complejidad de esta funcion?
% revese(Xs) = la inversa de la lista Xs
reverse([]) -> []
reverse([X|Xs]) -> reverse(Xs)++[X]
![Page 33: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/33.jpg)
Mejor sera esto. . .
reverse(Xs) -> reverse(Xs,[]).
reverse([],RevAcc) -> RevAcc;
reverse([X|Xs],RevAcc) -> reverse(Xs,[X|RevAcc]).
La funcion lists:reverse/1 esta eficientementeimplementada
Recomendaciones generales para programas que computanlistas como resultado:
Muy preferible computar [X|e] en lugar de e++[X]
Si por hacerlo ası sale el resultado al reves, usarlists:reverse/1
![Page 34: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/34.jpg)
Otras formas de poner condiciones a los argumentos: guardas when
Recordemosfac(0) -> 1;
fac(N) -> N * fac(N-1).
Podemos poner una condicion en la segunda clausulafact(0) -> 1;
fact(N) when N > 0 -> N*fact(N-1).
Aquı sı podemos cambiar el orden de las clausulasfact(N) when N > 0 -> N*fact(N-1).
fact(0) -> 1;
Tambien podemos poner el caso 0 con una guardafact(N) when N > 0 -> N*fact(N-1);
fact(N) when N==0 -> 1.
![Page 35: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/35.jpg)
Otras formas de poner condiciones: expresiones if
facif(N) ->
if N == 0 -> 1;
true -> N*facif(N-1)
end.
Igual preferimos esto otrofacif1(N) ->
if N == 0 -> 1;
N > 0 -> N*facif1(N-1)
end.
O incluso estofacif1(N) ->
if N == 0 -> 1;
N > 0 -> N*facif1(N-1);
true -> no_definido
end.
![Page 36: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/36.jpg)
Otros ejemplos: member/2
% member(X,Xs) = true si X es elemento de Xs; false e.o.c.
Con patronesmember(X,[]) -> false;
member(X,[X|_]) -> true;
member(X,[_|Ys]) -> member(X,Ys).
Con (alguna) guardamember(X,[]) -> false;
member(X,[Y|_]) when X=:=Y -> true;
member(X,[_|Ys]) -> member(X,Ys).
Con ifmember(X,[]) -> false;
member(X,[Y|Ys]) ->
if X=:=Y -> true;
true -> member(X,Ys)
end.
![Page 37: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/37.jpg)
Otras formas de poner condiciones: expresiones case
member(X,[]) -> false;
member(X,[Y|Ys]) ->
case X=:=Y of
true -> true;
false -> member(X,Ys)
end.
Tambien valdrıamember(X,[]) -> false;
member(X,[Y|Ys]) ->
case X=:=Y of
true -> true;
_ -> member(X,Ys)
end.
![Page 38: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/38.jpg)
Expresiones secuencia en el cuerpo de una clasula
sols(A,B,C) = lista de soluciones de Ax2 +Bx+ C = 0sols(A,B,C) ->
D= B*B-4*A*C, % calculamos D como valor intermedio
if D < 0 -> [];
D == 0 -> [-B/2*A];
D > 0 -> [(-B + math:sqrt(D))/(2*A),
(-B - math:sqrt(D))/(2*A)]
end.
![Page 39: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/39.jpg)
Formato general de una definicion de funcion f/n
f(Pat11,...,Pat1n) [when Guardas1] -> expr1;
. . . . . . . . .f(Patk1,...,Patkn) [when Guardask] -> exprk.
Donde
expri puede ser una expresion secuencia
Guardas ::= Guarda1;...;Guardam ; es como orelse
Guarda ::= GExpr1,...,GExprl , es como andalso
GExpr es una expresion booleana formada por algunas BIFs, como==,>,...,is atom,is list,...,pero no funciones de usuario.
![Page 40: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/40.jpg)
Y esto se ejecuta ası: para evaluar f(e1,...,en). . .
Se evaluan e1,...,en, para obtener t1,...,tnAhora, para evaluar f(t1,...,tn)
Se prueban las cabezas de las causulas en su orden hastaencontrar una aplicable a f(t1,...,tn). Si esta es la i, seevalua expri.La cabeza f(Pati1,...,Patin) when Guardasi es aplicablea f(t1,...,tn) si:
Los argumentos t1,...,tn ajustan con los patronesPati1,...,PatinLa guarda Guardasi se evalua a true (recuerda, interpretando; como orelse y , como andalso).
Si ninguna clausula resulta aplicable, se produce un error.
![Page 41: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/41.jpg)
Funciones de orden superior (HO functions)
Un lema famoso de la programacion funcional
Las funciones son ciudadanos de primera clase
Una funcion puede ser argumento o resultado de otra
Funciones de orden superior (HO functions)
Funciones con algun argumento (o el resultado) de tipofuncional.
Favorecen la abstraccion, concision y reutilizacion de codigo.
Funciones de primer orden: las ”normales”, que no son de OS
![Page 42: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/42.jpg)
Funciones de orden superior
Un par de funciones de primer orden...
% inc_list(Xs): suma uno a todos los elementos de Xs
inc(X) -> 1+X.
inc_list([]) -> [];
inc_list([X|Xs]) -> [inc(X)|inc_list(Xs)].
% cabezas(Xss): cabezas de los elementos de Xss
cabezas([]) -> [];
cabezas([X|Xs]) -> [hd(X)|cabezas(Xs)].
Se repite la misma estructura:aplicar una funcion f a todos los elementos de la lista
![Page 43: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/43.jpg)
Funciones de orden superior
Abstraccion de OS: map
% map(F,Xs) = resultado de aplicar F a cada elemento de Xs
% map(F,[X1,...,Xn]) = [F(X1),...,F(Xn)]
-module(ho).
map(F,[]) -> [];
map(F,[X|Xs]) -> [F(X)|map(F,Xs)].
> ho:map(fun erlang:hd/1,[[1,2,3],[2],[7,6,4]]).
[1,2,7]
> ho:map(fun ho:inc/1,[1,3,5])
[2,4,6]
![Page 44: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/44.jpg)
Funciones de orden superior
Recordemos: un par de funciones de primer orden...
inc(X) -> 1+X.
inc_list([]) -> [];
inc_list([X|Xs]) -> [inc(X)|inc_list(Xs)].
cabezas([]) -> [];
cabezas([X|Xs]) -> [hd(X)|cabezas(Xs)].
Pero es mejor usando map/2
inc_list(Xs) -> map(fun ho:inc/1,Xs).
cabezas(Xss) -> map(fun erlang:hd/1,Xss).
![Page 45: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/45.jpg)
Funciones de orden superior
Funciones anonimas (λ-abstracciones)
inc(X) -> 1+X.
> inc(3).
4
' > Inc=fun(X) -> 1+X end.
> Inc(3).
4
fun(X) -> 1+X end. ; funcion anonima
Podemos usarlas en map/2
inc_list(Xs) -> map(fun(X) -> 1+X end,Xs).
% hace innecesaria inc/1
cabezas(Xss) -> map(fun(X) -> hd(X) end,Xss).
% alternativa a fun erlang:hd/1
![Page 46: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/46.jpg)
Otros ejemplos de funciones anonimas
fun(X,Y) -> math:sqrt(X*X+Y*Y) end
fun ({milla,X}) -> {km,X*1.609344};({km,X}) -> {milla,X/1.609344}
end
fun(Xs) -> (fun(X) -> lists:member(X,Xs) end) end
![Page 47: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/47.jpg)
Otros ejemplos de funciones de HO: ¿que hacen?
filter(F,[]) -> [];
filter(F,[X|Xs]) ->
case F(X) of
true -> [X|filter(F,Xs)];
false -> filter(F,Xs)
end.
for(I,J,F) when I<=J -> [F(I)|for(I+1,J,F)];
for(I,J,F) when I>J -> [].
![Page 48: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/48.jpg)
Listas intensionales (List comprehensions)
Notacion inspirada en las Matematicas: conjuntos por comprension
{x2 | x ∈ {1, . . . , 5}} {1, 4, 9, 16, 25}
{x+ 1 | x ∈ {1, . . . , 10}, x2 acaba en 9} {4, 8}
En programacion funcional: map, filter
map(fun(X) -> X*X end,[1,2,3,4,5])
map(fun(X) -> X+1,filter(fun(X)->X*X rem 10 =:= 9 end,seq(1,10)))
O tambien podemos usar notacion de listas intensionales
[X*X || X <- [1,2,3,4,5]]
[X+1 || X <- seq(1,10), X*X rem 10 =:= 9]
![Page 49: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/49.jpg)
Mas ejemplos
[Y || Y <- seq(1,24), 24 rem Y =:= 0] [1,2,3,4,6,8,12,24]
divisores(X) -> [Y || Y <- seq(1,X), X rem Y =:= 0]
es primo(X) -> [Y || Y <- seq(2,X-1), X rem Y =:= 0] =:= []
[{X,Y,X and Y} || X <- [true,false], Y <- [true,false]]
[{Y,X} || X <- [true,false], Y <- [true,false] ,X and Y =:= X or Y]
![Page 50: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/50.jpg)
Morfologıa de las listas intensionales
[ X+1 || X <- seq(1,10) , X*X rem 10 =:= 9]
expresion principal
[X+1 || X <- seq(1,10) , X*X rem 10 =:= 9]
generador
[X+1 || X <- seq(1,10) , X*X rem 10 =:= 9 ] filtro
En general, una lista intensional es: [e || c1,...,cn]
e es una expresionc1 es un generadorCada ci con i > 1 es un generador o un filtroUn generador es de la forma p <- l
l es una expresion cuyo valor es una listap es un patron
Un filtro es una expresion booleana
![Page 51: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/51.jpg)
Generadores
Puede haber varios generadores seguidos[{X,Y} || X <- [1,2] , Y <- [a,b,c]]
[{1,a},{1,b},{1,c},{2,a},{2,b},{2,c}]El orden de los generadores influye[{X,Y} || Y <- [a,b,c] , X <- [1,2]]
[{1,a},{2,a},{1,b},{2,b},{1,c},{2,c}]Generadores multiples actuan al modo de bucles anidados
Un generador p <-l con p no variable tiene un efecto filtropor el ajuste de patrones[X+Y || {{X,Y},a} <- [{{2,1},a},{{1,3},b},{{2,4},a}]][3,6]
Filtros
Puede haber varios filtros seguidosCada filtro actua sobre el resultado de los generadores y filtrosanteriores
![Page 52: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/52.jpg)
Un ejemplo: quicksort
qsort([]) -> [];
qsort([X|Xs]) -> qsort([U || U <- Xs, U < X])
++ [X] ++
qsort([U || U <- Xs, U > X]).
![Page 53: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/53.jpg)
Ternas pitagoricas: (x, y, z) tales que x2 + y2 = z2
-- ternasP(N) = ternas pitagoricas con numeros =< N
ternasP(N)= [{X,Y,Z}|| X <- lists:seq(1,N),
Y <- lists:seq(1,N),
Z <- lists:seq(1,N),
Z*Z == X*X+Y*Y]
% Mejor, para evitar repeticiones
ternasP’(N)= [{X,Y,Z}|| Z <- lists:seq(1,N),
X <- lists:seq(1,Z-1),
Y <- lists:seq(1,X-1),
Z*Z == X*X+Y*Y]
![Page 54: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/54.jpg)
Map, filter, append y listas intensionales
map(F,Xs) = [F(X) || X <- Xs]
filter(P,Xs) = [X || X <- Xs , P(X)]
append(Xss) = [X || Xs <- Xss , X <- Xs]
Recıprocamente toda lista intensional puede expresarse enterminos de map, filter y append.
+ Las listas intensionales son azucar sintactico
![Page 55: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/55.jpg)
Manejo de errores y excepciones
Dos posibilidades en la evaluacion de una expresion
La evaluacion tiene exito y devuelve un valor > 1+2.
3
La evaluacion produce un error > 1+true.
exception error
Se genera o eleva una excepcion (raise an exception)Las excepciones rompen el flujo normal de evaluacionLas excepciones las puede generar:
el sistemael programador
![Page 56: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/56.jpg)
Tipos de errores producidos por el sistema
Function Clause Errors
Case Clause Errors
If Clause Errors
Bad Match Errors
Bad Argument Errors
Undefined Function Errors
Bad Arithmetic Errors
Bad Function Errors
Bad Arity Errors
System Limit Errors
![Page 57: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/57.jpg)
Captura de excepciones
Expresiones try. . . catch: version simple
try e
catch
error:PatronError -> e’
end
> try 1/0 catch error: -> ’Division por cero’.
’Division por cero’
> try 1/2 catch error: -> ’Division por cero’.
0.5
> try 1/0 catch error: -> 0.
0
> try 1/2 catch error:E -> E.
badarith
![Page 58: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/58.jpg)
Captura de excepciones
Expresiones try. . . catch: forma general
try e of
Patron1 [when Guarda1 ] -> e1;
Patron2 [when Guarda2 ] -> e2;
...
catch
exceptionType1 :PatronError1 -> e1’
exceptionType2 :PatronError2 -> e2’
...
end
![Page 59: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/59.jpg)
Tipos de excepciones
error: es el mas habitual.
Las produce el sistema como run-time errorsSe pueden producir mediante la BIF error(Why )
exit: mas ligada a procesos
Se pueden producir mediante la BIF exit(Why )
throw:
Se pueden producir mediante la BIF throw(Why )
![Page 60: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/60.jpg)
Records: tuplas con nombre para las componentes
Personas, representadas como tupas
{Nombre,Apellido1,Apellido2,Edad,Tipo Documento, Num Documento,
Ciudad, Provincia }
{’Francisco’,’Lopez’,’Fraguas’,56,dni, 51334962,
Madrid, Madrid}
![Page 61: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/61.jpg)
Records: tuplas con nombre para las componentes
Ejemplo: personas, representadas como records
. Definicion de la estructura de record para representar personas
> rd(persona, { nombre,ap1,ap2,
edad,tipo doc = dni,num doc,
ciudad = ’Madrid’,provincia=’Madrid’}).
. Creacion de un record persona concreto
> Yo = #persona{ nombre=’Francisco’,ap1=’Lopez’,
ciudad=’Getafe’,edad=56,
num doc=51344962}.
![Page 62: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/62.jpg)
rd/2 se usa en la shell para definir records
En programas hay que usar una directiva-record(Name,{...})Se suelen recolectar definiciones de records en ficheros *.hrl
Los ficheros *.hrl se cargan en otros mediante-include(file ).
Los ficheros *.hrl se cargan la shell mediante> rr(file ).
![Page 63: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/63.jpg)
Acceso a componentes de records
Acceso a una componente concreta:> Yo#persona.edad.
56
O mediante pattern matching de records:> #persona{edad=E,ciudad=C} = Yo.
#persona{...}
> E.
56
> C.
’Getafe’
Creacion de un record por actualizacion de otro
> Yo1 = Yo#persona{ap2=’Fraguas’}.#persona{...}
> Yo#persona.ap2.
undefined
> Yo1#persona.ap2.
’Fraguas’
> Yo1#persona.edad.
56
![Page 64: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/64.jpg)
Los records se muestran con apariencia de records
4> Yo.
#persona{nombre=’Francisco’,ap1=’Lopez’,ap2=undefined,edad=56,tipo doc=dni,
num doc=51334962,ciudad=’Getafe’,provincia=’Madrid}
Pero es azucar sintactico: son realmente tuplas
4> io:write(Yo).
{persona,’Francisco’,’Lopez’,undefined,56,dni,51334962,’Getafe’,’Madrid}ok
Tuplas: manejo de componentes por posicion
Records: manejo de componentes por nombre
Todo el procesado de los records es en tiempo de compilacion
![Page 65: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/65.jpg)
misrecords.hrl
-record(persona,{nombre,ap1,ap2,edad,tipo_doc=dni,num_doc,
ciudad=’Madrid’,provincia=’Madrid’}).
personas.erl
-module(personas).
-include("misrecords.hrl").
nombre_largo(Per) ->
{Per#persona.nombre,
Per#persona.ap1,
Per#persona.ap2}.
% Mejor con ajuste de patrones de record
nombre_largo1(#persona{nombre=N,ap1=Ap1,ap2=Ap2}) ->
{N,Ap1,Ap2}.
% Peor, usando tuplas
nombre_largo2(Per) ->
{element(2,Per),element(3,Per),element(4,Per)}.
![Page 66: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/66.jpg)
Macros: expansiones en tiempo de compilacion
-define(Constante,Valor ).
-define(Func(V1,...,Vn) -> Valor ).
Ejemplos
-define(ESCALA,1000).
-define(Doble(X) -> 2*X).
Una macro MACRO se usa como ?MACRO
-module(mapas).
-define(ESCALA,1000).
escala(X) -> X/?ESCALA.
Las macros se suelen recolectar en ficheros *.hrl
Existen macros condicionales: ver libro o manual
Existen macros predefinidas: ?MODULE,?FILE,?LINE
![Page 67: Erlang Secuencial - UCMgpd.sip.ucm.es/jaime/pda/erlang_secuencial.pdf · 2015-04-14 · Lo que nunca encontraremos: X=X+1 No hay variables asignables a un valor que va cambiando +](https://reader034.vdocuments.us/reader034/viewer/2022042205/5ea7232e0120281d803bc20d/html5/thumbnails/67.jpg)