Descubriendo CloudFormation

Desde hace algunas semanas he estado usando, como parte de mi trabajo diario, una de las opciones de Amazon Web Services que nos permite crear plantillas para automatizar la creación de recursos llamada CloudFormation.

En este artículo, tras revisar las las diferentes opciones que tenemos para crear recursos, describiremos algunas características de CloudFormation, y finalmente veremos mi propia experiencia al usar esta herramienta.

Creando recursos en AWS

Crear recursos en la nube, tales como máquinas, blobs para almacenamiento, colas para intercambio de mensajes, bases de datos, o incluso alarmas para medir el rendimiento, es algo que podemos hacer mediante tres maneras:

Mediante la interfaz de usuario

La interfaz nos ayuda a explorar la plataforma, conocer lo que nos ofrece, y suele tener además guías, recomendaciones y enlaces a documentación. Es un buen punto de entrada, pero propenso a error ya que no es sencillo de automatizar.

Usando las herramientas de línea de comandos

Prácticamente todas las acciones que se pueden hacer por la interfaz, se pueden hacer por la línea de comandos (Por ejemplo, aún no podemos crear dashboards de CloudWatch). Por una parte, tendremos que aprender la sintaxis, y el funcionamiento será menos intuitivo que usar el portal, pero por otra parte trabajar con la línea de comandos nos permite cierto grado de automatización.

A través del SDK

Esta opción viene a ser un complemento de la segunda, pero en vez de utilizar un lenguaje de consola de comandos como Bash para nuestra automatización, podemos usar lenguajes como C#, Python o Java para crear nuestros scripts.

Usando plantillas

Esta opción nos permite, mediante un fichero JSON, definir nuestros recursos, valores por defecto, relaciones entre ellos y parámetros que podremos rellenar cuando estemos aplicando la plantilla. Veamos un ejemplo:

{
  "AWSTemplateFormatVersion" : "2010-09-09",
  "Resources" : {
    "myDynamoDBTable" : {
      "Type" : "AWS::DynamoDB::Table",
      "Properties" : {
        "AttributeDefinitions" : [
          {
            "AttributeName" : "Album",
            "AttributeType" : "S"
          },
          {
            "AttributeName" : "Artist",
            "AttributeType" : "S"
          }
        ],
        "KeySchema" : [
          {
            "AttributeName" : "Album",
            "KeyType" : "HASH"
          },
          {
            "AttributeName" : "Artist",
            "KeyType" : "RANGE"
          }
        ],
        "ProvisionedThroughput" : {
          "ReadCapacityUnits" : "5",
          "WriteCapacityUnits" : "5"
        },
        "TableName" : "myTableName"
      }
    }
  }
}

CloudFormation es el sistema que nos permite crear y utilizar estas plantillas, y es el que establece la sintaxis que acabamos de ver para definir nuestros recursos y los diferentes atributos, veamos algunas de sus características y ventajas.

Características

Parámetros

Los parámetros nos permiten personalizar nuestra plantilla en tiempo de creación y pueden ser muy útiles para aplica el mismo recurso en diferentes regiones, o tener la misma plantilla para varios grupos de recursos, utilizando los siguientes tipos de datos:

  • Texto
  • Número
  • Números separados por comas
  • Textos separados por comas

Podemos ver un ejemplo del uso de parámetros en el siguiente bloque, donde, además, podemos utilizar la propiedad AllowedValues para mostrar un desplegable con las diferentes opciones disponibles, o bien dejar un campo de texto libre:

"Parameters" : {
  "InstanceTypeParameter" : {
    "Type" : "String",
    "Default" : "t1.micro",
    "AllowedValues" : ["t1.micro", "m1.small", "m1.large"],
    "Description" : "Enter t1.micro, m1.small, or m1.large. Default is t1.micro."
  }
}

Salida

Otra de las características que podemos utilizar de CloudFormation, es la definición de la salida, que nos permite obtener cualquier valor de los recursos que acabamos de crear, ya sean IDs de instancias de EC2, nombres DNS de recrusos, URLs de tablas en DynamoDB o ARN de colas SQS. Esto es especialmente útil si estamos aplicando nuestro script utilizando la línea de comandos de AWS.

"Outputs" : {
  "BackupLoadBalancerDNSName" : {
    "Description": "The DNSName of the backup load balancer",
    "Value" : { "Fn::GetAtt" : [ "BackupLoadBalancer", "DNSName" ]},
    "Condition" : "CreateProdResources"
  },
  "InstanceID" : {
    "Description": "The Instance ID",
    "Value" : { "Ref" : "EC2Instance" }
  }
}

