Resoluciones del Nuevo Mes: Julio 2015

Un nuevo mes comienza, y es tiempo de escribir mis nuevas resoluciones, y revisar las del mes pasado:

– Dar una charla sobre Meteor [completo] ver presentación
– Escribir posts sobre JavaScript e Artificial Intelligence [pendiente]
– Mejorar ClojJS [pendiente]
– Agregar soporte de NPM a ClojJS [pendiente]
– Continuar trabajando en SparkSharp [pendiente]
– Comenzar proyecto de mensajes en C#, a la Apache Camel [completo] ver repo 
– Mejorar Liqueed Project, programar kudos [pendiente]
– Mejorar Templie, template engine en Java [pendiente]
– Mejorar BScript, intérprete tipo Basic en C#[pendiente]
– Continuar trabajando en OStore [completo] ver repo
– Continuar trabajando en SharpMongo [completo] ver repo

Estuve trabajando también en:

– Comezar ObjectChannel, serialización de objetos en C# [completo] ver repo
– Compezar ejemplos de Elixir [completo] ver repo
– Dar una charla sobre Machine Learning [completo] ver presentación
– Comenzar NRiak, key-value store en JavaScript/NodeJS [completo] ver repo
– Comenzar ejemplos de Android [completo] ver repo

Las resoluciones de este mes:

– Continuar trabajando en SparkSharp
– Continuar trabajando en BScript
– Continuar trabajando en DynApp
– Continuar trabajando en TDD
– Continuar trabajando en SharpMongo
– Continuar trabajando en NRiak
– Continuar trabajando en Elixir samples
– Continuar trabajando en Android samples

Me diviegto como logco 😉

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Posted in C#, Java, JavaScript, NodeJs, Proyectos Open Source | Leave a comment

Sobre Machine Learning (1)

El año pasado toqué el tema de Inteligencia Artificial con JavaScript, y me gustaría ahora comenzar a comentar sobre un tema relacionado, que está digamos “de moda” por estos tiempos. Es el tema de Machine Learning, aprendizaje automático. También estoy preparando una charla, y parte de ese material que estoy investigando quiero volcarlo en esta serie de posts.

Es un tema que ya tiene décadas de desarrollo. Lo que veo al revisitarlo y enterarame de los últimos avances, es que ha cambiado su definición común. Veamos una definición. Leo en el curso de Coursera:

https://www.coursera.org/course/ml

Machine learning is the science of getting computers to act without being explicitly programmed. In the past decade, machine learning has given us self-driving cars, practical speech recognition, effective web search, and a vastly improved understanding of the human genome. Machine learning is so pervasive today that you probably use it dozens of times a day without knowing it. Many researchers also think it is the best way to make progress towards human-level AI. In this class, you will learn about the most effective machine learning techniques, and gain practice implementing them and getting them to work for yourself. More importantly, you’ll learn about not only the theoretical underpinnings of learning, but also gain the practical know-how needed to quickly and powerfully apply these techniques to new problems. Finally, you’ll learn about some of Silicon Valley’s best practices in innovation as it pertains to machine learning and AI.

Esa definición es la que yo tenía en mente desde el siglo pasado: hacer que las computadoras actuaran de alguna forma sin haber sido explícitamente programadas para ello, tal vez con el agregado de ir mejorando en un tiempo inicial en la tarea (que no sea simplemente conducta aleatoria).

Ahora bien, hay otras definiciones que involucran datos. Veamos la definición en el artículo actual de la Wikipedia:

http://en.wikipedia.org/wiki/Machine_learning

Machine learning is a subfield of computer science[1] that evolved from the study of pattern recognition and computational learning theory in artificial intelligence.[1] Machine learning explores the construction and study of algorithms that can learn from and make predictions on data.[2] Such algorithms operate by building a model from example inputs in order to make data-driven predictions or decisions,[3]:2 rather than following strictly static program instructions.

