domingo, 5 de febrero de 2012

Pizza de molleja

   Ayer después de bastante tiempo volví a hacer pizza casera. Para agasajar a un@s amig@s y compenzar que no pudimos comer pizza de molleja en Rosario (hogar de la pizza de molleja) decidí hacer mi versión de semejante delicia.

   No voy a explicar como se hace la masa de pizza, eso abunda por inet y sino quieren hacerla, prepizza.

   Para una pizza:

    1 molleja
    3 cebollitas de verdeo
    1cda de queso blanco
    1 vasito de whiskey o ron
    Aceite 

    Desgrasar la molleja (Muy importante, como la vamos a saltar toda la grasa que quede va a ir a la pizza. Y es mucha grasa)
    Cortar la molleja en pedacitos chiquitos de entre medio centimetro y un centimetro.
    Cortar en juliana las cebollitas de verdeo.
    Poner en una sartén o wok aceite y poner a calentar
    Saltar primero la cebollita de verdeo, después de haya largado toda la humedad, agregar la molleja. Saltarla hasta que este dorada. Agregar el vasito de whiskey o ron (si te cabe acercale un fosforo y divertie flambeando)
     Una vez que haya reducido el whiskey o ron agregarle la cucharada de queso blanco. Revolve hasta que quede bien diluido. Apagá y dejá que se enfríe.

     Listo, a la prepizza le pones una buena salsa de tomate bastante queso y arriba la molleja. Guarda que es pesadísima esta pizza.

Polvora Negra

Les dejo aca una copia de la receta de la conocida polvora negra.

Sepan que hagan lo que hagan con esta información es bajo su estricta responsabilidad.

Antes de comprar los ingredientes les recomiendo mucho que inviertan en seguridad: Guantes gruesos, antiparras que no dejen pasar aire, barbijo o respirador con filtro para orgánicos, un overol de algun material grueso resistente y que cueste encender.


Ingredientes para 100 gramos de polvora negra:

Nitrato de sodio o de potasio (75 g.)
Azufre (10 g)
Carbón vegetal (15 g)
Agua destilada

Equipo
Bolsas de plástico
Plato hondo de barro o madera
Un matraz de 300 a 500 ml
Fuente de calor (mechero bunsen)

1. Coloca una pequeña cantidad del nitrato sódico o potásico en el plato hondo y
muélelo a un muy fino polvo. Haz esto a todo el nitrato de sodio o de potasio, y
almacénalo en una de las bolsas de plástico.
2. Has lo mismo con el azufre y el carbono, almacenando cada producto químico en
bolsas separadas.
3. Coloca todo el nitrato de sodio o de potasio ya molido en el matraz, y agrégale
suficiente agua hervida para que todo se humedezca.
4. Agrega el contenido de las demás bolsas de plástico al nitrato de sodio o de potasio,
y mézclalos bien durante 15 minutos por lo menos. Has esto hasta que ya no haya más
azufre ni carbono a la vista, o hasta que la mezcla quede completamente negra.
5. Coloca el matraz a la luz directa del sol. La luz del sol es la mejor manera para secar
la pólvora negra, debido a que éste nunca la sobrecalienta como para hacerlo arder, solo
la caliente lo necesario para evaporar el agua.
6. Raspa la pólvora negra fuera del matraz, y almacénala en un contenedor seguro. Un
contenedor de plástico seria realmente seguro. Nunca guardes pólvora negra en una
bolsa de plástico debido a que las bolsas de plástico están propensas a generar
electricidad electrostática, lo que podría hacer estallar la pólvora negra.



En la semana les digo donde conseguir nitrato de potásio, que en teoria se consigue casas de botánica.

No sean boludos, no hagan huevadas de las que se puedan arrepentir, tengan mucho cuidado cuando hacen esto, diviertanse y aprendan.

