domingo, 19 de diciembre de 2010

Erlang


Ya hemos hablado de erlangs en otros post, vamos a hacer un repaso y luego desarrollar ejemplos.

Erlang es un lenguaje de programación concurrente y un sistema de ejecución que incluye una máquina virtual y bibliotecas.

El subconjunto de programación secuencial de Erlang es un lenguaje funcional, con evaluación estricta, asignación única, y tipado dinámico. Fue diseñado en la compañía Ericsson para realizar aplicaciones distribuidas, tolerantes a fallos, soft-real-time y de funcionamiento ininterrumpido. Proporciona el cambio en caliente de código de forma que éste se puede cambiar sin parar el sistema. Originalmente, Erlang era un lenguaje propietario de Ericsson, pero fue cedido como software de código abierto en 1998. La implementación de Ericsson es, principalmente interpretada pero también incluye un compilador HiPE (sólo soportado en algunas plataformas).

La creación y gestión de procesos es trivial en Erlang, mientras que, en muchos lenguajes, los hilos se consideran un apartado complicado y propenso a errores. En Erlang toda concurrencia es explícita.

Bueno vamos a bajarnos el runtime de http://www.erlang.org/download.html esto para windows, si estan en linux es más fácil instalarlo por ejemplo en debian es así “apt-get install erlang”, y listo!

Se puede escribir codigo en un archivo .erl y luego compilarlo opteniendo el .beam (ejecutable) nosotros vamos a usar la consola.

Escribimos en la consola erl o werl(para windows)

erl
Erlang (BEAM) emulator version 5.4.13 [source]
Eshell V5.4.13 (abort with ^G)
1>

1> % Este es un comentario
2> 2 + 2.
4
3> 2 + 2,0.
4,0

Veamos las listas:
4> [1, 2, 3,4]
[1, 2, 3,4]

No se puede hacer operaciones con diferentes tipos por ejemplo la suma:

5> 4 + "string".
** exception error: bad argument in an arithmetic expression
in operator +/2
called as 4 + "string"

Las variables deben comenzar con mayuscula:

7> Var = 1.
1
8> Var = 2.
=ERROR REPORT==== 8-Jan-2010::11:47:46 ===
Error in process <0.39.0> with exit value: {{badmatch,2},[{erl_eval,expr,3}]}
** exited: {{badmatch,2},[{erl_eval,expr,3}]} **
8> Var.
1
Como se puede ver solo se puede asignar un valor a una variable una vez; esto es asi porque Erlang es un lenguaje funcional.

Un símbolo es una palabra en minuscula (en la mayoria de los lenguajes que lo implementa) que sirve para representar algo. En Erlang el símbolo se denomina atoms.

9> red.
red
10> Pill = blue.
blue
11> Pill.
blue


Las listas son un conjunto de elementos que pueden tener diferente tipo y longitud:

13> [1, 2, 3].
[1,2,3]
14> [1, 2, "three"].
[1,2,"three"]
15> List = [1, 2, 3].
[1,2,3]

Tuples es una lista fija y heterogénea:

18> {one, two, three}.
{one,two,three}
19> Origin = {0, 0}.
{0,0}

Estas estructuras pueden convinarse:

20> {name, "Spaceman Spiff"}.
{name,"Spaceman Spiff"}
21> {comic_strip, {name, "Calvin and Hobbes"}, {character, "Spaceman Spiff"}}.
{comic_strip,{name,"Calvin and Hobbes"},
{character,"Spaceman Spiff"}}

24> Person = {person, {name, "Agent Smith"}, {profession, "Killing programs"}}.
{person,{name,"Agent Smith"},
{profession,"Killing programs"}}

Para obtener valores de la persona podemos hacer lo siguiente:

25> {person, {name, Name}, {profession, Profession}} = Person.
{person,{name,"Agent Smith"},
{profession,"Killing programs"}}
26> Name.
"Agent Smith"
27> Profession.
"Killing programs"

Se entiende? Obtenemos los valores en Name y Profession por medio de patrones de coincidencia.
Y con patrones de coincidencia se puede hacer más cosas:

28> [Head | Tail] = [1, 2, 3].
[1,2,3]
29> Head.
1
30> Tail.
[2,3]
32> [One, Two|Rest] = [1, 2, 3].
[1,2,3]
33> One.
1
34> Two.
2
35> Rest.
[3]

Si no hay suficientes elementos en la lista el patrón no funciona:

6> [X|Rest] = [].
** exception error: no match of right hand side value []

Erlang es dinámicamente tipado, Erlang puede enlazar tipos en runtime. Vamos a hacer una función para esto vamos a hacer un modulo. Yo uso debian pero para windows debe ser parecido.
Salimos del runtime Ctrl + G.
Escribimos:
nano basic.erl
En nano escribimos el siguiente código:

-module(basic).
-export([mirror/1]).
mirror(Anything) -> Anything.

Salimos y guardamos. Luego escribimos erl en la consola.
Y por ultimo compilamos:

1> c(basic).
{ok,basic}

La función mirror solo devuelve lo que pasamos como parámetro. Pueden ver que el operador -> simplifica el return.

5> mirror(smiling_mug).
** exception error: undefined shell command mirror/1
6> basic:mirror(smiling_mug).
smiling_mug
6> basic:mirror(1).
1
Vemos que hay que ingresar el nombre del modulo.

-module(matching_function).
-export([number/1]).
number(one) -> 1;
number(two) -> 2;
number(three) -> 3.

En la siguiente función se puede ver la influencia de Prolog en Erlang.
Por ultimo implementemos factorial y figonacci :

-module(yet_again).
-export([another_factorial/1]).
-export([another_fib/1]).
another_factorial(0) -> 1;
another_factorial(N) -> N * another_factorial(N-1).
another_fib(0) -> 1;
another_fib(1) -> 1;
another_fib(N) -> another_fib(N-1) + another_fib(N-2).

Hasta aca vimos muy por arriba Erlang en proximos post vamos a seguir hablando.

Dejo links: