Mostrando entradas con la etiqueta javascript. Mostrar todas las entradas
Mostrando entradas con la etiqueta javascript. Mostrar todas las entradas

domingo, 29 de enero de 2012

Aca les dejo un link a uhc-js. Se trata de una implementación de haskell sobre javascript. Es una alternativa copada a coffee script y otras ideas de lenguajes funcionales booteados desde javascript, pero me animo a decir que si es haskell posta va a ser la gloria.

Aca les dejo un link mas direccionado donde hacen un analisis muy interesante de los problemas core de javascript, como la falta de orden y el problema del sistema de tipos (algo de lo que hablaba en algun post anterior) y habla de algunas implementaciones (como uhc o ghcjs :3)

Mirenlo de este modo, en un sitio no hay necesidades de abstracciones locas que entender para empezar, por lo que se puede usar sin saber conceptos avanzados de funcional :).

sábado, 28 de enero de 2012

Manejo de errores simple Javascript

      Uno de los grandes problemas con javascript es el manejo de errores. Muchas veces uno se queda dando vueltas tratando de entender por que algo funciona y lo que sucede es que silenciosamente javascript falló y nadie se enteró de nada. O, en otros casos, una funcion nuestra que ejecutó JQuery falló y se ve el scope de jquery en version min y nos queremos cortar la sexualidad.

     Otras veces, con todas las funciones locas para agregar features de funcional, hay un gran nivel de indireccion y wrappeo de funciones, lo que lleva a un debug complicado.

    Por otro lados siempre es bueno tener el manejo de errores en un solo punto, después de todo DRY se aplica a todo, y los varios manejos de errores no traen mas que dolores de cabeza.


    En fin, siguiendo con la linea de pensamiento de orden superior podemos pensar en una funcion que se use en la definicion de las funciones que pueden tirar un error.

function e (fn, st) {
   if (st == null) st = alert;
   return function () {
        try {fn.apply(null, arguments)}
        catch (err) { st(err); }
   }
}


  Como bien se puede ver esta funcion devuelve la funcion metida adentro de un try catch definido y con una estrategia de manejo de error pasada por parametro y con alert como estrategia por defecto.

  Ahora con agregar un objeto tercero que maneje errores tenemos una definición robusta. :)

 Un ejemplo de uso puede ser

   var funcionManejada = e( function () { throw "ejemplo"}  );
   funcionManejada(); 



  Les prometo que si encuentro como bajar monadas felices a Jscript voy a hacer la versión monádica, que es todavía mas poderosa.


Ahora, como aplicamos esto a javascript orientado a objetos?
Se me ocurre velozmente una forma similar con el siguiente boceto

function ErrorMixin (object) {
    for(k in object){
     if(this.isMethod(object[k]) {
         object[k] = e(object[k]);
    }
  }
}

function objetito () {
   ErrorMixin(this);
   
}


Faltaria definir isMethod, que es una huevada pero no me acuerdo los strings :P Igual esta claro que este mixin es bastante pobre por que se aplica sobre todos los metodos del objeto. Se me ocurre tambien que podrían anotarse o podrían definirse con una expresion regular y alguna convencion adhoc.


Buep, enjoy your weekend my friend. Por mi lado me voy a escaviar y comer fondue a la farmacia

domingo, 15 de enero de 2012

Celtic Punk y Curryfication (O javascript para programadores funcionales - Parte 4)

Bueno bueno, aca estoy escuchando Floggin Molly (chivo de mi otro blog) y pensando en como traer la curryficacion y la aplicacion parcial a este blog :D y seguir con el thread cuyo post anterior es: highorder functions)

Bueno, primero empecemos por el principio.

Aplicacion Parcial de funciones

Este tema sale por ahí de la pregunta ¿Cual es el resultado de aplicar una funcion de n parametros con n-m parametros?

Por ejemplo:


function suma (a, b) {
        return a + b;
}



Que pasa si yo hago


var a = suma (1);



?


Lo que va a pasar en javascript asi como viene es que va a devolver NaN por resultado.
Va a tratar de sumar 1 + nulll.

O sea, va a tratar de ejecutar el código con lo que tiene. Eso nos lleva un poco a un post anterior (no el de brownies, al de lazy evaluation ), donde decimos "Las cosas se ejecutan cuando es necesario", en este caso agregamos "Y cuando pueden ser ejecutadas".


