sábado, 5 de noviembre de 2011

JavaScript Server Side - Alejandro Hernandez

Tercer tech update!!!!!

sábado, 29 de octubre de 2011

lunes, 17 de octubre de 2011

JavaScript - Alejandro Hernández

Tengo el agrado de contarles que se hizo realidad uno de mis sueños más grandes. Poder comenzar a dar una serie de charlas sobre JavaScript en una gran multinacional. En este momento me encuentro trabajando en Globant, empresa Argentina dedicada al outsourcing de recursos en tecnologías de la información y, hasta ahora, el mejor lugar que conozco para trabajar.

Sin más introducción, aquí el video.



miércoles, 5 de octubre de 2011

Steve Jobs


Stay hungry, stay foolish!!!!!!
Nuestra industria ha perdido un grande. Revolucionario, creativo e inspirador son apenas unas pocas de las miles de palabras que se vienen a mi cabeza en este momento, para describir a la gran persona que fue Steve Jobs, sin duda influyó de manera importante en nuestra historia y por ello será recordado siempre.
Un gran saludo Steve..... y una cosa más.... mi más sincera admiración por el trabajo de tu vida.


viernes, 2 de septiembre de 2011

A recoger la basura

Este post surgió por una consulta en mi trabajo asi que Gracias Guille por la idea!

Vamos a hablar un poco del famosisimo proceso de Garbage colection de javascript
Como sabrán (deberían) el Garbage colector de un lenguage es el encargado de liberar la memoria que ya no se está utilizando, pero... como es que hace esto?
La parte dificil aqui es decidir cual es la memoria que se debe liberar y cual no, entonces es necesario un algoritmo para marcar que objetos en memoria no son más necesarios.
En las primeras implementaciones (javascript 1.1 Netscape 3) el garbage collector utilizaba un mecanismo llamado
Reference Counting (Conteo de referencias) el cual basicamente mantiene un registro de la cantidad de variables que apuntan a un objeto en memoria.


var a = {};
//creamos un objeto en memoria y lo apuntamos desde la variable a
// la cantidad de variables (referencias al objeto) es 1

var b=a;
//con b apuntamos al mismo objeto aumentando su reference counting en 1
//por lo tanto ahora 2 variables le apuntan

b=null
//desapuntamos b, decrementa el conteo de referencias nuevamente a 1

a=null
//desapuntamos el objeto y su conteo de referencias cae a 0
// ahora es un objeto en memoria no apuntado por nadie propenso
// a la recolección de basura (y recupero del espacio en memoria)

Sin embargo el algoritmo de reference counting, tiene un problema Gravisimo
las referencias ciclicas
esto es

var a={color:'rosa'};
var b={color:'rojo'};
var c={color:'negro'};
//creo 3 objetos y los apunto con 3 variables
//cada objeto tiene su reference count en 1
//RC(rosa):1 RC(rojo):1 RC(negro):1


a.next=b;
//ahora apunto con a.next al objeto rojo
//RC(rosa):1 RC(rojo):2 RC(negro):1
b.next=c;
//con b.next apunto al objeto negro
//RC(rosa):1 RC(rojo):2 RC(negro):2
c.next=b;
//con c.next apunto nuevamente al objeto rojo
//RC(rosa):1 RC(rojo):3 RC(negro):2

//desapunto todas las variables
a=null;
b=null;
c=null;
//decrementando en 1 todos los RC
//RC(rosa):0 RC(rojo):2 RC(negro):1
//cuando el proceso de garbage colector note que el objeto
//rosa no es apuntado por nadie lo eliminará, eliminando
//el puntero next al objeto rojo decrementando su RC nuevamente
//RC(rosa):0 RC(rojo):1 RC(negro):1
//pero rojo y negro continuan apuntandose entre si por tanto
//sus RC jamas decaen a 0 y no son liberados
//MEMORY LEAK!!!!!


Los objetos apuntados ciclicamente no pueden ser liberados mediante este algoritmo, por lo cual muchos nisiquiera aceptan a Reference Counting como un algoritmo de Garbage Collection.

Por suerte los tiempos cambiaron y la mayoria de los interpretes de javascript han decidido actualizar sus algoritmos de garbage collection a algo mucho mas efectivo llamado

Mark-and-sweep