Sobre IDEs y Herramientas

   Hace poco tuve una discusión bastante pelotuda con un amigo sobre si Vim es mejor que Eclipse o no, discusión que terminó en boludeces retóricas y cero aporte a algo, como medirse la pija pero con IDE's (Super triste, super foreveralone).
 
  Eso me lleva a analizar sobre las discusiones sobre IDEs y sobre los IDEs mismos.

  ¿Qué es un IDE?
   IDE es una sigla que significa Integrated Development Environment. O sea, Entorno integrado de desarrollo.

  ¿Cuál es su función? 
   Las tecnologías no evolucionan y aparecen de una manera realmente sistémica. Aparecen mas bien cuando son necesarias (sobre todo en el ámbito industrial). Eso hace que no tengan mucha consistencia las distintas herramientas que se utilizar para el desarrollo de software. Eso hace necesario que haya herramientas que integren estos mundos muchas veces distintos y faciliten tareas repetitivas y tediosas y disminuyan considerablemente la curva de aprendizaje a cubrir necesaria para comenzar a utilizar una tecnología. Un ejemplo icónico es Maven en el mundo de Java o derivados (groovy, scala, etc)
 
 ¿Cómo elegir un IDE? 
   Es muy importante no ponerse ninguna camiseta. Si se puede nunca ponerse una camiseta, excelente, sino por lo menos cuando se usa el sombrero crítico. No hay un Microsoft es una garcha, java es una mierda, o lisp es una genialidad o aguanten las db relacionales.

  Hay dos tipos de criterio a satisfacer para elegir: lo colectivo y lo individual.

  Lo colectivo
    No hay que olvidarse que el software contemporaneo es en general muy grande para que lo desarrolle una sola persona. Así que se suele trabajar en equipo.
   En los distintos lenguajes hay distintas convenciones, cada persona tiene distintos gustos en la forma de codear y cada proyecto tiene distintas herramientas para el control de versión.
   En este aspecto entonces, yo, tengo muy en cuenta el auto formateo de código y la capacidad del IDE para dejarme configurar el formateo de código como definimos con el equípo. De esta manera yo programo como se me cante a mi. Despues auto formateo como se convino y listo.
   También influye bastante para mí el saber que cosas cambie y poder hacer comparativas rapidas con versiones anteriores para los momentos de duda. Me es imperativo switchear lo minimo posible por que pierdo la concentración y me pongo a boludear.

En lo individual
 
   En lo individual me interesan varias cosas que puedo diferenciar entre funcionales y técnicas

   Funcionales  (que me gustaría que haga por mí)

       Lo mas importante para mí en este caso es lo que mas suelo hacer: browsear código. No me gusta perder tiempo buscando en que archivo esta cierta clase o cierto tipo o cierta función. Bastante con convivir con el hecho de que estoy programando en archivos.

     Después me importa en casi igual medida la integración con los tests dado que suelo programar usando la idea de TDD, para mí es muy importante esta forma de integración.  Poder correr los tests, saber donde falla cada test y por que y que relación tiene cada test con cada parte del código sin tener que recordar de memoria todo lo que hice hace una semana (ni hablar de un mes o dos años).

     Después me importa en casi igual medída tambien la capacidad de refactor y generación de código automático (esto es muy cierto para mi en java, y en menor medida en lenguajes menos burocráticos). Necesito poder generar esqueletos de código a partir de mis tests hechos antes que la funcionalidad, eso me permite mantenerme en la misma linea de pensamiento sin tener que pensar en cosas como 'tengo que crear un archivo'.

     Después en menor medida la predicción de código (la listita de mensaje aparece cuando ponés punto, o el token de mensaje pertinente). Esto tiene bastante importancia, permite que uno se abstraiga de implementaciones y de largas documentaciones. Sobre todo cuando los nombres de mensajes están bien puestos.

    Después la integración de herramientas terceras como software de gestión y construcción de proyectos , editores copados de xml, integración con servidores, tanto para deployment como para monitoreo. Muchos de estos softwares son no triviales para empezar a usar, y es una cagada perder el tiempo aprendiendo a usar maven por ejemplo, cuando podría uno sacarselo de encima y preocuparse por lo importante: las reglas de negocio. Es cierto que uno no puede evitar para siempre aprender estas tecnologías, pero al menos puede distribuir el aprendizaje en el tiempo.

   Después en menor medida snipets típicos de código, como un for, una clase, un html, etc.

   Todo esto, claramente tiene que estar resuelto agilmente, eso implica shortcuts. Es muy importante que haya shortcuts, mas intensivos sobre los primeros items de la lista y en el resto pueden ser en menor medida.

  Ténicos

    Bueno, en este caso, es de mayor importancia no mear afuera del tarro. Tiene que funcionar todo lo necesario dentro de la misma computadora, por lo que dependiendo de los recursos disponibles, lo que podamos elegir y lo que se pueda explotar.



  Entonces

    Es muy importante saber que dependiendo de los lenguajes que uno use, cuan nuevos y poderosos sean, cuanta metadata proporcionen, etc, se puede pensar en distintos niveles de herramientas. Así, mientras para lenguajes tipados el refactor automático puede ser trivial, para otros lenguajes como python, un rename de por sí ya es un desafío realmente complicado. Lo interesante es que se compensa en la versatilidad  y sencillez del lenguaje.

   Otros lenguajes como Scala o Haskell, son sencillos, versatiles y tienen una gran cantidad de metadata, pero son o muy nuevos o muy poco usados, por lo que hay menos herramientas. Y otros lenguajes como Smalltalk no tienen mucha meta data par dar, pero por las caracteristicas de la forma de ejecución esto es mas sencillo o no.


  Cual es la papa

    Creo que lo mas importante es que te sientas cómodo con lo que usas. Si no te sentís comodo, probá otra herramienta y así. Cada tecnología puede hacer que necesites otro IDE.
    Por razones obvias, no te pongas la camiseta. Hay que tener muy en cuenta que si no fuese por Visual Basic, ese horrendo producto de esa horrenda compañía, hoy por hoy tal vez no habría IDEs.
   
   Yo mientras codée en Java, Scala, Javascript con GAE o Android voy a seguir con eclipse por que me dá la maquina y por que pese a que el soporte de Javascript es una garcha, en los otros es sobresaliente en todos los aspectos que a mi me importan.

   Al final, elegir un IDE es como elegir cualquier otra cosa. Comodidad y sentido común. 

