martes, 5 de octubre de 2010

Scala Solutions


El 4 de octubre Martin Odersky, creador del lenguaje Scala, anunció la fundación de Scala Solutions. "Hemos fundado Scala Solutions para proveer las herramientas y servicios avanzados que los desarrolladores de Scala necesitan para hacer realidad la creación de aplicaciones de misión crítica, un desarrollo rápido y un mantenimiento fácil".

Compañías como Twitter, LinkedIn, Foursquare, The Guardian, Xerox, Sony, Siemens, Novell y EDF utilizan ya Scala para implementar partes críticas de su negocio. Scala Solutions proveerá herramientas y servicios que facilitarán el uso de Scala para crear y mantener aplicaciones de negocio.

Este es un paso fundamental para la expansión y la adopción del lenguaje de forma masiva. Sus capacidades están fuera de toda duda, sólo quedaba tener una corporación detrás que diera las máximas garantías para que las empresas se embarquen en desarrollar utilizando toda su potencia.

Scala Solutions







El 4 de octubre Martin Odersky, creador del lenguaje Scala, anunció la fundación de Scala Solutions. "Hemos fundado Scala Solutions para proveer las herramientas y servicios avanzados que los desarrolladores de Scala necesitan para hacer realidad la creación de aplicaciones de misión crítica, un desarrollo rápido y un mantenimiento fácil".

Compañías como Twitter, LinkedIn, Foursquare, The Guardian, Xerox, Sony, Siemens, Novell y EDF utilizan ya Scala para implementar partes críticas de su negocio. Scala Solutions proveerá herramientas y servicios que facilitarán el uso de Scala para crear y mantener aplicaciones de negocio.

Este es un paso fundamental para la expansión y la adopción del lenguaje de forma masiva. Sus capacidades están fuera de toda duda, sólo quedaba tener una corporación detrás que diera las máximas garantías para que las empresas se embarquen en desarrollar utilizando toda su potencia.

jueves, 23 de septiembre de 2010

Sobre la muerte de Java


Mucho se ha elucubrado sobre la muerte de Java, sobre los nuevos lenguajes que superan con creces sus características, la compra de Sun...

Java, hoy por hoy, es el líder indiscutible en el desarrollo de aplicaciones empresariales, esto es innegable, y lo seguirá siendo por mucho tiempo. Cuenta con el mayor pool de desarrolladores, el mayor ecosistema que ha tenido ningún lenguaje jamás y la empresa está de su lado, muchos productos han evolucionado hacia sus tecnologías.

Si analizamos por ejemplo el lenguaje C que lleva con nosotros desde 1972 y sus estadísticas de uso según Tiobe, está en segundo lugar con un 17,147%, poco detrás de Java. Su evolución, C++ se encuentra en tercer lugar con un 9,81%.

Java podrá gustar más o menos a la gente, pero el éxito de un lenguaje no depende sólo de sus características, si no estaríamos programando todos en LISP desde hace mucho tiempo. Depende en su mayor medida de las relaciones entre empresas, software opensource, productos que lo utilicen... El lenguaje que sustituya a Java probablemente sea una nueva versión del mismo Java ampliada soportando y simplificando lo que actualmente Java es. Es lo que hizo Java en su momento:

1. Respetar todo lo posible la sintaxis del lenguaje precedente C/C++.
2. Simplificar la gestión de memoria, concurrencia y modelo de objetos.
3. Facilitar el desarrollo multiplataforma.

El siguiente killer language tendrá que soportar los problemas actuales:

1. Simplificar el desarrollo distribuido desde el propio lenguaje
2. Simplificar y potenciar la concurrencia.
3. Respetar todo lo anterior.

Se me viene a la cabeza ahora mismo Erlang como mayor valuarte, pero debería respetar la sintaxis y la orientación a objetos del mismo modo que lo hizo Java en su momento, el cambio drástico hacia la programación funcional es duro de asumir por el grueso de desarrolladores.

Quizá sea el propio Java el que evolucione en este sentido... el futuro nos dirá.

viernes, 13 de agosto de 2010

Oracle demanda a Google por Java en Android

Oracle ha presentado una demanda contra Google por violación de derechos de propiedad intelectual de Java en el desarrollo de la plataforma Android.