En el mundo funcional,

var fn = suma(1);


fn es una funcion que recibe un parametro y le suma 1 :) Obvio no?

Ahora, ¿Para qué mierda sirve esto? Hay quien dice que no sirve, que es pizarron, y otras cosas relacionadas

A eso le digo, si, C tambien era "pizarron" en la época de assembler. Objetos pensado tambien es pizarron hoy. Incluso detenerse y pensar antes de codear es "pizarron" desde alguna óptica. So, asi como hay codemonkeys que se contentan con tirar lineas de código por metro, tambien hay quien se contenta con tirar lineas eficientes y pensadas y no lidiar con repetición de código y otros tantos anti-patterns.

    A fin de poder hacer una herramienta poderosa del pase de funciones por parametro (highorder functions), necesitamos herramientas que nos dejen crear funciones a partir de funciones, y dar un saltito chiquito a otro orden de abstracción.

    'Dame un ejemplo práctico'
    'Bueno, ok. JQuery, en sus llamadas a ajax recibe para el caso de exito una funcion que recibe un parametro. Si vos tenes una función de dos parametros que recibe un parametro conocido y el otro es la data que retorna el server tenes que hacer otra función que reciba los datos y hardcodee el dato conocido, si pudieses hacer success:funcionLoca("valorHardCodeado") te ahorrarias multiples referencias indirectas a una función y repetición de código a lo pavote. Por otro lado tendrías un mecanismo para tener funciones polimorfisables.'
    'Aa, pero es un sintax sugar'
    'Si, igual que la suma. Todos sabemos que un programa que suma dos numeros luce así:



suma:
mov al,[1001]
mov bl,[1002]
mov cl,[1003]
add  al,bl
add al,cl
mov [1005],al



   ... digamos que yo prefiero llamarlo bootstraping '

   Como hacemos para tener aplicacion parcial entonces?

   bueno, un esbozo puede ser




var slice = Array.prototype.slice;

function partialApplication ( fn ) {
  var args = slice.apply(arguments, [1]);

  //aplico slice sobre arguments (que es una variable que apunta a todos los argumentos recibidos),
  //que no es de tipo array, pero se le parece bastante


   return function () {
               fn.apply(null, args.concat(slice.apply(arguments));
              // este es un truquito que une args (que esta vez es un array por haber pasado por slice) con

             // arguments pasado por slice para ser tambien un array.
    }

}





Excelente :D Ahora podemos hacer


var suma1 = partialApplication (suma, 1);



  Tadaaaa, aca tenemos una funcion directamente basada en otra :D. Si leen el código van a ver que une n parametros con m parametros. O sea, podrian hacer



var suma12 = partialApplication (suma, 1, 2);

suma12(); // = 3
suma123 = partialApplication (suma, 1, 2);
suma123(); // = 3 - ok, no tiene sentido, pero se puede hacer.




Con esto entonces tenemos una herramienta mas para trabajar con funciones. :)

" Pero pero, para! dijiste algo de curryficacion.. que onda? "

 Curryficacion

 Cierto cierto, no me habia olvidado. La curryficacion viene de (nombre inspirado en Haskell Curry, tambien encontrable como curryfication, currying ) 

 Bueno, esta idea esta muy emparentada con la aplicación parcial. Se trata de ver a las funciones que reciben n parametros (n > 0) como funciones que reciben un parametro y devuelven una funcion n-1 parametros. Cuando la funcion tiene todos los parametros que necesita se aplica o reduce.

entonces

var unoMasTres = suma(1)(2);



Me debiera devolver 3.

Esto nos lleva a la implementación de curryficate, una funcion que dada una funcion devuelve su funcion curryficable. (una aplicación parcial mas prolija y capa)




var slice = Array.prototype.slice;

function curryficate (fn) {

      if(!fn.hasOwnProperty("protoLength")) {
            fn.protoLength = function () { return fn.length; }       }
      var fnwrap = function () {
            var args = slice.apply(arguments,[0]);            if (fn.protoLength() - args.length <= 0) {                  return fn.apply(null, args);            }            else {
                  var curryfied = function () {                        return fn.apply (null, args.concat(slice.apply(arguments,[0])))                  };
            curryfied.protoLength = function () { return fn.protoLength() - args.length;       };
      return curryficate(curryfied);            }
      }

      fnwrap.protoLength = function () { return fn.protoLength() };

      return fnwrap;
}