Referencias

Podemos enlazar recursos en tiempo de creación, es decir, podemos crear una cola SQS, y a su vez una segunda cola para que guarde los mensajes tras varios intentos (lo que se denomina Dead Letter Queue), o podemos crear una tabla y una alarma de CloudWatch asociada a la misma, utilizando referencias internas.

En este ejemplo podemos ver una dirección IP que asociamos a una instancia que hemos definido anteriormente:

"MyEIP" : {
   "Type" : "AWS::EC2::EIP",
   "Properties" : {
      "InstanceId" : { "Ref" : "MyEC2Instance" }
   }
}

Ventajas

La primera ventaja es que es una manera limpia de crear y administrar recursos en AWS, los recursos creados como parte de una plantilla se pueden modificar directamente subiendo una nueva versión de la misma, o bien se pueden borrar, evitando tener que hacer estas acciones por separado.

En segundo lugar, nos facilita replicar nuestra infraestructura en diferentes regiones, ya que AWS mantiene una separación muy estricta entre las regiones (de hecho, no todas las regiones cuentan con todos los recursos, y los precios varían por región).

En tercer lugar, nos aporta control de cambios, ya que por una parte tenemos un fichero de texto que podemos agregar a nuestro sistema de control de versiones, y por otra parte, al aplicar las plantillas, mantenemos un histórico de cambios, donde se aprecian qué recursos se han creado, modificado y eliminado cuando actualizamos nuestras plantillas.

Finalmente, es gratis! AWS no hace ningún cargo por el uso de CloudFormation, solamente pagaremos por los recursos que creamos con el mismo, que sería lo mismo que si los creáramos por separado.

Mi experiencia personal

Personalmente he utilizado CloudFormation para crear plantillas a partir de recursos ya existentes entre diferentes zonas de AWS, creando ficheros (denominados “Stacks”) para tablas DynamoDB, colas SQS y sistemas de notificaciones SNS, así como alarmas de CloudWatch.

Además de los parámetros que hemos visto antes, he necesitado personalizar los stacks que he creado, y para ello, utilizando la función Join para combinar valores por defecto y parámetros:

"Fn::Join" : [ ":", [ "a", "b", "c" ] ] //a:b:c

He experimentado bastante libertad a la hora de enlazar recursos y personalizar los valores, y el hecho de que muchos de los valores sean opcionales me ha permitido centrarme en las características específicas de mi Stack, y no tener que aprender todas las opciones antes de empezar a trabajar, lo cual es de agradecer.

Una cosa que sí hecho en falta de CloudFormation es la posibilidad de crear plantillas automáticamente especificando un recurso, esto nos permitiría convertir tablas, colas, o instancias EC2 en plantillas que podríamos luego replicar en otras zonas.

Resumen

CloudFormation nos permite, utilizando parámetros, crear una serie de ficheros JSON llamados templates, que podemos aplicar desde la UI o la línea de comandos para crear, modificar o eliminar recursos como colas SNS, tablas, máquinas EC2 o alarmas CloudWatch, sin tener que pagar un sobrecoste por esta característica.

Testing with Hamcrest

When I build software one of the things that I need to consider is how to test what I’ve built. Testing gives me a safety net to add new features and to refactor existing code without breaking functionality. For having the basics covered, I use unit tests, and with frameworks such as JUnit we can get easily used to code like this:

assertEquals(expected, actual, message)

When using this code, semantics don’t help, and the question is always the same: what is the expectation, and what is the actual? I tend to swap them, and sometimes I see the test fail with wrong messages. These messages can misguide us or the developer who needs to do some maintenance work.

One of the approaches that we can use for fixing this issue is by using Hamcrest, a JUnit extension that provides a different way of reading our tests. Let’s replace the previous code with:

assertThat(actual, is(expected)) 

With this way of writing, we are stating the assertion, asssertThat whatever object or property we want to validate has an expected value.

The method is, is named a “matcher”, a specific snippet that allow us to build a readable assertion, such as the following ones.

assertThat(result.message, is(equalToIgnoringCase("EXPECTED")));
assertThat(result.message, allOf(containsString("aa"), containsString("bb")));
assertThat(result, hasItem(expected));