Que basicamente toma un contexto y revisa para todas las variables de ese contexto, todos los objetos en memoria alanzables desde esas variables y los marcan como "ALCANZABLE" desde el contexto del programa.
luego recorre la memoria en busca de los objetos no marcados como "ALCANZABLES" y los borra.

es un algoritmo que requiere mucho mas trabajo pero es más efectivo.

tienen una mejor explicación aqui

como pueden ver en
Google chrome utiliza garbage collection por Mark-and-sweep
"he V8 garbage collector reclaims memory used by objects that can never again be accessed."
y como lo hace en

Linda historia... pero es "historia"?

En cuanto al lenguage si, PEEEERO y este es un gran pero, dependiendo del entorno en el que uses javascript esto puede variar.

Para los navegadores?

Lamentablemente no, todos los navegadores aún continuan utilizando Reference Counting para los objetos del DOM
por lo tanto basta apuntar a un objeto del DOM desde javascript y al objeto javascript desde el DOM y habremos generado un memory leak

veamos un ejemplo


var tryingToLeak = function(){
obj=document.getElementById("btnClearLog");
//apunto al DOM desde JS
document.getElementById("btnClearLog").expandoProperty=obj;
//apunto a JS desde el DOM
obj.bigString=new Array(10000).join(new Array(2000).join("XXXXX"));
//Consumo memoria en JS
};
tryingToLeak();


cada vez que ejecutamos el codigo anterior el proceso reclama 200mb de ram que no devuelve jamas
pueden probarlo utilizando el "Administrador de tareas de Google Chrome"
por mas que la variable de JS ya no tenga visibilidad el objeto del DOM continua con un RC mayor a 1 y por tanto no es sujeto a ser eliminado.

A continuación les dejo dos códigos que demuestran que no se producen memory leaks en javascript


var tryingToLeak = function(){
for(var i=0; i<=1000; i++){
var str=new Array(1000).join(new Array(2000).join("XXXXX"));
}
};
tryingToLeak();


var tryingToLeak = function(){
for(var i=0; i<=1000; i++){
var arr=[];
for(var j=0; j<=1000;j++){
arr.push(new Array(2000).join('XXXXX'));
}
}
};
tryingToLeak();


Saludos

sábado, 30 de abril de 2011

1, 2, 3..... TODOS A LA CHURCH!

"Estoy escribiendo la función que nunca nadie escribió.... pero no puedo terminarla"


Cuando hablamos de Javascript hablamos de funciones lambda, pero... de donde viene ese lambda?.

El calculo lambda es un sistema formal introducido por Alonzo Church allá por los años 30 para modelar la matemática (WOW! Que ambición!) pero se volvió suceptible a la paradoja de Russell y entonces lo uso para estudiar la computabilidad.
Ahora... cómo es el calculo lambda?
Bueno Alonzo introdujo algunos conceptos muy complejos en las funciones, conceptos que ya estaban ahi pero que nadie habia notado.


Los tres conceptos del cálculo lambda

Dada la función suma(x,y)=x+y Church nota los siguientes puntos

Las funciones no necesitan ser explícitamente nombradas: esto es: suma(x,y)=f(x,y)=s(x,y)=x+y, no importa el nombre de la función, sino lo que esta hace.

El nombre que se le asigne a los parámetros es irrelevante: quiere decir que suma(x,y)=x+y === suma(u,v)u+v (simple)

Toda función que recibe más de un argumento puede ser reescrita como una función que recibe un solo argumento que devuelve otra función que recibe un argumento, que devuelve otra función que recibe un argumento, que devuelve otra......(asi sucesivamente).... hasta que la ultima es la que realiza la operación: Y aqui ya necesitamos de la notación de javascript para ver de que estamos hablando

function suma(x,y){
return x+y;
}

function sumador(x){
return function(y){
return x+y;
}
}

var sumador5 = sumador(5);

alert(suma(5,4)); //9

alert(sumador5(4)); //9

a este proceso se le conoce como currificación (nombre horrible) me quedo con el ingles currying, concepto del que ya hemos hablado en este post

Con estas tres observaciones Church decide expresar sus números para realizar una aritmética básica, para ello define la función Identidad de la forma

function I(x){
return x;
}

Ahora bien, los números de Church propiamente dichos se expresan así:

El número N de Church es una función que recibe una función f como parámetro y devuelve otra función que compone la función f, N veces consigo misma.
es decir