La mayor parte de los post que versan sobre este tema indican que se ha perdido el espíritu de Sun por el que Java triunfó. Pienso que ese mismo espíritu es el que le llevó a Sun a no saber rentabilizarlo y a acabar en manos de Oracle. Si por algo se caracteriza Oracle es por saber rentabilizar sus inversiones, es posible que si Java hubiera nacido en el seno de Oracle no hubiese llegado a nada, pero ahora que es la plataforma más extendida de desarrollo de aplicaciones empresariales, no se van a dejar escapar el monetizar lo que Sun no supo como manejar.

Por otro lado, uno de los mayores impulsores de Java siempre ha sido Google (GWT, Android...) ¿Apostará Google por otra plataforma que le de menos quebraderos de cabeza? Otro lenguaje que siempre ha tenido presente Google ha sido Python, muy maduro, omnipresente en Linux y con un ecosistema igual o mayor que el de Java.


miércoles, 11 de agosto de 2010

C para todos por el MIT opencourseware

Muy buen curso de C para Linux en el que se cubre desde el comienzo hasta los aspectos prácticos de programación de red, concurrente y entrada/salida asíncrona. Proporcionado por MIT opencourseware.


viernes, 28 de mayo de 2010

Competitividad en el sector TIC de servicios informáticos

A continuación voy a exponer 3 puntos que permitirían ofrecer mejores precios para que los clientes vieran viables las inversiones en nuevos servicios y que reducirían los costes significativamente, aumentando el beneficio en el sector de los servicios informáticos:

1. Opensource: Esta es la evidente y más clara, presentar una oferta en la que el cliente debe hacer un desembolso en licenciamiento en estos tiempos tira para atrás cualquier tipo de nueva implantación. De muestra, un botón, aquí podéis comprobar las tarifas que tiene Oracle.

2. Commodity Hardware: Con el desembolso que el cliente realizará en servidores de medio rango y mainframes se pueden desplegar infraestructuras basadas en commodity hardware utilizando las técnicas de computación distribuida que permitirán una mayor escalabilidad, mejor rendimiento y un descenso significativo en la inversión a realizar. Esto sólo tiene sentido si se utilizan soluciones opensource, porque el coste de licenciamiento sería desproporcionado.

3. Remote work: La oficina debe ser un centro de reunión para tratar temas concretos, con las infraestructuras de telecomunicaciones domésticas existentes actualmente los empleados pueden ejercer su trabajo desde su casa probablemente en condiciones de mayor productividad y aprovechamiento del tiempo que en la propia oficina. Este punto quizá sea el más difícil de implantar dada la cultura empresarial y laboral que existe, en la que se mide a la gente por cuando entra o cuando sale, en lugar de fijar objetivos muy concretos de cumplimiento. El ahorro de costes en emplazamientos sumados a un estricto control de los objetivos supondría también un incremento sustancial del beneficio.

jueves, 27 de mayo de 2010

Tutorial de Erlang (1) Básico


Este es el primero de una serie de guías esquemáticas que realizaré mientras me introduzco en el apasionante mundo de Erlang:




1. Funciones y módulos

Con este primer programa veremos como se desarrolla con erlang:

test1.erl:
---------------------------------------------
-module(test1).
-export([sumar/2, restar/2, factorial/1]).

% Funcion sumar
sumar(X, Y) ->
X + Y.
% Funcion restar
restar(X, Y) ->
X - Y.

% Funcion factorial
factorial(1) ->
1;
factorial(X) when X > 0 ->
X * factorial(X - 1).
---------------------------------------------


Situar el fichero test1.erl en el bin donde reside el programa erl (erl.exe en windows).

---------------------------------------------
C:\Program Files\erl5.7.5\bin>erl.exe
Eshell V5.7.5 (abort with ^G)
1> c(test1).
{ok,test1}
2> test1:sumar(3,5).
8
---------------------------------------------

Con c(test1). realizamos la compilación del módulo.


Elementos que hemos visto:

- module(test1)
Nombre del módulo. El fichero que lo contenga debe llamarse igual que el módulo con la extensión .erl. Para llamar a las funciones que exporte el módulo la sintaxis es modulo:funcion(param1, param2).

-export([sumar/2, restar/2]).
Exportación de funciones del módulo al exterior con el número de parámetros esperados

factorial
Define dos comportamientos en función del parámetro de enrada para limitar la recursividad, el ";" separa las múltiples definiciones de la misma función.

%
Comentario, acaban con el retorno de carro