As we can see in the previous examples, we have equality modifers, we are able to group different assertions into one and we even have support for Collections.

With this way, we can have more expressive tests and less error prone. This is not something “new”, in fact, it was added to JUnit 4.4 (check out the original release notes) but it’s a different way of writing our tests in Java.

Which syntax do you use for your tests?

Libro: The Clean Coder

downloadEsta semana he terminado de leer “The Clean Coder”, de Robert (Uncle Bob) Martin, un libro que la crítica considera la la continuación del célebre “Clean Code” del mismo autor, pese a que está más enfocado a corregir ciertas actitudes a la hora de programar, de relacionarnos con compañeros, aceptar responsabilidades, etc, dentro de la imagen del programador profesional.

A lo largo de poco más de 200 páginas el libro nos explica detalladamente conceptos técnicos como TDD, que nos ayuda a generar un conjunto de pruebas antes de comenzar a escribir una línea de código, la importancia de Pair Programming como medio de estar centrados en la solución del problema y de transmitir conocimientos, la necesidad de tener un sistema de integración continua que haga que los test se ejecuten de manera regular y la necesidad de que estos tests sean rápidos para poder ejecutarlos una y mil veces, entre otras cosas.

Por otra parte, y más relacionado con habilidades interpersonales, nos cuenta la importancia de saber decir NO a cualquier petición por urgente que parezca, y valorar si realmente podemos hacerlo, lo que nos lleva a saber decir , y hacernos responsables de las promesas que hacemos a nuestros clientes, managers y compañeros.

Siguiendo esta línea, el libro nos explica cómo los programadores solemos interpretar las estimaciones que hacemos como meras aproximaciones, y nuestros clientes o managers las suelen interpretar como deadlines, y explica varias técnicas para poder dar estimaciones más fiables como puede ser el análisis PERT, en el cual asignas caso mejor, caso más probable y caso peor a cualquier tarea.

Relacionado con la estimación, nos habla de la necesidad de conocer el negocio en el que nos encontramos para poder dar una mejor valoración a las prioridades que vienen “de arriba” usando algunas anécdotas.

Finalmente nos habla de la importancia de practicar, de aprender, de mantener nuestras herramientas al día, de buscar mentores, ya sea de la manera clásica (alguien que dedique activamente su tiempo a ayudarnos) o de maneras menos convencionales (un libro, una conferencia, algo que nos motive a seguir adelante aunque los autores no lo sepan).

En definitiva, una lectura recomendable, sobre todo al empezar un nuevo proyecto profesional, nos ayudarán a identificar puntos a mejorar de nuestros equipos, y nos ayudaran a ser mejores profesionales.

En Amazon: The Clean Coder: A Code of Conduct for Professional Programmers

Manteniendo nuestros eBooks sincronizados entre diferentes dispositivos.

Cuando nos movemos del modelo de libros físicos al modelo de libros digitales, ganamos una enorme conveniencia, y es que nuestros libros de repente se vuelven accesibles allá donde vayamos, en nuestro lector de eBooks, en nuestro móvil, en nuestra tablet, e incluso en cualquier ordenador vía el navegador, guardando el estado de la lectura.

A mí personalmente me encanta cómo funciona el ecosistema de Kindle, ya que tienes por una parte el dispositivo y por otra parte una suite de aplicaciones para iOS, Android, Windows y un lector web que mantienen todo conectado.

Sin embargo, a pesar de que el catálogo de Amazon es bastante grande, no es la única fuente para comprar ebooks, y a veces nos encontramos con otras fuentes, que incluso a veces ofrecen libros de manera gratuita, como por ejemplo:

  • O’Reilly y sus ofertas diarias
  • Manning, que nos regala el ebook cuando compramos el libro en papel.
  • Pragmatic Programmers, con ofertas recurrentes.
  • Microsoft Press, con libros gratuitos.

Amazon no ofrece ninguna manera de poder ampliar nuestra biblioteca, aunque sí que nos permite enviar libros a dispositivos y aplicaciones concretas, pero sin la capacidad de sincronización entre ellos.

Buscando una solución a esto me topé con Google Play Books, que para aquellos que tengan Android es la aplicación por defecto para abrir libros en formato ePub, también tiene aplicaciones para iPhone, y además es una web donde podemos continuar leyendo nuestros libros.

Una de las ventajas que descubrí de Google Play Books es la posibilidad de subir nuestros propios libros, hasta 1000, con lo cual (siempre que no estén protegidos por DRM) podemos tenerlos accesibles desde cualquier parte manteniendo nuestro estado guardado.