function churchOne(f){
return function(x){
return f(x);
};
}

function churchTwo(f){
return function(x){
return f(f(x));
};
}

function churchTree(f){
return function(x){
return f(f(f(x)));
};
}

Sin embargo sería aburridisimo expresar los números de esa forma, por tanto define una funcion Sucesor que es una función que recibe un número de Church N como parámetro y devuelve el siguiente número de Church (N+1)
El sucesor de Church se escribe de la siguiente forma

function churchSucc (n) {
return function (f) {
return function (x) {
return f(n(f)(x));
};
};
}

Además tambien define el cero de Church como una función que recibe una función f como parámetro y devuelve la función Identidad (caprichoso el cero) , de la forma

function churchZero (f){
return I;
}

Pero.... de que esta hablando Church, pues bien para que se den una idea, si f(x)=x+1 , entonces el calculo lambda se vuelve la aritmética común, de esta forma podemos probar el siguiente programa completo para ver los números de Church en toda su gloria

function I (x) {
return x;
};
function churchZero (f) {
return I;
};

function churchSucc (n) {
return function (f) {
return function (x) {
return f(n(f)(x));
};
};
}

function f(x){
return x+1;
}

alert(f(0));//1
alert(I(f)(0)); //1

alert(churchZero(f)(0)); //0

var churchOne=churchSucc(churchZero);
alert(churchOne(f)(0));//1

var churchTwo=churchSucc(churchOne);
alert(churchTwo(f)(0));//2


alert(churchSucc(churchSucc(churchSucc(churchZero)))(f)(0));//3


Entonces vemos que el mismo churchSucc es una función suceptible de ser utilizada con los mismos numeros de Church para hallar números de Church superiores

alert( churchTwo(churchSucc)(churchTwo)(f)(0) );//4


Entonces vemos que se puede volver realmente muy interesante la composición sucesiva de una función.
Por ahora los dejos solamente con los números y volveremos luego con algunos operadores.
Si te cansaste de leer Church a lo largo del post, te dejo el resultado de la siguiente función

function f(x){
return x+'Church ';
}

var churchTen =churchSucc(churchSucc(churchSucc(churchSucc(churchSucc(churchSucc(churchSucc(churchSucc(churchSucc(churchSucc(churchZero))))))))));
alert( churchTen(f)(''));

//Church Church Church Church Church Church Church Church Church Church

jajajaa
que lo disfrutes!
Articulo fuente de la implementación Javascript (al que aprovechamos y le dimos una manito)

viernes, 15 de abril de 2011

Sabes programar en javascript...Y?

"Puedo escribir las funciones menos tristes esta noche."
picanteverde

Despues de tanto tiempo sin traerles nada divertido al blog, he decidido volver porque por suerte ahora tengo un trabajo donde puedo aprender cosas nuevas para traer por aca.
Hoy vamos a hablar de Y combinator (me encantaría escribir este post en ingles pero lo voy a hacer en castellano para contribuir un poco a la poquisima cantidad de articulos (de buen javascript) en este idioma).

Qué es el combinador Y?

Ademas de ser una empresa de Capital de riesgo de inversión y un operador matemático (por dios que estas leyendo) tambien conocido como Fixed Point Combinator
es uno de los artilugios más fascinantes de la ciencia de la computación y es muy simple de explicar (eso es mentira).

El Combinador Y es una funcion de alto orden que calcula el punto fijo (fixed point) de otra funcion.

Si no entendiste nada vamos por partes.

El punto fijo (fixed point) de una función f es un valor x tal que: f(x)=x
Por ejemplo 1 y 0 son puntos fijos de la función cuadrado, debido a que si
f(x)=x^2 entonces 1^2=1 y 0^2=0.
Ahora bien, eso es valido para funciones de primer orden (funciones en valores simples como enteros).

Para una función f de alto orden, un punto fijo es otra función p de forma que f(p)=p
y un combinador de punto fijo (combinador Y), es OTRA función g que produce una función punto fijo p para cualquier funcion f de forma que:
p=g(f), f(p)=p
ó
f(g(f))=g(f)

ya se a esta altura te estas arrepintiendo de haberte puesto a leer algo que no parece tener nada que ver con javascript pero ahora vamos a escribirlo en javascript, no porque sea útil en si, disculpen mi obtusa visión pero aún no logro comprenderlo tanto como para encontrarle una funcionalidad, es por eso que decidí escribir este post (de la misma forma que el post que estoy leyedo ).