2. Variables, Atomos, Tuplas y Listas


Variables
Empiezan por mayúscula, pueden asignarse, pero sólo una vez.

Atomos
Comienzan por minúscula y se reducen a un literal que podrá ser utilizado en el programa.

Tuplas:
Compone un tipo de dato mediante un número fijo de términos:
{Term1,...,TermN}
Cada término en la tupla se llama elemento. El número de elementos es el tamaño de la tupla.
Hay funciones predefinidas para manejarlas (BIFs: built-in functions).

Examples:

1> P = {adam,24,{july,29}}.
{adam,24,{july,29}}
2> element(1,P).
adam
3> element(3,P).
{july,29}
4> P2 = setelement(2,P,25).
{adam,25,{july,29}}
5> tuple_size(P).
3
6> tuple_size({}).
0

Listas:
Compone un tipo de datos mediante un número variable de términos
[Term1,...,TermN]
Cada término de la lista se llama elemento. El número de elementos es la longitud de la lista.

Examples:

37> L = [a, b, {1, 2}].
[a,b,{1,2}]
38> [H|T] = L.
[a,b,{1,2}]
39> H.
a
40> L.
[a,b,{1,2}]
41> T.
[b,{1,2}]
42> length(H).
** exception error: bad argument
in function length/1
called as length(a)
43> length(T).
2
44> length(L).
3
45> L2 = [a, b | T].
[a,b,b,{1,2}]
46> L2.
[a,b,b,{1,2}]
47> T.

test2.erl:
---------------------------------------------
-module(test2).
-export([contar_lista/1, invertir_lista/1]).

% Funcion contar_lista
contar_lista([]) ->
0;
contar_lista([H|T]) ->
1 + contar_lista(T).

% Funcion invertir_lista interfaz
invertir_lista(L) ->
invertir_lista(L, []).

% Funcion invertir_lista implementacion con variable auxiliar de arrastre
invertir_lista([H|T], Lista_Invertida) ->
invertir_lista(T, [H | Lista_Invertida]);
invertir_lista([], Lista_Invertida) ->
Lista_Invertida.
---------------------------------------------


3. Salida por el terminal


1> io:format("salida").
salidaok
2> io:format("salida~n").
salida
ok
3> io:format("salida ~w~n", [hola]).
salida hola
ok
4> io:format("salida ~w ~w ~w~n", [hola, adios, 1]).
salida hola adios 1
ok


4. Control de flujo (if/case)

test3.erl:
---------------------------------------------
-module(test3).
-export([encontrar_elemento/2, encontrar_elemento_case/2]).

% Funcion encontrar_elemento
encontrar_elemento(A, []) ->
false;
encontrar_elemento(A, [H|T]) ->
if
A == H ->
true;
% El else aqui seria true ->
A =/= H ->
encontrar_elemento(A, T)
end.
encontrar_elemento_case(A, []) ->
false;
encontrar_elemento_case(A, [H|T]) ->
case A of
H ->
true;
_Else ->
encontrar_elemento_case(A, T)
end.
---------------------------------------------

5. Expresiones


5.1. Comparación de términos

Expr1 op Expr2
op Descripción
---------------------------
== igual
/= distinto
=< menor o igual
< menor
>= mayor o igual
> mayor
=:= exactamente igual
=/= exactamente distinto


5.2. Operadores aritméticos

op Expr
Expr1 op Expr2

op Descripción Tipo de arg
-----------------------------------------------
+ operador unario + number
- operador unario - number
+ number
- number
* number
/ división en coma flotante number
bnot not unario a nivel de bit integer
div división entera integer
rem resto entero de X/Y integer
band and a nivel de bit integer
bor or a nivel de bit integer
bxor xor a nivel de bit integer
bsl desplazamiento a la izq. integer
bsr desplazamiento a la dcha. integer


5.3. Expresiones booleaneas

op Expr
Expr1 op Expr2

op Descripción
---------------------
not unario not
and and lógico
or or lógico
xor xor lógico


5.4. Expresiones (short-circuit) evaluación perezosa

Sólo se evalúa la 2 si es estrictamente necesario.

Expr1 orelse Expr2
Expr1 andalso Expr2


5.5. Operaciones sobre listas

Expr1 ++ Expr2
Concatenación de listas
1> [1,2,3]++[4,5].
[1,2,3,4,5]