lunes, 30 de enero de 2012

Pechuguitas rellenas agridulces

  Hace tiempo que no las hago por el calor. Pero es algo que mas o menos estandarice ya como para pasarlo como receta.

   Me gusta mucho probar distintas mezclas a la hora de hacer pollo. Sobre todo cosas con limón (pese a no ser este el caso). El tema es que alguna vuelta vine a casa del laburo y pensé 'que ganas de comer yakitori', pero claro, es un quilombo, tenía que buscar una receta y después ir al supermercado y rogar encontrar todos los ingredientes cerca de casa (que casualmente esta lejos de cualquier barrio chino). Entonces pensé, 'ya fué, hago la mía, en definitiva quiero algo de pollo agridulce o algo así'. Así me fui al super y compré

Miel,
Salsa de soja,
Salsa picante (Tabasco puede hacer el truco)
Tomates secos
Queso fresco
Cebollita de verdeo
Papel aluminio
Supermas de pollo.


Primero y antes que nada hay que hidratar los tomates secos. Yo suelo ponerlos en agua caliente con un poco de vinagre así  se hidratan rapido y quedan acidos. Pero haganlo como les guste mas.

Después hay que hacer la salsa. Es bastante sencilla, en una cacerolita ponés bastante salsa de soja, ponele un quinto o un cuarto de botellita de esas medianas. Cuando levanta un poco de temperatura mandas una buena cucharada de miel y tanta salsa picante como te guste. Revolves hasta que la miel quede bien disuelta. Sacas la olla del fuego.


Abris las supremas  (te recomiendo que la abras y le saques un poco de su relleno de pollo como si fueses a hacer un sanwich y le sacases la miga al pan). Lo que te queda de pollo en la mano lo saltas en aceite con la cebollita de verdeo picada y los tomates secos tambien cortados. (Vale agregar lo que quieras, como panceta, espinaca saltada, brocoli, etc)

Ahora extendé un buen corte de papel aluminio, ponele la salsa, pones arriba la suprema abierta. Poné el relleno y mezclalo con queso fresco. Cerras la suprema, le pones mas salsa arriba y cerras todo bien con el papel aluminio. Eso lo mandas al horno moderado unos 30 - 40'. Cuando este cocido, abris el paquete de aluminio y lo dejas dorar un rato si te gusta dorado.

Presentación :P: Lo ponés en un plato (obvio no?), con el resto de la salsa y algo verde, ensalada de rucula, brocoli, esparragos, ensalada de espinaca cruda, de lechuga con cebolla y mostaza, etc etc.

Si bien tiene su preparación, no es tan complicado como suena, de trabajo real seran 20' y el resto es poner una alarma e irse a duchar o a ver un capitulo de algo.