Para qué sirve Y?

Y es comúnmente usado para permitir recursión anónima en lenguajes donde no se puede asumir que esté soportada.
Veamos un ejemplo con una función para calcular el factorial de un numero de forma recursiva.

var factorial = function(x){
return x == 0 ? 1 : x * factorial(x - 1);
};

alert(factorial(4)); //24

pero que pasaría si....

var factorial = function(x){
return x == 0 ? 1 : x * factorial(x - 1);
};

var fac=factorial;
factorial="nada";
alert(fac(4));


Deja de funcionar debido a que factorial llamado desde dentro de la función no es más la función misma, sino otra cosa.

Antes que nada voy a aclarar que javascript si permite recursividad anónima usando callee

var factorial = function(x){
return x == 0 ? 1 : x * arguments.callee(x - 1);
};

var fac=factorial;
factorial="nada";
alert(fac(4));


Peeeero si no pudiese, necesitaríamos el combinador Y, vamos a encontrarlo.

Supongamos que para evitar esto, pasamos una referencia de la función con la que debe realizar la recursividad, evitando así hacer cualquier tipo de referencia a alguna variable global.

var factorial = function(h, x){
return x == 0 ? 1 : x * h(h, x - 1);
};
alert(factorial(factorial, 4));// 24

Pero podemos precompilar el primer parametro de la función y devolver una función que reciba solo un parametro, y escribirla de la siguiente manera

var factorial = function(h){
return function(x){
return x == 0 ? 1 : x * h(h)(x - 1);
};
};

alert(factorial(factorial)(4));

Aquí yace la magia, factorial recibe una referencia a si misma y devuelve una función recursiva sobre su propia referencia, de ahí que [h(h)] devuelve una función recursiva sobre si misma. Por tanto debemos invocarla en la forma [factorial(factorial)](4), donde la función devuelta por factorial(factorial) es la función recursiva.

Hasta ahí todo bien, pero tenemos ese h(h)(x) en la definición de la función, en lugar de un simple q(x), entonces podemos crear otra función de envoltorio que cree una referencia a h(h), es simplemente para poder llamarla en la forma q(x)


var factorial = function(h){
return function(x){
var f = function (q,x){
return x == 0 ? 1 : x * q(x - 1);
};
return f(h(h), x);
};
};

alert(factorial(factorial)(4));

Ahora en la función f podemos realizar la misma precompilación del primer parametro que ya hicimos antes y obtener la siguiente función

var factorial = function(h){
return function(x){
var f = function(q){
return function(x){
return x == 0 ? 1 : x * q (x - 1);
};
};
return f(h(h))(x);
};
};

alert(factorial(factorial)(4));


pero ahora, la función f no posee ninguna referencia externa o global, asi que podemos sacarla afuera, y aún así funcionará.

var f = function(q){
return function(x){
return x == 0 ? 1 : x * q (x - 1);
};
};

var factorial = function (h){
return function (x){
return f(h(h))(x);
};
};

alert(factorial(factorial)(4));


Ahora llegamos a que f es nuestra función de la que queremos el punto fijo. el punto fijo es la función devuelta por factorial(factorial), entonces podemos escribir Y() para que nos la devuelva de la siguiente manera.

var Y = function (f){

var g = function (h){
return function(x){
return f(h(h))(x);
};
};

return g(g);
};

var factorial = function (q){
return function(x){
return x == 0 ? 1 : x * q(x - 1);
};
};

var factorial_recursivo = Y(factorial);

alert(factorial_recursivo(4));


Finalmente escrita en propósito general, quedaría


var Y = function(f){
return (function (g) {
return g(g);
})(function(h) {
return function(){
return f(h(h)).apply(null,arguments);
};
});
};

//Y LISTO!!!! ahora podemos escribir factorial así

var factorial = Y(function(recurse){
return function(x){
return x==0 ? 1 : x * recurse(x - 1);
};
});

alert(factorial(4)); //24!!!!!!!!



Lo más frustrante acerca del combinador Y es que una ves que lo derivaste, es imposible decir que hace, con solo mirar su código.
Si llegaste hasta aquí, sin marearte, FELICITACIONES!!!!!!!