Es una función un poco mas complicada, dado que una función que no define la cantidad de parametros en la firma no tiene parametros, hay que agregar datos a la funcion (aprovechando que las funciones son objetos :3 .. amo javascript :D )


Como la usamos? las formas mas comodas que encontre son asi:



var foldr = <b>curryficate</b>(
      function(list, funct, aux) {            for(i in list) {                  aux = funct(list[i], aux);            }            return aux;      });



En este caso no nos importa la version no curryficada, entonces definimos la funcion como curryficada de movida.

Por otro lado la otra version es



function foldr(list, funct, aux) {
      for(i in list) {            aux = funct(list[i], aux);      }      return aux;
}
var cfoldr = <b>curryficate</b> (foldr);







Lo que no recomiendo es usar esto en sub-scopes, presta a confusión.

Una vez curryficada la funcion se puede se puede usar de muchas formas:




var suma3 = curryficate ( function (a,b,c) { return a+b+c }}) ;


suma3(1,2,3); // = 6
suma3(1)(2,3); // = 6
suma3(1,2)(3); //= 6
suma3 (1) // = suma3(b,c);
suma3 (1,2) //= suma3(c);




La unica contra de esto es que las funciones curryficadas SOLO ejecutan cuando tienen todos los parametros, por lo que se pierden las funciones de parametros variables. Con esto, curryficate y partialApplication son funciones en parte complementarias.


Felicidad. Disfruten lo que queda de este domingo hermoso :D. Salgan al sol :D

domingo, 8 de enero de 2012

highorder functions - Funciones de orden superior. (Javascript para programadores funcionales parte 3)

Ya en el artículo de lazy evaluation vimos que es copado pasar funciones por parametro para evitar ejecutar código antes de tiempo.

   High-order function es como se llama a las funciones que reciben funciones por parametro.

   A diferencia del artículo de lazy evaluation, las funciones de esta categoría son funciones que reciben criterios por parametro.

Qué es un criterio? 

Uhm, bueno, hay varias formas de criterio, pero creo que puedo generalizarlos en dos, criterio de consulta y criterio de ejecución. Un criterio de consulta es un computo que me permite saber algo de la ejecución. Un criterio de ejecución es un computo que me permite realizar una acción.

Un caso clarisimo es el if como funcion:

function ifFn (expression, ifTrue, ifFalse) {
  if(expression) ifTrue();
  else ifFalse();
}


Donde expression es un criterio de consulta, que nos dice si sucedio algo y ifTrue / ifFalse son unidades computables.

En este caso, la funcion de orden superior es ifFn, que define un comportamiento general que se termina de definir con las funciones que recibe por parametro.

Esta misma idea puede ser llevada a varios ambitos, sobre todo algoritmicos.


Cuantas veces hemos definido algoritmos identicos en mecanismo pero distintos solo en consulta y modificación? 


Para que vean cuantas veces hicieron cosas una y otra vez por ahi sin terminar de verlo y para terminar de explicar el punto voy a dejar un pequeño catalogo de funciones tipicas de funcional


/* 
   foldr(ight) es una funcion que dada una lista, una funcion y un elemento, retorna la aplicacion de la funcion sobre cada item de la lista y el resultado de la ejecucion anterior como segundo parametro (en el caso de la primera ejecucion del a funcion, el segundo parametro es el elemento recibido por parametro. Recorre la lista de izquierda a derecha
  function suma (a,b) { return a + b }


  foldr([1,2,3,4,5,6,7,8,9], suma, 0) = sumatoria de todos esos numeros (no jodan, no voy a calcularlo)

*/
function foldr (list, funct, aux) {
    for(i in list) {
       aux = funct(list[i], aux);
    }
    return aux;
}


/* Foldl(eft) es igual que foldr, pero recorre la lista de derecha a izquierda */


function foldl (list, fn, aux) {
     return foldr(list.reverse(), fn, aux);
}