Si bien es la definición más en boga en estos tiempos (usar datos como base del aprendizaje) no es la única, al menos en la historia de las ciencias de la computación. Lo que pasa es que vivimos en una época donde aparece el Big Data, y el Machine Learning sobre eso, e incluso en tiempo real, ha motivado varias implementaciones, a partir de “startups” y otros emprendimientos.

Veremos en los próximos posts algunos ejemplos históricos de Machine Learning, que no involucraban datos, y luego sí, nos sumergiremos en el actual estado del arte, con datos, aprendizaje supervisado, no supervisado, distribuido y en tiempo real.

Mientras, algunos enlaces y otros posts relacionados en inglés:

https://ajlopez.wordpress.com/category/machine-learning/

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Posted in Aprendizaje Automático, Inteligencia Artificial | Comments Off on Sobre Machine Learning (1)

Resoluciones del Nuevo Mes: Junio 2015

Es tiempo de la revisión de mis resoluciones de mayo, y escribir nuevas para este mes de junio:

– Mejorar ClojJS [pendiente]
– Agregar soporte de NPM a ClojJS [pendiente]
– Escribir posts sobre JavaScript e Inteligencia Artificial [pendiente]
– Dar una charla sobre Meteor [parcial]
– Preparar charla sobre Clojure o ClojureScript [parcial]
– Mejorar BScript [pendiente]
– Mejorar AjErl, distribuido [parcial] ver repo
– Mejorar Proyecto Liqueed, implementación de kudos [completo] ver repo

Tambien estuve trabajando en:

– Comenzar SparkSharp, Apache Spark-like in C# [completo] ver repo
– Mejorar SharpMongo, MongoDB-like in C# [completo] ver repo
– Mejorar OStore, objetos en memoria, JavaScript/NodeJS [completo] ver repo
– Mejorar PythonSharp, intérprete Python en C# [completo] ver repo
– Mejorar RedPython, compilar Python a C usando JavaScript/NodeJS [completo] ver repo

Mis nuevas resoluciones para junio:

– Dar una charla sobre Meteor
– Escribir posts sobre JavaScript e Inteligencia Artificial
– Mejorar ClojJS
– Agregar soporte de NPM a ClojJS
– Continuar trabajando en SparkSharp
– Comenzar proyecto de mensajes en C#, inspirado en Apache Camel
– Mejorar el Proyecto Liqueed, implementación de kudos
– Mejorar Templie, template engine en Java
– Mejorar BScript, intérprete tipo Basic en C#
– Continuar trabajando en OStore
– Continuar trabajando en SharpMongo

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Posted in .NET, C#, Java, JavaScript, NodeJs, Proyectos Open Source | Leave a comment

El valor de TDD (3)

Anterior Post

En el primer post de esta serie, ya mencioné el tema simplicidad, y di algún ejemplo. Es un tema fundamental para entender TDD (Test-Driven Development), pero parece ser que es uno de los menos entendidos. Así que me permito insistir hoy en el tema.

Una de las cosas hacia las que empuje TDD es a la simplicidad, pero siempre y cuando pensemos alineados con el flujo de trabajo de TDD. Veamos la respuesta a la pregunta:

¿Por qué TDD empuja a la simplicidad?

Por dos razones: como se escriben los tests primero que el código (y muchas veces, se escribe un solo test, y hasta que no se termina de trabajar en ese test, no se pasa a otro), nos conviene comenzar con tests sencillos de expresar su intención, no comenzar por los tests más complicados. Como ejemplo, pueden ver los commits de mi proyecto SparkSharp (ver posts). Ahí tengo que implementar un concepto llamado Dataset, sobre el que aplicar map y reduce. ¿Acaso escribí los tests más complicados primero? No, siguiendo la premisa de ir por pasos de bebé (“baby steps”), fui planteando los casos más sencillos primero. Por ejemplo, escribí primero tests para Datasets que se alimentan de items enumerables en memoria, antes de pasar a Datasets que se alimentan de archivos locales. Y luego, en algún momento futuro, escribiré y haré pasar a verde tests sobre Datasets que se alimenten de datos remotos. Pero como en la vida, el más largo camino comienza con un solo paso. Y otro paso y otro paso y así.