Expr1 -- Expr2
Substracción, elimina la primera aparición de cada elemento de la segunda lista de la primera, opera en modo foreach
1> [1,2,3,2,1,2]--[2,1,2].
[3,1,2]


5.6. Guard Sequences (secuencias de guardia)

Una secuencia de guardia es una secuencia de guardias, separadas por punto y coma (;). La secuencia de guardia es true si al menos una de sus guardias (elementos) es true. Cuando una lo cumple, las restantes, si las hubiera, no son evaluadas:

Guard1;...;GuardK

Una guardia es una secuencia de expresiones de guardia separadas por coma (,). La guardia es true si todas las expresiones evaluadas son true

GuardExpr1,...,GuardExprN

Expresiones válidas de guardia son las siguientes:

El atom true, otras constantes (términios y variables establecidas), comparaciones de términos, expresiones aritméticas, booleanas y short-circuit, y las siguientes funciones predefinidas:

BIFs de chequeo de tipos
-------------------------
is_atom/1
is_binary/1
is_bitstring/1
is_float/1
is_function/1
is_function/2
is_integer/1
is_list/1
is_number/1
is_pid/1
is_port/1
is_record/2
is_record/3
is_reference/1
is_tuple/1

BIFs aritméticas
--------------------------
abs(Number)
bit_size(Bitstring)
byte_size(Bitstring)
element(N, Tuple)
float(Term)
hd(List)
length(List)
node()
node(Pid|Ref|Port)
round(Number)
self()
size(Tuple|Bitstring)
tl(List)
trunc(Number)
tuple_size(Tuple)


5.7. Funciones de orden superior

fun
(Pattern11,...,Pattern1N) [when GuardSeq1] ->
Body1;
...;
(PatternK1,...,PatternKN) [when GuardSeqK] ->
BodyK
end

Una función de orden superior (fun expression) empieza con la palabra reservada "fun" y acaba con la palabra reservada "end". Entre ellas aparece la declaración de la función, similar a una declaración de función estandar excepto que no aparece el nombre de la función especificado.

1> Fun1 = fun (X) -> X+1 end.
#Fun
2> Fun1(2).
3
3> Fun2 = fun (X) when X>=5 -> gt; (X) -> lt end.
#Fun
4> Fun2(7).
gt

foreach y map son dos funciones estandar que operan de este modo, la primera aplica la función a cada elemento de la lista y la segunda genera una nueva lista como resultado de aplicar la función a cada elemento de la lista.

92> Add 3 = fun(X) -> X + 3 end.
#Fun
93> lists:map(Add 3, [1,2,3]).
[4,5,6]



6. Programación concurrente


6.1. Procesos

Los procesos Erlang son como los threads pero sin datos. La función predefinida "spawn" es utilizada para crear nuevos procesos.

spawn(Módulo, Función exportada, Lista de argumentos)

Retorna el identificador del proceso Pid.

test4.erl:
--------------------------------------------
-module(test4).
-export([start/1, funcion/2]).

funcion(Palabra, Proceso) ->
io:format("~w - ~w~n", [Palabra, Proceso]).

start(0) ->
done;
start(A) ->
Pid1 = spawn(test4, funcion, [hola, A]),
io:format("Proceso ~w arrancado~n", [Pid1]),
Pid2 = spawn(test4, funcion, [adios, A]),
io:format("Proceso ~w arrancado~n", [Pid2]),
start(A - 1).
--------------------------------------------


6.2. Paso de mensajes:

--------------------------------------------
-module(test5).
-export([start/0, funcion/0]).

funcion() ->
receive Mensaje ->
io:format("Proceso recibe el mensaje: ~w~n", [Mensaje]),
funcion()
end.

1>Pid = spawn(test5, funcion, []).

2>Pid ! hola
3>Pid ! adios
--------------------------------------------

Patrón de recepción de mensajes:

receive
patron1 ->
acciones1;
patron2 ->
acciones2;
....
patronN ->
accionesN
end.

Paso de mensaje: Pid ! mensaje

self(): Función que da el Pid del proceso actual


6.3. Registrar nombres de procesos

register(pong, spawn(tut16, pong, []))

pong ! mensaje

register(Name, Pid) Asocia un átomo con un Pid
registered() Retorna una lista de nombres registrados.
whereis(Name) Retorna el Pid del nombre buscado si está registrado