/*
  fmap es una funcion que aplica una funcion f sobre cada item de una lista y mapea cada resultado en un array que retorna. 


  Ejemplo de uso: 
  
  fmap(even, [1,2,3,4,5,6]) = [false, true, false, true, false, true]


  function nombre (m) { return m.nombre }


  fmap(nombre, [ {nombre:"jacinto" }, {nombre:"elisa" }, {nombre:"ramona" }] = 
   ["jacinto", "elisa", "ramona"] 


  Matematicamente hablando, fmap transforma un conjunto dado aplicando una funcion de transformación
 **/

function fmap (f, array) {
    var retorno = [];
    for (i in array) {
      retorno.push(f(array[i]));
    }

    return retorno;
}




/*
  Filter es una funcion que filtra items de una lista, segun la funcion parametro 


  ejemplo: 


  filter(even, [1,2,3,4,5,6]) = [2,4,6]
 
*/
function filter (fn, array) {
        var retorno = [];
        for (i in array) {
            if(fn(array[i]) retorno.push(array[i]);
        }
        return retorno;    

}



Tengo varias highorder mas, pero no alcanza lo que explique hasta ahora para poder mostrarlas y que tenga sentido, so, keep tuned. El proximo post viene botines de punta con meta-funciones


> perá perá!! como se lo explico a mamá???

A tu vieja decile

 Una funcion de orden superior es como una señora que limpia, vos le decis que consideras desordenado, y como te gustaria que quede, después te desentendes de como lo hace o en que orden.
 

PD: Foldr es muchisimo mas poderosa de lo que explico aca, pero bue, para mas adelante, tenganla en cuenta :)

Lazy evaluation - Evaluacion perezosa (Javascript para programadores funcionales - Parte 2 )

x Antes de adentrarne en esta idea, primero pensemos un poco en que es la evaluación.

 ¿Qué es la evaluación?
  Es la ejecución o reducción de un computo a su forma mas simple. Teniendo por computo cualquier cosa suceptible a ser computada: funciones, aplicacion de operadores, expresiones booleanas, etc.

  Análisis

  Hay varios aspectos en el análisis de la forma de evaluación. El tema de este post es el computo en el tiempo, o sea, el momento en que se da el computo.

   En el caso de eager evaluation la evaluacion se hace lo antes posible, en el caso de lazy evaluation se deja para el momento en que realmente es necesaria.

  Uno de los casos emblematicos (no reproducibles en javascript) es el de las listas infinitas. Haskell por ejemplo permite que uno defina una lista infinita:


   x = [1..]



  Esto es posible por que la lista se va generando on demand a diferencia de la mayoria de los lenguajes, donde antes de usar una lista, esta tiene que estar creada. (Este aspecto puede ser llevado mas lejos, pero eso esta out-of-scope).

  Un ejemplo mas mundano es el de la necesidad de datos, por ejemplo cuando uno necesita datos para poder ejecutar una funcion y estos datos son obtenidos de otra funcion, uno tiene que ejecutar las segundas para poder aplicar la primera.


   funcionQueNecesitaDatos(fndata1(), fndata2(),..., fndataN());


En el caso de javascript, un debug nos diria que primero se ejecuta fndata1, despues la 2 y asi hasta llegar a la N, una vez resueltos los parametros, se ejecuta funcionQueNecesitaDatos.


  En haskell, por ejemplo, el resultado de una funcion no se termina de evaluar hasta que es realmente necesario, o sea, hasta que funcionQueNecesitaDatos usa el parametro. Supongamos una funcionQueNecesitaDatos de la forma

   funcionQueNecesitaDatos (a,b,c){
      if(a) return b;
      else return c;
   }


En el esquema de eager evaluation se ejecutan las cuatro funciones, en el esquema de lazy evaluation solo se ejecutan tres. Si a eso sumamos que todo en haskell es una funcion, inclusive las expresiones (3 > 2) y que tambien se evaluan on demand vemos que no se ejecuta absolutamente nada que sea innecesario y todo se obtiene al momento en que se necesita. Ese es el poder del esquema lazy evaluation.

Claramente en javascript tampoco podemos llegar a ese nivel de granularidad, es una cuestion de la concepcion del lenguaje. Pero, pero, peeero, podemos re pensar un poco nuestro código para que tienda a ese lado, lo que nos lleva a que las funciones son datos :)


Las funciones son datos y pueden ser pasadas por parámetro