¿Acaso en ese proyecto implementé directamente la API del proyecto original, Apache Spark? No, la idea es ir planteando casos de uso pequeños de la API, dado un estado, llamar a un método, y escribir lo que se espera obtener como respuesta o como cambio de estado. Por ejemplo, en el proyecto original los Datasets se crean con métodos factoría de un Spark Context. Yo no he tenido necesidad de eso en los tests simples que he escrito. Cuando llegue el caso de necesitar eso, por alguna circunstancia concreta, lo haré, haciendo refactor y rediseño. Pero recuernde: no hay que cruzar el puente ANTES de llegar al puente.

Y la segunda razón: TDD nos lleva a resolver el pasaje del test a verde DE LA FORMA MAS SENCILLA. Eso lo tenemos que poner nosotros, la voluntad de implementar código de producción, APENAS PARA que pase el test. Si sentimos que al código de producción le falta algo (por ejemplo “debería controlar que este parámetro no sea nulo”), entonces ESCRIBIMOS el test correspondiente, y luego agregamos la funcionalidad que falta. Si no hay ningún test que pida a gritos la implementación de algo, ese algo NO SE IMPLEMENTA. Primero el test, luego la implementación. De alguna forma, esto lleva a que casi cada línea de código de producción PUEDA SER TRAZADO su origen a algún test. Línea de producción que no nace de un test, es sospechosa.

Corolario: no agrego librerías y dependencias que no necesito para resolver un test. No digo “no agregar Angular”, o “no agregar Hibernate” nunca. Digo: lo agrego cuando realmente los casos de uso planteados (los casos de la API, lo que espero que haga), realmente justifican el agregado de la dependencia. Y van a ver, que gracias a TDD, el agregado de la librería en general no cuesta mucho. Una de las consecuencias del uso de TDD y simplicidad y lo ágil en general, es que el diferir las decisiones no tiene un gran costo, y hasta mejora nuestro diseño porque permite que lo que se agrega se agregue por necesidad real, y no por “cargo cult programming” o porque sea “la mejor práctica”. Recuerden, no hay “mejores prácticas”, sino “mejores prácticas en contexto”. Además, el diferir la decisión tal vez ayudar a decidir, luego de ver mejor los casos de uso, que en vez de Angular necesitamos React, o que en vez de un ORM necesitamos un MicroORM, y así. Permite que nuestro diseño no vaya anclado a una decisión temprana de tecnología.

Veamos ahora un “pecado” que he observado cuando se intenta comenzar con TDD: pensar demasiado por adelantado. Recuerden, los primeros tests tienen que ser sencillos. Por ejemplo, en mi implementación de una especie de OLAP en memoria, MemOlap, ¿acaso pensé todas las estructuras internas de antemano? Para nada. A medida que implementé casos de uso, fui implementado mejor lo que quería hacer, y refactorizando. El software crece así como un organismo, guiado por nuestras ideas y por el ambiente que lo rodea, los tests que vamos incorporando de a poco. Justamente, MemStore fue la semilla para un proyecto real no público, que avanzó mucho más, y hoy está en producción. Y cuando en ese avance se plantearon nuevos casos de uso, o se vió que había que refactorizar algo, se lo hizo, sin mayor esfuerzo. Doy un caso: cuando se llegó a probar el rendimiento con cientos de millones de registros, se vió que algunas operaciones eran lentas. Ahí se hizo refactor, se implementó el recorrido de los items de una forma más eficientes, sin apelar a crear y destruir objetos a cada momento, y gracias a los tests en verde, todo siguió andando. Hasta hubo refactor quirúrgico: llamo así a los que cambian mucho de la implementación. Y al comienzo de tal tipo de refactor pueden quedar muchos tests en rojo. Pero volviendo todo a verde, al final queda un sistema tan estable como al principio.

