miércoles, 12 de marzo de 2014

Typescript, nodejs, generadores, harmony, q, taskjs y autocompletado

Introducción:

Últimamente he estado probando y experimentando con algunas tecnologías interesantes: virtualización a nivel de sistema operativo: chroot / lxc / docker. He estado experimentando también con heroku y monhohq. Y hace tiempo estuve experimentando con node-webkit y cross-walk y traceur compiler.

Este post lo escribo a poco de que salga nodejs 0.12, y typescript 1.0 y tras haberle dado otra oportunidad a dart en su versión 1.1 con muchas expectativas y con un resultado algo decepcionante. Con generadores implementados en v8 y disponibles en node.js a partir de la 0.11, y con task.js y q de por medio, habiendo adquirido mucha más experiencia con promesas, señales y streams, y con las promesas ya propuestas en el draft de harmony.

sábado, 1 de junio de 2013

Haxe3 + Starling + Continuation + Air

La metaprogramación de haxe es tan potente que permite modificar el AST en tiempo de compilación directamente desde haxe (código que se ejecuta en tiempo de compilación para modificar el AST de la compilación). Esto permite que se puedan crear pseudolenguajes, o que puedas programar en haxe y generar shaders de opengl. Pero lo que me gustaría comentar ahora es el proyecto continuation. Básicamente convierte código lineal en código asíncrono añadiendo cierta metainformación a la clase y a los métodos que lo van a usar de forma que se preprocese el código y se genere código asíncrono.

Desde Haxe3 además se pueden cargar archivos .SWC fácilmente.



jueves, 30 de mayo de 2013

Promesas

La programación asíncrona en JavaScript y especialmente en Node.JS ha estado basada principalmente en callbacks. Le pasas a la función que estás llamando un callback que ejecutará cuando termine de procesar lo que tenga que hacer. Esto llevaba a una pirámide de código inmanejable. La pirámide de código hace que procesar código asíncrono con bucles, o flujo condicional acabe siendo tedioso, además de ser muy propenso a errores ya que la gestión de errores se suele hacer pasando un parámetro con un posible error y otro parámetro con un valor. function(err, value) { }. Si se lanzan excepciones que no se gestionan dentro del código, se dejan de llamar a los callbacks esperados y se rompe el flujo; con lo que hace que todo sea extremadamente frágil.

Promises/A, Q, y asíncrono lineal con generadores

Con las promesas cambiamos el flujo. De funciones de tipo function myAsyncFunction<T>(...params:any[], done: (err:Error, value:T) => void) (que tienen un callback para seguir con el flujo y devuelven void) pasamos a funciones del tipo function myAsyncFunction<T>(...params:any[]) : Promise<T> (que ya no tienen el callback y lo que hacen es devolver una Promise).
Una promise es algo similar a un Event Listener, solo que no podemos hacer un dispatch y únicamente nos podemos registrar a un evento: obtener valor y obtener un error.

interface IDeferred<T> {
    resolve(value?: T): void;
    reject(err: Error): void;
    get promise(): IPromise<T>;
}

interface IPromise<T> {
    then(onResolved: (value: T) => void, onError?: (err: Error) => void, onProgress?: () => void) : IPromise<T>;
}

Básicamente cuando queremos convertir un código funcionando con callbacks tradicionales al sistema de promesas, lo que hacemos es generar un Deferred, que contiene los métodos para continuar el flujo con un valor o con un error y devolvemos la promesa vinculada al deferred, que únicamente tiene un método then, que ejecutará los callbacks que le pasamos cuando la llamamos cuando el deferred se resuelve o se rechaza. El método then devuelve otra promesa, que se lanzará cuando se complete el then actual.
De esta forma un método delay/sleep hecho con promesas quedaría así:

function sleep(timeInMilliseconds: number) : IPromise<any> {
    var deferred = new Deferred();
    setTimeout(function() {
        deferred.resolve();
    }, timeInMilliseconds);
    return deferred.promise;
}

sleep(1000).then(function() {
     alert('1 second passed');
});