function funcionQueNecesitaDatos (expresion, then, otherwise) {
     if(expresion()) return then();
     else return otherwise();
}







funcionQueNecesitaDatos(fnData1,fnData2, fnData3)


Como se puede ver en este caso, las funciones llegan por parametro y se ejecutan segun necesidad.

En este esquema tenemos la dificultad de que las funciones debieran ser todas invocables sin parámetros para que no sea una gran complicación. 

En el post de highorder functions voy a mostrar un humilde hadouken para pasar este problemilla.







Corolario


Cuando tenemos código mas caro de ejecutar que la creacion de una función, podemos asegurarnos que se ejecute solo cuando sea necesario pasando funciones por parametro o buscando hooks que nos permitan estirar el momento de evaluación el mayor tiempo posible para asegurarnos que sea realmente necesaria su ejecución.

Esto nos da en retribución un código varios ordenes mas eficiente.


Como se lo contás a tu vieja?

A ella le decís que eager evaluation sería limpiar el cuarto estando ella de vacaciones, mientras que lazy evaluation es ordenar el cáos justo antes de que ella llegue.

sábado, 31 de diciembre de 2011

Javascript para programadores funcionales - Parte 1

 ¿Por que no hablo de Coffee Script? 
 
  Basicamente por dos razones:
  • Lo miré por arriba, pero por ahora Coffee script no se banca todo lo que quiero
  • No siempre se pueden usar frameworks

¿Por que javascript y no otro?

   Por que es un lenguaje que uno facilmente puede odiar por no verle las posibilidades que nadie cuenta.  Si me dan las ganas voy a tratar de poner ejemplos de como se haría en Scala, Haskell, Python y si tengo ganas sobrenaturales lisp (perdon amantes de lisp, odio los parentesis).


¿Que me motiva?

  Cuando llegué al mundo de javascript y vi los frutos lo primero que pensé es: ¡Esto es una mierda!

   Pero después de entender javascript como javascript y no como lo que se hace con javascript ví la luz. Javascript no solo no es una mierda, sino que es hoy por hoy uno de mis lenguajes favoritos.
 
  Hay dos razones por la cual pasa esto:

   a) tengo objetos armados armados a partir de prototipos (por lo que tengo mixins en dos patadas)
   b) las funciones son datos.


  En los posts relacionados con el tópico me voy a dedicar al punto b.

 Las funciones son datos

  En javascript todo es un dato. Algunos datos son ejecutables otros no. Esto plantea una situación completamnete opuesta a la típica implementación de paradigma funcional, donde todo (incluyendo los datos) son funciones.

 En una situación opuesta, y con el soporte que tiene javascript a los tipos de datos (basicamente ninguno) uno tiene un montón de herramientas para poder llegar en pocos pasos al lado opuesto.

  En javascript la analogía se ve muy claramente a la hora de crear una funcion y asignarla a una varible:

var suma = function (a, b) {
   return  a + b
}


 Como se puede ver, suma es una variable y contiene una funcion, por lo que es un dato.
 Como buen lenguaje orientado a datos, los datos se pueden pasar por parametro, con lo que tenemos la libertad de hacer con las funciones lo que querramos. Lo unico importante es asegurarse de que lo que vamos a ejecutar sea una funcion y no un dato.

 ¿Y que ventajas de funcional puedo llevar a javascript?

  Bueno, hay varias ventajas que se pueden pensar y que voy a enumerar en adelante y que voy a ir explayando en varios articulos. Hay otras que no voy a nombrar por que bue, no tiene sentido (como el sistema de tipos de haskell) y otras que por ahora no se me ocurre como hacerlo sin asesinar un gatito a sangre fría.
  • Lazy evaluation (Evaluacion perezosa)
  • Lambda expressions (Funciones anonimas)
  • Currification - Partial Application (Aplicación parcial y currificación)
  • Highorder functions (Funciones de orden superior)
  • Monads (Mónadas -- esto no estoy seguro de que pueda hacer esto sin matar gatitos =P )

lunes, 26 de diciembre de 2011

Mixins y javascript

Para terminar el día del blog (ahora paso a hacer catarsis en otro blog) voy a tirar un par de ideas de compartimiento en javascript.

 Antes que nada voy a remarcar que escucho mucho 'javascript es una mierda' 'javascript no es orientado a objetos' y otras paparruchadas.