En gran parte, el bajo esfuerzo de cambio resultó de la simplicidad adoptada hasta ese momento, y la ayuda de los tests ya escritos, que permitieron rápidamente, ante un refactor (cambio interno de implementación) o un rediseño (cambio de la API porque hay nuevos casos de uso a contemplar), darse cuenta en el momento qué se había roto y qué no.

Entonces, no comenzar a pensar ya en el primer test en repositorios, ORM, y contextos de ejecución. Hay que relajarse y volver a plantear el desarrollo del software como juego. Imaginemos que cuanto más tests en verde tengamos, más avanzamos en el juego.

Hacer de cada test, un test sencillo.

Hacer de cada implementación, la más simple para que pase el test.

No agregar algo a la implementación, sin respaldarlo con test.

Y como siempre, la neurona atenta, vermú con papas fritas y good show! 😉

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Posted in Desarrollo Agil, Programacion, Test-Driven Development | Comments Off on El valor de TDD (3)

SparkSharp, Spark in C# (2) Implementando Map y Reduce

Anterior Post

El proyecto está en:

https://github.com/ajlopez/SparkSharp

Como es usual, lo estoy desarrollando siguiendo el flujo de TDD (Test-Driven Development), así que el código va evolucionando a medida que encuentro nuevas soluciones a pequeños casos de uso planteados por los tests. Lo que muestro hoy puede cambiar mañana, al necesitarse en nuevos tests nueva funcionalidad o nuevas implementaciones. Por ejemplo, en el proyecto original de Apache Spark los dataset se crean desde métodos factorías en algo llamado Spark Context. Pero esa funcionalidad todavía no la necesité. Así que por ahora mis tests apuntan a crear simples objetos Dataset, directamente con el operador new, y a consumirlos.

Actualmente, nacida en algún refactor, está la clase abstracta BaseDataset. Parte del código:

public abstract class BaseDataset<T> : IEnumerable<T>
{
    public abstract IEnumerable<T> Elements { get; }

    public BaseDataset<S> Map<S>(Func<T, S> map)
    {
        return new EnumDataset<S>(this.ApplyMap(map));
    }

    public S Reduce<S>(Func<S, T, S> reduce)
    {
        S result = default(S);

        foreach (var elem in this)
            result = reduce(result, elem);

        return result;
    }
    
    // ...

    private IEnumerable<S> ApplyMap<S>(Func<T, S> map)
    {
        foreach (var elem in this)
            yield return map(elem);
    }
    
    // ...
}

Vemos que la implementación de enumerar los elementos que contiene queda delegada a la clase concreta. Pero en el código de arriba dejé la implementación base de los métodos Map y Reduce. Gracias a C#, estos métodos pueden recibir un lamba, o una Func (una función como objeto) como veremos en algún test.

Vean como el ApplyMap usa el yield de C# para devolver cada elemento, y el foreach sólo se vuelve a ejecutar cuando el consumidor del IEnumerable necesita el próximo item. Tanto el uso de lambdas como de yield han simplificado la implementación de estas ideas. Esta es una prueba de lo que se necesita en un lenguaje para cumplir mejor con alguna necesidad. Como digresión, comento que me parece que la historia de C# ha sido bastante acertada, incorporando estas ideas, mientras que en el mundo Java, se ha dado el caso de lenguajes como Scala que, siendo un gran lenguaje, me parece que trata de sumar demasiadas cosas.

No se ejecutan tests sobre la clase abstracta (que de nuevo, vean la historia de commits, nació como un refactor), sino sobre alguna concreta. Siendo EnumDataset una clase concreta (a examinar en próximos posts), sea un test típico del Map:

[TestMethod]
public void MapIncrement()
{
    EnumDataset<int> ds = new EnumDataset<int>(new int[] { 1, 2, 3 });
    BaseDataset<int> mapds = ds.Map(i => i + 1);
    var enumerator = mapds.GetEnumerator();

    for (int k = 1; enumerator.MoveNext(); k++)
        Assert.AreEqual(k + 1, enumerator.Current);

    Assert.AreEqual(3, mapds.Count());
}

Y un test del Reduce:

[TestMethod]
public void ReduceSum()
{
    EnumDataset<int> ds = new EnumDataset<int>(new int[] { 1, 2, 3 });
    var result = ds.Reduce<int>((x, y) => x + y);

    Assert.IsNotNull(result);
    Assert.AreEqual(6, result);
}

Próximos temas: más métodos de BaseDataset, datasets concretos, datasets con clave, etc…

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Posted in .NET, C#, Computación Distribuida, Proyectos Open Source, SparkSharp, Test-Driven Development | Comments Off on SparkSharp, Spark in C# (2) Implementando Map y Reduce

SparkSharp, Spark in C# (1) Primeras ideas

Siguiente Post

En el post de ayer mencionaba el uso de Spark por parte de gente de Medallia. Conocía un poco de ese proyecto Apache, pero hoy me puse a ver la interfaz de programación que tienen, y me pareció interesante reproducir alguna parte en C#.

Ellos trabajan con Dataset, conjuntos de datos que pueden venir, por ejemplo, de archivos locales o distribuidos, y a los que aplican funciones de transformación (Map) y funciones de reducción, obtención de algún valor resultante (Reduce). Los trabajos definidos se pueden correr en varios nodos (tengo que revisar cómo consiguen consolidar la etapa de Reduce final).

Pero para comenzar una implementación en C#, me parece interesante comenzar en pequeño, y como es usual, usar el flujo de trabajo de TDD (Test-Driven Development). Así que ni lerdo ni perezoso, en la tarde de ayer comencé este proyecto:

https://github.com/ajlopez/SparkSharp

Si ven los primeros commits, se siguió la idea de flujo de TDD. Va quedando que los datasets implementan como base a un IEnumerable<T> sobre el que se aplican de forma ordenada funciones Map, Reduce, Split, Take, Skip y otras que vayan apareciendo. Esos datasets pueden ser simples “wrappers” de otros IEnumerable<T> (como un arreglo de tipo T, o una lista), o pueden venir de tomar un texto y partirlo en líneas (ver el TextDataset), o tomar un archivo y procesarlo en líneas.

Todos esos datasets son, digamos, locales, no distribuidos. El próximo paso simple (siempre hay que ir por lo más simple) es exponer un dataset cualquiera para que se pueda consumir ordenadamente de forma remota. Por ejemplo, en un nodo/máquina podemos tener un gran archivo de texto a analizar. Queremos procesar sus líneas. Para esto hoy ya en el proyecto está el TextFileDataset, que procesa las líneas a medida que se van leyendo. Pero se podría implementar un ServerDataset o RestDataset, que sea un “wrapper” sobre ese dataset local, y se exponga para afuera, mediante TCP o una API que devuelva JSON o un simple string via HTTP. Entonces, distintas clases clientes (me imagino RestClientDataset, o ServerClientDataset), podrán consumir esos datos desde nodos remotos, como si fueran datasets locales. En el caso normal, un TextFileDataset expondría sus líneas a los nodos remotos, para que se puedan consumir, pero de una forma controlada: cada línea iría al próximo nodo que pida un item del dataset.

Despues de implementar la exposición de un dataset local como remoto (con ese cuidado de que cada item SOLO vaya a un nodo solicitante, que no se REPITA el proceso de un item entregándolo a DOS o más nodos), implementar la serialización/deserialización (temas ya encarados en AjErl y Aktores), automáticamente comenzamos a tener procesamiento distribuido. Claro que todo esto es el caso feliz: si el proyecto progresa, habrá que contemplar fallas en la comunicación, ingreso y egreso de nodos dinámicamente en el medio del proceso, coordinación/recolección de datos en un Reduce final que consuma resultados parciales de varios nodos, etc.