Como decía en mi artículo al principio del año, uno de mis objetivos es leer más, y de momento este pequeño descubrimiento me está ayudando bastante.

Enlace: Google Play Books

Y llegó 2016

Ya con esta son seis ediciones del resumen anual de mi blog, o lo que es lo mismo, más de 2000 días desde mi primer artículo, y es que 2015 ha sido un año muy interesante para mí, aunque he de reconocer que he escrito menos, mucho menos, de lo que pensaba en un primer momento.

Comencé el año volviendo a mi universidad a hablar de tres Tecnologías Microsoft que no se dan en la carrera, comprobando cómo, años después de mi paso por las aulas, el DotNetClub sigue vivo y dando caña. Enhorabuena a Arcadio (actual Presidente de la asociación) por ese trabajo.

En febrero publiqué The Time Box, mi primera aplicación para Android, y pude dar un vistazo a esa plataforma, tener mi primera aplicación en Google Play y ver todo el ciclo de desarrollo de una aplicación móvil.

En marzo tuve la oportunidad de formar parte de la primera gran conferencia de .NET a nivel nacional, en la que tuve el honor de presentar dos sesiones, una de ellas acompañado por el ilustre Eduard Tomás en la que hablamos de ASP.net vNext, y las novedades que traía.

Entre febrero y abril, Juan Quijano y yo un par de hangouts en los que tratamos temas como Xamarin o programación funcional desde la perspectiva del mundo real, y de cómo profesionales usan estas herramientas y lenguajes en su día a día.

Mayo fue mes de cambios, y de despedidas, ya que cerré un ciclo profesional en Frontiers, una empresa de publicaciones suiza en la que participé en la creación de Loop, su red social.

Alrededor de la misma fecha, y a pesar de que no le hice la publicidad que se merecía en el blog, publiqué mi primer curso de CampusMVP, que ahora forma parte de la oferta del Master Online de desarrollo de Aplicaciones Front-End.

Durante el resto del año estuve un poco alejado del blog, ya que apenas tuve tiempo, pero eso no me impidió publicar un monográfico de Scala, que me gustaría retomar este año, o publicar mi experiencia en el lambda world de Cádiz.

Como último artículo del año, me calcé las zapatillas otra vez y comenté mi experiencia corriendo la carrera “Ponle Freno” un año después de mi primera incursión en el mundo del “Running”

El año pasado además, dejé lista una lista de objetivos que quería cumplir este año:

  • Aprender un nuevo lenguaje de programación o framework, y hacer un proyecto en él: En este caso he aprendido algo de programación para Android y Scala, así que lo podemos dar por conseguido.

  • Hacer más vídeos en inglés y en castellano: La parte de castellano está conseguida con el curso de CampusMVP, la parte en inglés no tanto. digamos que cumplido al 50%

  • Montar más hangouts: 3 en 2014 contra 2 en 2015, está claro que este año no ha podido ser.

  • Hacer más proyectos personales: 2015 terminó con un par de ideas, mi primera aplicación Android y un pequeño clon de Trello, creo que lo podemos dar por conseguido.

  • Cerrar un ciclo de certificaciones Microsoft: Este año no ha podido ser.

  • Cursar y aprobar otro MOOC: Muy en la línea de las certificaciones Microsoft, tampoco ha podido ser.

  • Trabajar más en mi segundo o tercer idioma: A fecha de hoy trabajo en inglés al 100%, así que mi nivel de inglés y mi vocabulario han mejorado, pero el tercer idioma sigue siendo una incógnita.

  • Seguir escribiendo: Pese a que he escrito menos, he escrito, y espero seguir el año que viene.

Así, pongo la vista en 2016 con la siguiente lista de tareas, que seguramente sufrirá modificaciones a lo largo del año, pero esto es lo que quiero hacer a fecha de hoy:

  • Enviar al menos 3 papers a conferencias técnicas.

  • Leer más literatura técnica, mínimo 10 libros.

  • Hacer más proyectos personales, mínimo 3.

  • Escribir más artículos técnicos, mínimo 20.

  • Hacer un nuevo MOOC de Coursera/edX, etc.

  • Conseguir al menos una certificación de tecnología, ya sea Microsoft, Java, etc.

  • Aprender al menos un lenguaje, tecnología, plataforma o paradigma que me saque de mi zona de comfort.