Como ya dije antes, no se atengan a la receta, es una idea, muten todo y disfruten de una buena comida :)

domingo, 29 de enero de 2012

Bootstrapping languages

 Ya me estoy sintiendo incomodo por que vengo citando bootstrapping hace varios posts o en un comentario y en general no es un termino conocido. Así que voy a agregarlo al blog como reseña para que se terminen de entender las huevadas que diga. Así que voy a tirar dos versiones, una explicativa onda charla de bar nerd  y otra para tu vieja. Les debo la formal, no encontré ninguna digna de mención, y toda la paja hacerla yo.

Acá entre nos

En terminos generales en lo que es computación asociamos bootstrap o boot o bootstrapping con el inicio del sistema operativo. Hablamos tranquilamente de 'esta booteando' a veces sin saber bien por que.

La metasfora esta relacionada con las botas, por eso boot. Parece que las botas largas (yo nunca use botas, así que no se si se seguira usando) tenían 'bootstraps' un cacho de tela o simil que servia para hacer mas fuerza y poder calzar la bota. O sea, un punto en el que hacer fuerza para poder empezar a usar las botas! Un punto de arranque :).

Tiempo despues la idea se extendio a procesos autocontenidos, despues de todo el bootstrap de la bota tiene algo muy particular: es parte de la bota.

   Bla bla. Al final, en la jerga de compiladores se tomó como la idea de punto de arranque hablando de empezar un lenguaje a partir de otro lenguaje.

   En principio el siginificado era crear un lenguaje de alto nivel a partir de otro de alto nivel. El unico lenguaje considerado de bajo nivel real es el lenguaje de maquina (PLC, assembler, etc).

   Luego paso a incluir que el compilador este escrito en el mismo lenguaje self-hosting compiler, lo cual es una generalización. Yo en general lo cito cuando hablo de un lenguaje nuevo con poca personalidad o trayectoria y basado en otro lenguaje de alto nivel, o bien cuando uso un lenguaje demasiado técnico (cosa que trato de no hacer).



Para tu vieja

A tu vieja decile que se trata de hacer mejores pinzas usando pinzas.
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 :).

El futuro

Aca les dejo otro video que es sobre la evolución de haskell y por que funcional, bajo la concepción de haskell, es necesariamente el futuro.

Excelente presentación y explicación de nociones básicas de haskell y del paradigma.

Temporally Quaquaversal Virtual Nanomachine Programming In Multiple Topologically Connected Quantum-Relativistic Parallel Spacetimes... Made Easy!

Post de recien llegado y un tanto ebrio :D.Aca les dejo una presentación brain-melting.

Se trata de un chabon que explica como aplicar mecanica cuantica con la teoria de la relatividad, composicion molecular y uala :D super velocidad de procesamiento con la idea de chicle tiempo. Muy pero muy fumado. En perl.

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

Alquimia - Brownies

Si si, estuve haciendo brownies hace unos días y como este blog tambien es de alquimia decidí mecharlo aca también para que vean que el criterio y todas las demas combinaciones de procesos no sirven solo para programar :D , asi como el arte y las ganas de hacer algo "rico"  no se debiera acotar solo a la cocina.

Para preparar unos buenos brownies necesitamos
  • Cacao amargo 100 g
  • Manteca 100 g
  • Azúcar 180 g
  • Huevos 4
  • Harina 0000 100 g
Fundir la manteca a fuego muy suave o a baño María, mezclarla con el cacao (ojo que es un quilombo si no lo hacen despacio) Despues agregar el azúcar y los huevos, ahi le das duro hasta que quede bien espumosa la mezcla. Por último, agregas la harina tamizada.

Va a quedar una maza bastante liquida, la pones en una fuente enmantecada de 20 x 30 aprox ( lo importante es que quede algo de 1cm de alto de masa en toda la fuente). Despues al horno (que debieras poner a calentar antes de empezar a cocinar) , temperatura 180° aproximadamente entre 15 y 20 minutos, mas cerca de 20. Sacas del horno (claramente apagar nada mas no alcanza) y los cortas ahi antes de que se enfrien, sin desmoldarlos. Una vez frios los sacas y a una lata (o a la panza)

No sigas nunca una receta al pie de la letra, ponele onda, nueces, almendras, sacale las cosas que no te cierran. La cocina es expresión :D.





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.