Pero piano, piano se va a lontano. Por ahora, baby steps, la neurona atenta, vermú con papas fritas, y good show!

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Posted in C#, Computación Distribuida, Proyectos Open Source, SparkSharp | Comments Off on SparkSharp, Spark in C# (1) Primeras ideas

Tech Night en Medallia

El jueves pasado se organizó una reunión en Medallia, Argentina, en Buenos Aires. Pueden ver la empresa global en:

http://www.medallia.com/

y aparte de servicios, tienen un producto donde conectan a una empresa con sus clientes. Eso implica que tienen que trabajar con grandes volúmenes de datos, analizarlos, descubrir patrones y relaciones y hacer análisis de “sentimientos”. Tienen central en Palo Alto California, y desarrollan allá y en Buenos Aires. En otras ciudades, como Londres, tiene soporte, ventas, marketing y esas ‘)cosas que tienen que hacer los mortales que no programan ni se dedican a las matemáticas :-)

No fue una reunión abierta, sino por invitación. Habremos sido como treinta personas, del ámbito del desarrollo de software principalmente, que asistimos y disfrutamos de CERVEZA (sí, ya saben que si voy a alguna reunión no es por el tema, sino por la cerveza ja ja ja), y tragos de bebidas espirituosas (con nombres como C#, Java, y hasta NodeJS, no recuerdo los ingredientes, pero había tequila, jugos de fruta y similares). Luego de la charla técnica que hubo, sé que se zamparon varias pizzas y vieron un evento por televisión, algo así como fútbol, otra de esas cosas que hacen los mortales jaja.

Yo fui invitado gracias a la recomendación inicial de @gabrielsz que está trabajando desde hace unos años en Medallia, desde Palo Alto.

En la charla técnica, presentaron dos desarrolladores de Medallia:

https://www.linkedin.com/in/kreide Kristian Eide
https://www.linkedin.com/in/slicer Thorvald Natvig

La presentación giró alrededor de dos temas: el proceso de datos estructurados, y de datos desestructurados. Conversando con Eide, ví que trabajan mucho con Java, y con Spark, para el procesamiento distribuido (abandonaron Hadoop hace un tiempo parece). También trataron el tema de compilar “queries” sobre los grandes conjuntos de datos que tienen, pero tendría que revisar las tecnologías involucradas. Hay que ver los proyectos públicos de Medallia:

https://github.com/medallia

Es interesante ver el trabajo de

https://github.com/medallia/Word2VecJava

Donde portaron a Java un procesamiento de palabras a vectores, ver los papers relacionados

http://ttic.uchicago.edu/~haotang/speech/1301.3781.pdf
http://papers.nips.cc/paper/5021-distributed-representations-of-words-and-phrases-and-their-compositionality.pdf
http://www-personal.umich.edu/~ronxin/pdf/w2vexp.pdf

Jaja Ideas para portar a C# entonces acá, como Code Kata. Es interesante ver redes neuronales aplicadas en este problema (un tema con el que me encontré hace alredecor de tres décadas y sigue dando vueltas por ahí, van a aparecer en mi serie sobre JavaScript e Inteligencia Artificial y ya apareció en mi GitHub). Hay mucho de “sentiment analysis” al parecer en el trabajo de Medallia, igual comenté que hay poco de real semántica en estos caminos, parece más una correlación de textos que un real modelo del mundo y de la mente. Algo así comenté al final de mi charla en la JSConf Argentina 2014: todos estos algoritmos para reconocer gatos, reconocen miles de gatos, pero no tienen la más pálida idea de qué es un gato. Redes neuronales tiene esa fascinación: produce resultados, y eso es importante, pero no sé si no nos estamos perdiendo algo importante. O quizás sea el camino para una inteligencia artificial fuerte emergente, sólo que hasta ahora estamos en los primeros pasos.

La idea es que Medallia conecte con la comunidad de desarrollo local, y surjan ideas para realizar, dentro del grupo. Ya se formó un Google Groups, y en unos meses se realiza la próxima reunión (más cerveza :-)

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com

Posted in Buenos Aires, Inteligencia Artificial, Java, Programacion, Redes Neuronales, Reunion | Comments Off on Tech Night en Medallia

AjErl Implementando Erlang en C# (2) Expresiones

Anterior Post

Hace un tiempo que escribo de este proyecto, que trata de implementar Erlang como intérprete sobre C#. Veamos hoy una primera aproximación a expresiones. Una expresión es algo que se evalúa dentro de un contexto. Por ejemplo, la variable X, es una expresión que se evalúa dentro de un contexto que diga cuánto vale la variable X, a qué valor está ligada, o que diga que X todavía es una variable sin ligar.

Todas expresiones se escribieron usando el flujo de trabajo de TDD (Test-Driven Development). Quedó, con el tiempo, definida esta interfaz, que al final implementan todas las expresiones:

public interface IExpression
{
    object Evaluate(Context context, bool withvars = false);

    bool HasVariable();
}

El gran método es el evaluar, que puede admitir o no que queden variables sin ligar. También hay un método hasVariable() que indica si una expresión tiene o no una variable. Veamos la expresión más simple, una constante:

public class ConstantExpression : IExpression
{
    private object value;

    public ConstantExpression(object value)
    {
        this.value = value;
    }

    public object Value { get { return this.value; } }

    public object Evaluate(Context context, bool withvars = false)
    {
        return this.value;
    }

    public bool HasVariable()
    {
        return false;
    }
}

El método Evaluate no usa el Context provisto, sino que simplemente devuelve el objeto constante que se proveyó en el constructor al armar esta expresión (todavía no lo vimos, pero las expresiones se agrupan en un árbol de expresiones, que se evalúa recorriéndo sus ramas y hojas).

Una implementación menos trivial es la expresión que evalúa una variable, dado su nombre:

public class VariableExpression : IExpression
{
    private Variable variable;

    public VariableExpression(Variable variable)
    {
        this.variable = variable;
    }

    public Variable Variable { get { return this.variable; } }

    public object Evaluate(Context context, bool withvars = false)
    {
        if (!context.HasValue(this.variable.Name))
            if (!withvars)
                throw new Exception(string.Format("variable '{0}' is unbound", this.variable.Name));
            else
                return this.variable;

        return context.GetValue(this.variable.Name);
    }

    public bool HasVariable()
    {
        return true;
    }
}

Esta vez se usa el contexto. Si la variable no está todavía ligada a un valor, pueden pasar dos cosas: que el Evaluate acepte que alguna variable quede sin ligar, y se devuelve como resultado de la evaluación la variable, o que se dispare una excepción. Vamos a ver que hay ocasiones donde Erlang espera y necesita que una expresión esté completamente evaluada, en el sentido de no contener variables sin ligar.

Les comentaba que todo este código fue implementado siguiendo el flujo de trabajo de TDD. Listo algunos tests abajo para dar constancia. Para expresión constante:

[TestMethod]
public void CreateSimpleConstantExpression()
{
    ConstantExpression expr = new ConstantExpression(10);

    Assert.AreEqual(10, expr.Value);
}

[TestMethod]
public void EvaluateSimpleConstantExpression()
{
    ConstantExpression expr = new ConstantExpression(10);

    Assert.AreEqual(10, expr.Evaluate(null));
}

Para expresión de variable:

[TestMethod]
public void CreateSimpleVariableExpression()
{
    Variable variable = new Variable("X");
    VariableExpression expression = new VariableExpression(variable);

    Assert.AreEqual(variable, expression.Variable);
}

[TestMethod]
public void EvaluateVariableExpression()
{
    Variable variable = new Variable("X");
    Context context = new Context();
    context.SetValue("X", 1);
    VariableExpression expression = new VariableExpression(variable);

    Assert.AreEqual(1, expression.Evaluate(context));
}

[TestMethod]
public void EvaluateUndefinedVariableExpression()
{
    Variable variable = new Variable("X");
    Context context = new Context();
    VariableExpression expression = new VariableExpression(variable);

    Assert.AreEqual(variable, expression.Evaluate(context, true));
}

[TestMethod]
public void RaiseIfEvaluateUndefinedVariableExpression()
{
    Variable variable = new Variable("X");
    Context context = new Context();
    VariableExpression expression = new VariableExpression(variable);

    try
    {
        expression.Evaluate(context, false);
        Assert.Fail();
    }
    catch (Exception ex)
    {
        Assert.AreEqual("variable 'X' is unbound", ex.Message);
    }
}

Próximos posts: explorar otras implementaciones de expresiones, implementaciones de estructuras básicas del lenguaje, como variables y mapas, etc…

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Posted in AjErl, C#, Erlang, Proyectos Open Source | Comments Off on AjErl Implementando Erlang en C# (2) Expresiones

Resoluciones del Nuevo Mes: Mayo 2015

De nuevo, es tiempo de revisión de mis resoluciones del mes pasado, y escribir las del nuevo mes:

– Escribir posts sobre JavaScript e Inteligencia Artificial  [pendiente]
– Mejorar ClojJS [completo] ver repo
– Agregar soporte de módulos npm a ClojJS [pendiente]
– Mejorar el emulador de Chip8 [pendiente]
– Mejorar BScript [completo] ver repo

Además, estuve trabajando en:

– Mejorar AcquarellaJS [completo] ver repo
– Mejorar AjErl, refactor de funciones de tipo [completo] ver repo
– Mejorar OStore, primeros operadores en match a la MongoDB [completo] ver repo
– Mejorar SimpleLists, operación de intersección de listas [completo] ver repo
– Mejorar MeteorSamples, usando Windows version 1.1 [completo] ver repo
– Participar en Google Code Jam, ronda previa [completo] ver repo
– Programar en Proyecto Liqueed [completo] ver repo
– Grabar sesión de programación en equipo del Proyecto Liqueed usando TDD [completo] ver post/video
– Escribir posts sobre el Proyecto Liqueed [complete] leer posts en inglés leer posts en español

Las resoluciones para este nuevo mes de mayo son:

– Mejorar ClojJS
– Agregar soporte de módulos NPM a ClojJS
– Escribir posts sobre JavaScript e Inteligencia Artificial
– Dar una charla sobre Meteor
– Preparar una charla sobre Clojure o ClojureScript
– Mejorar BScript
– Mejorar AjErl, características distribuidas
– Mejorar Proyecto Liqueed, la implementación de kudos

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Posted in .NET, C#, JavaScript, NodeJs, Proyectos Open Source | Leave a comment

Programando con TDD en Proyecto Liqueed

El viernes pasado hubo sesión de programación remota, en Google Hangout, en el Proyecto Liqueed

https://github.com/liquid-co-ops/liqueed

Quedó grabado el uso que le estamos dando a TDD en el proceso de desarrollo:

Se implementó la primera versión de dar ‘kudos”, una forma de premiar a un miembro de un equipo, por envío de kudos de parte de otros miembros, incluso con integración a Slack. Se va a seguir con esta “feature”, y de la misma manera, implementando todo siguiendo el flujo de trabajo de TDD. Pueden ir viendo los commits del proyecto.

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Posted in JavaScript, Liqueed, NodeJs, Test-Driven Development, Video | Comments Off on Programando con TDD en Proyecto Liqueed