Y a todo eso, sumar conseguir correr la San Silvestre Vallecana en menos de 1h.

Gracias por leer este blog. Espero que tengas un próspero y 2016 cargado de cosas interesantes.

OT: Corriendo voy… un año después

El año pasado por estas fechas comentaba mi primera experiencia en una carrera popular, y toda la tecnología que había visto en su momento.

He de reconocer que fue agónico, tuve que parar varias veces y el resultado implicó una semana de agujetas, aunque fue suficiente para que me picara la curiosidad, empezara a correr de manera más regular y a participar en alguna que otra carrera más:

  • Rexona Street Run (5K) en la que descubrí lo divertido que es participar en una carrera resfriado, altamente recomendable. Me paré un par de veces pero logré terminarla corriendo.

  • Rock n’Roll (10K), que llegué justo y no pude dejar la mochila en el guardarropa, con lo cual me tocó correr con la bolsa, una faena, pero logré terminarla sin parar.

  • Carrera Popular Alcobendas (10K) ya en primavera, pude comprobar que el calor no perdona, y los desniveles de Alcobendas son algo intimidantes. Me tocó pararme varias veces y casi no lo consigo.

  • Proniño (10K) la última carrera que corrí en verano, todo fue perfecto, un tiempo maravilloso, un terreno plano prácticamente sin cambios de nivel, logré terminarla sin parar logrando mi mejor tiempo en 10K hasta ahora.

  • Ponle Freno (5K) he repetido este año aunque en la modalidad 5K, con la suerte de que todo ha salido bien, desde el transporte hasta el guardarropa, y he conseguido mi mejor tiempo.

Con cada carrera, he ido aprendiendo muchísimo sobre ritmos, tiempos, estiramientos, qué llevar, qué no llevar, etc, y de momento mi stack tecnológico de runner consiste en lo siguiente:

  • Fitbit Charge HR: Además de contar pasos, Detecta cuando empiezo (y termino) una actividad como correr, registrando distancia y ritmo cardiaco, lo que me permite analizar mejor los resultados tras la carrera.

  • Pebble Time: Además de poder personalizar la hora y poder leer los mensajes de Whatsapp mientras corres, permite la conexión con Endomondo, resultando muy útil para tener datos como el ritmo actual directamente en la muñeca.

  • Auriculares Bluetooth MPow Cheetah: En su momento me costaron poco más de 20€, y son extremadamente buenos para el precio que tienen, se oyen bien, resultan cómodos, aíslan del ruido y evitan los molestos cables, sin sacrificar batería. disponible en Amazon

  • iPhone 6: Hace un año tenía un iPhone 5 que luego descubrí que formaba parte de la partida con problemas de batería, tras una temporada en el mundo Android he vuelto a iOS, y la batería del 6 me permite correr sin tener que depender de baterías extra.

  • Endomondo: Mi app de referencia para todo lo relacionado con deporte, me ayuda a correr, mide las distancias y me va indicando ritmo y kilómetros por los auriculares mientras corro.

  • Spotify He de reconocer que envidio a aquellos que son capaces de correr sin música, pero yo aún no he llegado a ese nivel, ni sé si seré capaz, de momento spotify (y su opción running) me ayudan a concentrarme, aunque para la carrera opté por una lista de reproducción, ya que spotify running requiere internet y no quería depender del estado de la red mientras corría.

Dar con el equipamiento definitivo es una cuestión de prueba y error, aunque de momento creo que el que tengo me vale, lo siguiente es encontrar unas buenas zapatillas, y creo que para eso le preguntaré a los chicos de runnics.

Nos vemos en la línea de meta!

Estuve en el Lambda World

Escribo estas líneas volviendo en tren desde Cádiz, una ciudad enigmática que me recuerda muchísimo a mi añorada Habana, tal vez porque la segunda se construyera basándose en la primera.

Cádiz, además de ser la ciudad que acogió la firma de la primera Constitución Española en 1812, ha acogido el pasado fin de semana el primer evento internacional de programación funcional celebrado en España, el Lambda World.

En este evento, ponentes de todas partes del mundo han venido a contarnos acerca de características de la programación funcional como mónadas, funciones puras, inmutabilidad, efectos secundarios, o sobre cómo llevar conceptos de programación funcional a programación orientada a objetos.

Para ello, hemos visto ejemplos en lenguajes como F#, C#, Java, Ruby, Swift, y, sobre todo, Scala. He aprendido muchísimo y aquí resumo algunos conceptos que me han llamado la atención y que me toca seguir estudiando.