Javascript no es una mierda, la mierda es tener que programar una pagina y que se vea bien en internet explorer 6.

A javascript lo unico que le agregaría para orientación a objetos seria la palabra clave object para no tener que definir un objeto con function. Pero no me pondría a hablar de forradas como clases, herencia y eso, después de todo es un lenguaje orientado a objetos con otras forma de armado de objetos, mas manual si, pero mucho mas poderosa.


 Empecemos un poco por, ¿Por qué existen las clases?

Simple, tengo un monton de objetos que van a tener el mismo comportamiento, defino una plantilla y después los creo creandolos a partir de esta plantilla.

Si nos ponemos a pensar que lo importante en la orientación a objetos son los objetos, entonces en seguida salta a la luz que la clase es una forma de programar menos en ciertos contextos, es una forma de clasificar y ordernar conocimiento que tira una linea fuerte obvia y unidireccional: un objeto puede ser de solo una clase (bajo la idea original de clases) y en general esta clase esta muy relacionada con la clasificación que tiene esta 'idea' en el contexto de nuestro negocio.

>> y entonces... la herencia? 
>> la herencia es para poder compartir aun mas código, y para mantener la clasificación en varios niveles, permitiendo mejores abstracciones que las que daría una linea tan dura como ser una clasificación única. (por ejemplo, si solo puediera tener una clasificación no se me ocurriria pensar en la clase animal domestico, iria directamente a tener las clases perro y gato) 


>>Pero javascript no tiene una buena forma de ordenar y compartir codigo
>> Eso lo decís por que estas pensando en clases cuando debieras estar pensando en compartir código.


Hace algunos años apareció la idea de traits / mixins. En lineas generales se trata de compartir codigo entre distintos objetos / clases (segun approach) a un nivel menos estricto que el de clase, permitiendo otras figuras de clasificación que solo el jerarquico de un padre a n hijos (como propusiera en su momento la herencia multiple sin buen recibimiento por la paja mental de los diseñadores de lenguaje a la hora de pensar en la resolución de mensajes).

Probablemente después me cope y haga un articulo para este tema puntual, ahora mismo voy a suponer que lo tienen al menos de oido. Sino busquen por google o esperen a mañana o pasado que escriba y lo suba.

Aca les dejo una idea de mixin en javascript


function BaseComponentMixin (object) {
         object.log = function (message) { console.log (message); };
         object.renderOver = function (componentId) {
                                 $("#"+componentId).append(object.getHtml());
         };
         object.getHtml = function (){
                                  alert("El objeto mixeado debe implementar getHtml()");
        };
}

function HtmlExample (object)  {
       object.getHtml = function () { return "<b> hola mundo </b>"; } ;
}


function  Componente () {
        BaseComponentMixin(this);
        HtmlExample(this);
}

var comp = new Componente();
comp.log("hola");
comp.renderOver("unIDdeDiv");



Que ganamos con esto? Ahora tenemos codigo ordenado por cierta 'habilidad' y podemos organizarlo en mas formas que solo clases. Eso nos permite reutilizar mas código y llegar a abstracciones mas locas que en un codigo sin orden y que en un codigo con un orden demasiado estricto.



>> pero.. es javascript, para que me quiero romper tanto la cabeza? es solo la pantallita
>> Si bueno, la pantallita te puede traer muchos problemas y mucha repetición de código. Tambien hay que tener en cuenta que los sitios evolucionan a ser de una sola pagina por lo que ya no es mas un poquito de javascript para animar los menues, sino que tambien necesitamos java para el comportamiento que ya no va a generar el servidor.
>> Bue.. no se.. igual yo voy a seguir haciendo clases aunque sean mixins
>> No seas pelotudo, usa los mixins como mixins y las clases como clases. No acotes tu pensamiento a la costumbre y no pronuncies opiniones tan cerradas sin haber probado si quiera una vez lo que vas a críticar.




Finalmente si sos usuario de Javascript por ahí te hace ruido que en el mixin haya usado objeto.selector = function ().... en vez de hacerlo vía objeto.Prototype.selector, la razón por la que lo hago así es por que me gusta la posibilidad de elegir que objetos estan mixineados y que objetos no.