Task.js permite utilizar los generadores bidireccionales de Harmony y el funcionamiento de las promesas para hacer una programación de procesos/tareas/actores/green threads/minithreads  cooperativos/multitarea no preemptiva. Esto se consigue pausando la ejecución y mandando/"generando" desde el generador una promesa. El gestor de tareas se suscribe a la promesa, y retoma el generador cuando la promesa se resuelve o se rechaza; mandando un valor de vuelta al generador, o generando una excepción dentro del contexto del generador.

martes, 28 de mayo de 2013

Generadores

Hace poco he escrito sobre que V8 ya soporta generadores en el bleeding_edge y que se pueden usar ya desde node con las últimas versiones inestables y que con eso se podrá escribir código asíncrono lineal desde javascript (sin anidar millones de funciones).

¿Qué son los generadores?

Enlace a la wikipedia: http://en.wikipedia.org/wiki/Generator_(computer_programming)

Básicamente un generador es como un iterador pero implementado como una función que va generando valores que otra función consume. Por ejemplo, podemos tener una función que genera un listado infinito de números primos. Podríamos hacer una función que generase un array con un montón de números primos, pero además de que ocuparía bastante memoria si generamos una lista grande, la lista sería limitada. Hay lenguajes que soportan la interfaz Iterable que permite crear una clase con un método que se va llamando en cada paso.

Async: código asíncrono lineal en javascript (node.js v0.11.2 y cliente con traceur) (¡por fin!)

Introducción:

Nota: Voy a escribir una serie de artículos sobre generadores y código asíncrono lineal para los que no sepan de qué va todo esto.
Update: Generadores.

Recientemente me he enterado de que ya han implementado generadores en el bleeding_edge del motor de javascript de google V8. ¿Qué implicaciones tiene esto? Código asíncrono lineal, limpio y elegante en el servidor sin cosas raras.

La tarea del proyecto V8:
https://code.google.com/p/v8/issues/detail?id=2355#c22

El blog del tío que ha hecho la implementación:
http://wingolog.org/archives/2013/05/08/generators-in-v8

Así que esta tarde, nada más llegar de trabajar, me he puesto manos a la obra y me lo he montado todo para empezar a usarlo.

viernes, 24 de mayo de 2013

Versionado, gestión y vinculación de tareas y deploy automático con #bitbucket, #git, #jira

Hoy me gustaría explicar cómo tener un entorno de desarrollo óptimo para freelancers o grupos pequeños de trabajo por menos de 10€ idealmente con un servidor dedicado o uno virtualizado.


Bitbucket

Lo primero que necesitamos es una cuenta de Bitbucket. Bitbucket permite alojar repositorios GIT (además de mercurial) como podría hacer Github, pero tiene la peculiaridad de que nos permite tener repositorios privados ilimitados de forma gratuita. La única limitación que tiene es el número de usuarios que pueden acceder a tus repositorios: que empieza siendo 5 y que puede subir hasta 10 con referers. Los proyectos tienen también de forma gratuita, wiki, un sistema de tareas y de otro revisión de código.

Jira 6

En Atlassian venden el Jira 6 autogestionable para 10 usuarios por 10$. Como Bitbucket ya limita a 5-10 usuarios, posiblemente con 10 usuarios también haya suficiente al menos para llevar un tracking interno de tareas.

TortoiseGIT

El TortoiseGIT es la opción por excelencia para usar GIT desde windows.

domingo, 3 de marzo de 2013

atpl.js, mi twig para node.js, completado #nodejs #twig

Hoy he terminado mi proyecto atpl.js.

atpl.js (Advanced TemPLates) tenía como intención implementar completamente el proyecto de sistema de templates Twig, pero en vez de para PHP, para Node.JS.
Tengo constancia de un par de proyectos que pretendían/pretenden hacer eso mismo: swig y twig.js.



Historia:
El proyecto lo empecé hará cosa de un año, pero decidí dejar algo de tiempo a los proyectos swig y twig.js para ver si maduraban e implementaban twig de una forma correcta. Para mediados de diciembre de 2012, con TypeScript recién salido del horno, y viendo que swig y twig.js no habían madurado lo suficiente, decidí retomarlo en TypeScript. Y tras haber trabajando en el proyecto de forma intermitente desde entonces hasta día de hoy, he implementado todas las funcionalidades de Twig de las que tengo constancia.