La inmutabilidad, más complicada pero menos propensa a errores.

En programación orientada a objetos definimos clases con propiedades y comportamiento. Este comportamiento suele implicar un cambio en el estado del objeto.

Sin embargo, es justamente lo que queremos evitar en programación funcional, ya que trabajamos con objetos inmutables, con lo cual una vez creados, no cambia ninguna de sus propiedades.

Esto también se aplica a colecciones, y a los miembros de la misma, con lo cual la acción de añadir un objeto a una colección, o modificar un objeto de la misma requiere crear una nueva colección.

Con estos objetos inmutables lo que conseguimos asegurarnos que su estado no va a cambiar, y que no vamos a tener “sorpresas” cuando pasemos un objeto a un método que de repente modifique alguna de sus propiedades.

Sin embargo, aunque lenguajes como Swift, Scala o F# soportan inmutables por diseño, en el mundo clásico de la orientación a objetos, tanto para Java, C# o Ruby, es justamente al contrario, y queda de nuestra mano utilizar colecciones inmutables y definir manualmente nuestros objetos.

Las funciones puras no generan efectos secundarios, o casi

Otro concepto que se repitió bastante en el evento era el de función pura, que no es más que un método que recibe una entrada y devuelve una salida.

La magia de este concepto es que cuando lo combinamos con los objetos inmutables, conseguimos que para una entrada X tenemos la absoluta seguridad de que la salida será Y, SIEMPRE.

Esto nos permite, entre otras cosas, poder probar de manera rápida nuestras funciones si el lenguaje que estamos utilizando incorpora una consola REPL (Read Evaluate Print Loop), ya que una vez definida la función solamente tenemos que ejecutarla con los valores adecuados.

Los lenguajes funcionales no son algo solamente “académico”

Aunque los conceptos que nos muestren se acerquen bastante más a las matemáticas que a ensamblador, los ejemplos mostrados en aplicaciones móviles, sistemas cliente-servidor, arquitecturas funcionales y videojuegos, me dejaron bastante claro que la programación funcional está aquí para quedarse, y que ya estamos tardando, al menos, en aprender algunos de sus conceptos.

No tengo ni idea de lo que son las monads, creo.

Uno de los conceptos de programación funcional que se me escapa es el de las monads, que al parecer son tipos de datos con propiedades específicas, y uno de los ejemplos que veíamos en el evento era el del monad Either, que tiene dos tipos, Left o Right.

Con este monad podíamos definir el resultado de nuestra función, siendo Left un resultado de éxito, y Right una definición de un error, evitando flujos como captura de excepciones.

Este concepto tiene a su vez conceptos relacionados como monoids o functors… de los cuales tendré que leer, y mucho.

Podemos usar conceptos de programación funcional con lenguajes no puramente funcionales.

Conceptos como funciones puras u objetos inmutables son relativamente fáciles de implementar aunque los lenguajes no lo refuercen nativamente, sin embargo requiere un grado de disciplina mayor.

Sin embargo lenguajes como C# o Java van aportando cada vez más características de la programación funcional a su sintaxis, como las Lambdas y las colecciones inmutables. Aunque no es el escenario ideal para utilizar programación funcional, nos permite usar lo que ya sabemos.

Tenemos muchas maneras de empezar, aunque hay dos muy interesantes:

Por una parte tenemos lenguajes como Scala, en el que podemos desarrollar de la misma manera en la que lo veníamos haciendo hasta ahora, ya que soporta tanto tipos mutables como inmutables, e ir agregando características de la programación funcional a nuestros programas.

Por otra parte tenemos lenguajes F#, que nos permite lanzarnos al vacío, con una sintaxis que nos podría recordar cuando encadenamos la salida de distintos procesos en una shell de unix, que nos permite aprender programación funcional más “pura” y su interoperabilidad con C# nos permite agregar componentes funcionales a nuestro proyecto.

En resumen

Tenemos características como la inmutabilidad y las funciones puras que nos evitan sorpresas en nuestro código, podemos empezar migrando poco a poco a funcional o tirarnos a la piscina con lenguajes que solamente implementan este paradigma, y tenemos algo de soporte en nuestros lenguajes del día a día de algunos conceptos como las lambdas. Ha sido una experiencia muy enriquecedora, y espero veros en la siguiente edición de Lambda World