La compra de GitHub por Microsoft desde la perspectiva de un desarrollador

05/06/2018
Artículo original

Buy

Como casi todas las noticias bomba, el rumor de que Microsoft estaba interesada en la adquisición del principal repositorio de código libre del mundo, GitHub, me llego a través de las redes sociales cargado de incertidumbre y desconfianza.

Lo que no ha sido sorprendente ha sido la sobre reacción de la comunidad de desarrolladores, en donde se encendieron las viejas antorchas de la inagotable guerra entre los fanboys (pro) y los talibanes (anti) Microsoft.

Y por ello, quiero aportar al extenso debate y a los cientos de artículos que recorren las redes sociales, el punto de vista de diversos desarrolladores con los que he conversado sobre la polémica compra.

¿Qué es GitHub?

Github 840x473

En abril del 2005 Linus Torvalds, el padre del sistema operativo Linux, diseñó un motor de control de código llamado Git con el propósito de tener un sistema descentralizado que le permitiera trabajar de la forma que las herramientas del momento no le permitían.

Su éxito fue inmediato y rápidamente creció su adopción por la comunidad de desarrolladores hasta convertirse en el gestor de código más utilizado en todo el mundo.

Usando este repositorio como piedra angular, en 2008 Chris Wanstrath, PJ Hyett, y Tom Preston-Werner, fundan GitHub con el propósito último de construir herramientas para la comunidad de desarrollo, sentando las bases de la plataforma que acoge más de 28 millones de usuarios y supera los 85 millones de repositorios.

Aun cuando ofrece un servicio de repositorios privados y empresariales, el éxito de GitHub viene por su adopción como estándar de facto para la publicación de proyectos open source, y un funcionamiento principalmente basado en Pull Request; técnica de construcción colaborativa ampliamente aplicada en el desarrollo de código abierto.

Es tal su éxito, que es casi de obligado cumplimiento el tener un repositorio en GitHub para poder ponerse el título de “desarrollador”; incluso llegando a ser parte fundamental del currículum profesional, como pueden ser también el perfil de Linkedin o la presencia en las redes sociales y eventos de comunidad.

Y, aún más allá del almacenamiento del código fuente, se utiliza para distribuir documentación, blogs, información, páginas web estáticas, etc.

¿Por qué su destino era la Bolsa o la compra?

Stock

Como un buen ejemplo de start-up, GitHub no rinde beneficios en comparación con el volumen de inversión que ha ido recibiendo. Al principio, cuando el dinero provenía de sus tres fundadores, el resultado anual era positivo en relación con la importante tasa de crecimiento que consiguieron.

Pero las alarmas empezaron a saltar cuando el reputado medio Bloomberg publicó un informe en dónde se mostraba que el ritmo de gasto de GitHub, para seguir creciendo y protegerse de sus competidores, había llegado a los 66 millones de dólares en 9 meses.

7.500.000.000 de razones, son muchas para decir que no.

La cosa se tuvo que empezar a poner de color hormiga (no hay acceso a las cifras) cuando en agosto del 2017 Chris Wanstrath, fundador y CEO de la compañía, ponía pies en polvorosa (o le obligaban) y no había forma de encontrar una nueva cabeza que dirigiera los pasos de la empresa.

Todos los analistas veían únicamente tres soluciones, la cual una de ellas (el cierre) hubiera significado un desastre tanto económico para los inversores, como un problema de enormes repercusiones para la comunidad del desarrollo de software.

Otra opción era preparar una salida a Bolsa basada en la confianza de una plataforma robusta, que ha vencido a competidores del calibre de Google Code, Sourceforge y CodePlex, y que tiene millones y millones de clientes que respaldan el servicio. Pero con el inconveniente de ser un poco “pequeña” aún para entrar en el juego de la especulación financiera; habiendo un riesgo cierto de que saliera mal, y perdiera lo poco que le podía quedar de crédito.

La última opción, y que es la que ha resultado ganadora, es conseguir vender la plataforma a una de las grandes del sector como podría ser Google, Microsoft, Oracle, IBM, o similar. Eliminando de un plumazo todos los problemas financieros y obteniendo unos más que suculentos beneficios.

Y les ha salido muy bien. En el momento de la venta, GitHub estaba sobre estimada en unos dos mil millones de dólares, y Microsoft ha puesto encima de la mesa más del triple de dinero: 7.500 millones.

¿Por qué la ha comprado Microsoft?

Gitmicrosoft

CodePlex fue el repositorio de código público creado y sostenido por Microsoft desde el 2006 hasta finales del 2017, en donde cerraron ante el auge imparable y la adopción de GitHub como plataforma principal para publicar el código fuente de los proyectos Open Source de la compañía.

Una compra estratégica para protegerse del competidor

Esta adopción también se mostró en las herramientas de desarrollo, desde las cuales puedo conectar mis proyectos con el motor Team Foundation Version Control, Git o GitHub, indistintamente.

Además, cada vez se publica más y más información, documentos y material de formación en GitHub. Siendo la plataforma elegida por Azure para sus repositorios de plantillas de despliegue de Infraestructura como Código.

Es decir, Microsoft reconoció y se rindió ante la realidad de que la combinación de Git + GitHub era imbatible y había sido la elegida por la comunidad para gestionar el código.

Y ahora, aprovechando las vicisitudes financieras por las que pasaba GitHub, tiene sentido que se propusiera una adquisición preventiva estratégica de una plataforma que se ha vuelto crítica y troncal en el negocio del desarrollo, para evitar que pudiera ser adquirida por competidores de la talla de Google u Oracle, lo cual podría traerle serios inconvenientes funcionales. Recordemos la reciente política anti Microsoft de Google, que tantas molestias ha causado a los usuarios.

Lo positivo de la compra

Smiley One Thumb Up

La primera ventaja de esta adquisición es que se han evaporado los negros nubarrones financieros sobre el futuro de GitHub. No se puede negar que Microsoft tiene más que suficientes recursos como para sostener los costes de operación a largo plazo sin pestañear.

Para los desarrolladores que utilizan el stack de Microsoft, estamos de enhorabuena porque se espera una integración en todo el ciclo de desarrollo mucho más cercano, y el resultado de la integración de GitHub con Visual Studio Team Services puede ser muy interesante.

De hecho, uno de los puntos que más ilusión me hacen de la nota de prensa de Satya Natedella, es cuando habla como se va a potenciar el desarrollo en cada etapa del ciclo de vida, manteniendo la absoluta libertad de elección del lenguaje, herramientas, sistemas operativos y nube que se tiene ahora.

Para la mayoría que no utilizan herramientas de Microsoft más allá de VS Code, los cambios deberían ser menos evidentes, ya que se supone que se va a aplicar un modelo de funcionamiento similar al de Linkedin. Es decir, GitHub seguirá funcionando igual que ahora, con su marca, sus cifras y su modelo de negocio; pero bajo las órdenes de gente tan buena como Nat Friedman y Scott Gurnie.

Malas cosas malas

Sauron

Las causas del rechazo a esta compra parecen ser más bien emocionales. Basadas en la desconfianza a una compañía que durante muchos años ha sido un enemigo declarado del Open Source, y que ha sido condenada por prácticas monopolísticas y por manipulación del mercado.

Aun habiendo pasado más de 20 años, aún muchos recuerdan las palabras de Ballmer demonizando el software libre. Pero más recientemente los grandes fiascos de Windows Phone o Windows RT, con cientos o miles de proyectos tirados a la basura por un cambio de rumbo empresarial, producen reticencia en muchos desarrolladores.

Un Anillo para gobernarlos a todos. Un Anillo para encontrarlos, un Anillo para atraerlos a todos y atarlos en las tinieblas...

También el ejemplo de Oracle, y cómo despiezó Sun, hace temer por el futuro y continuidad de GitHub.

Por otra parte, este movimiento de Microsoft produce una concentración excesiva de poder y control en una sola compañía. Y pone en sus manos los datos y proyectos de millones de programadores en todo el mundo, a los que se pide que confíen en la buena fe de una compañía que aún muchos comparan con Saurón.

Conclusión

Sabiendo quienes van a ser los responsables de dirigir GitHub, y que se va a aplicar la política de funcionamiento que se ha permitido a Linkedin, tengo la sensación de que todo se va a quedar igual.

Como mucho, veremos cómo Visual Studio Team Services va a integrar las capacidades de GitHub, aunque muchas ya las tiene, y cómo los repositorios públicos van a recibir mejoras desde la plataforma DevOps de Microsoft.

Si tuviera alguna duda, es si Atom va a aguantar el bocado que ya le ha dado Visual Studio Code, o va a dejar de ser apoyado por la comunidad y languidecer.

No habrá cambios, ni desbandada. GitHub seguirá siendo el rey

Hay que tener en cuenta que, como todo lo gratis, significa que (las personas) somos el producto. Pero eso ya pasaba con los anteriores dueños de la plataforma, y me alegro de que no sea una empresa pura de datos (como Google o Facebook) quien haya dado la tranquilidad financiera a GitHub.

Mientras, las estadísticas de GitLab sobre migraciones de proyectos desde GitHub muestra un pico muy pequeño de desarrolladores cambiando de plataforma (apenas unos pocos miles de proyectos en comparación con los más de 80 millones que se han quedado), lo cual puede mostrar que la tendencia es que sigamos utilizando GitHub como repositorio público preferido.

Más información | Comunicado de GitHub, Comunicado de Microsoft, GitHub Is Building a Coder’s Paradise. It’s Not Coming Cheap

En WSL | Ya es oficial: Microsoft compra GitHub por 7.500 millones de dólares, Ante la paranoia, Microsoft promete que GitHub se mantendrá independiente y abierto

También te recomendamos

Cómo influye la conexión de dispositivos en tu calidad de vida

CoreCLR, el núcleo de ejecución de .NET Core se publica Open Source

.NET se pasa a Open Source

-
La noticia La compra de GitHub por Microsoft desde la perspectiva de un desarrollador fue publicada originalmente en Genbeta Dev por Juan Quijano .

Ya está disponible .NET Core 2.1

05/06/2018
Artículo original

Como ya os comentamos en directo durante la pasada DotNet2018, Microsoft ha anunciado la disponibilidad de .NET Core 2.1. Esta nueva versión incluye mejoras en el rendimiento, el runtime y las herramientas. También incluye una nueva forma de implementar herramientas como paquetes NuGet. Se agrega un nuevo e interesante tipo primitivo llamado Span<T> que opera en datos sin asignaciones de memoria adicionales. Hay muchas otras nuevas API, centradas en la criptografía, la compresión y la compatibilidad de Windows. Es la primera versión que admite chips Alpine Linux y ARM32. Esta nueva versión es compatible con .NET Core 2.0, lo que facilita mucho la actualización, claro está.

ASP.NET Core 2.1 y Entity Framework Core 2.1 van incluidas en esta actualización.

Puede descargar y comenzar con .NET Core 2.1, en Windows, macOS y Linux:

.NET Core 2.1 es compatible con Visual Studio 15.7, Visual Studio para Mac y Visual Studio Code.

Si lo tuyo es Docker, las imágenes correspondientes están disponibles en microsoft/dotnet tanto para .NET Core como para ASP.NET Core.

Puedes ver los detalles completos del lanzamiento en las notas de la versión de .NET Core 2.1.

.NET Core 2.1 es una versión de soporte a largo plazo (LTS), cosa que no era .NET Core 2.0. Esto significa que se dará soporte por parte de Microsoft durante tres años, por lo que se puede recomendar su uso desde ya.

De todos modos Microsoft dice que tienen la intención de enviar algunas actualizaciones significativas en los próximos 2 o 3 meses para estabilizar la versión por completo y empezar a dar el soporte LTS. Después de eso, las actualizaciones se orientarán a la seguridad, la confiabilidad y la adición de soporte de la plataforma (por ejemplo, Ubuntu 18.10). 

Las principales ventajas de adoptar .NET Core 2.1 son:

  • Soporte a largo plazo.
  • Rendimiento y calidad superiores.
  • Nuevo soporte de plataformas, como: Ubuntu 18.04, Alpine, ARM32...
  • Es mucho más fácil administrar las versiones de .NET Core y ASP.NET Core en los archivos del proyecto y con la publicación de aplicaciones auto-contenidas.

En la actualidad .NET Core funciona en las siguientes plataformas:

  • Windows Client: 7, 8.1, 10 (1607+)
  • Windows Server: 2008 R2 SP1+
  • macOS: 10.12+
  • RHEL: 6+
  • Fedora: 26+
  • Ubuntu: 14.04+
  • Debian: 8+
  • SLES: 12+
  • openSUSE: 42.3+
  • Alpine: 3.7+

y se soportan los chips: x64 en Windows, macOS y Linux, x86 en Windows y ARM32* en Linux.

*Nota: .NET Core 2.1 es compatible con Raspberry Pi 2+. No es compatible con Pi Zero u otros dispositivos que usan un chip ARMv6. .NET Core requiere chips ARMv7 o ARMv8, como ARM Cortex-A53 .

 Herramientas de .NET Core

.NET Core ahora dispone de un nuevo mecanismo de despliegue y extensibilidad para herramientas. Esta nueva experiencia es muy similar e inspirada por las herramientas globales de NPM . Puedes crear tus propias herramientas globales echando un vistazo a las herramientas de ejemplo dotnetsay.

Las herramientas para .NET Core son aplicaciones de consola .NET Core que se empaquetan y adquieren como paquetes NuGet. Por defecto, estas herramientas son aplicaciones dependientes del framework, e incluyen todas sus dependencias NuGet. Esto significa que las herramientas .NET Core se ejecutan en todos los sistemas operativos y arquitecturas de procesador compatibles con .NET Core, con un único binario. Por defecto, el comando de dotnet tool install de la herramienta dotnet busca herramientas en NuGet.org. Puedes usar feeds NuGet propios también.

Actualmente, .NET Core Tools admite dos modelos de instalación:

  • Instalación global, que requiere el parámetro -g o -global para instalar la herramienta. Las herramientas instaladas a nivel global se copian a una ubicación específica en tu perfil de usuario que está en el path del sistema, por lo que se pueden invocar de manera directa desde cualquier línea de comandos.
  • Instalación Ad-hoc, que requiere utilizar el parámetro -tool-path. Las herramientas instaladas ad-hoc se copian en la ubicación que elijamos. Se pueden invocar a través de la ruta completa o puede agregar al path, lo que permite una configuración similar pero personalizada de la instalación global.

Aquí puedes encontrar una lista de herramientas para .Net Core mantenida por Nate McMaster.

Las siguientes herramientas DotNetCliReferenceTool que antes había que instalar por separado, se han convertido en herramientas "de serie", así que mejor quita sus referencias del archivo de proyecto antes de actualizar a la versión 2.1:

  • dotnet watch
  • dotnet dev-certs
  • dotnet user-secrets
  • dotnet sql-cache
  • dotnet ef

Grandes mejoras de rendimiento

El enfoque principal de Microsoft en esta versión ha sido quizá el de mejorar el rendimiento de la compilación .NET Core. Se ha mejorado mucho, especialmente en el caso de compilaciones incrementales. Estas mejoras se aplican tanto al comando dotnet build como a las compilaciones desde Visual Studio.

La siguiente imagen muestra las mejoras que se han obtenido en comparación con .NET Core 2.0 en el caso de los proyectos de referencia:

Como vemos, en el caso del proyecto grande se han conseguido mejoras de velocidad de compilación de hasta 10 veces menores.

En el caso del rendimiento en tiempo de ejecución las mejoras de rendimiento son también sustanciales. Puedes ver un estudio detallado en este artículo: Performance Improvements in .NET Core 2.1.

Del mismo modo se ha incrementado mucho el rendimiento en operaciones de red ya que se ha rescrito por completo la clase HttpClientHandler, en forma de la nueva clase SocketsHttpHandler. Esta es ahora es la implementación por defecto que se usa para HttpClient. La mayor ventaja de SocketsHttpHandler es el rendimiento. Es mucho más rápido que la implementación existente. También elimina las dependencias específicas de la plataforma y permite un comportamiento uniforme en todos los sistemas operativos.

Span <T>, Memory <T> y similares

Estamos entrando en una nueva era de informática eficiente y de alto rendimiento con .NET, con la introducción de Span<T> y los tipos similares relacionados. Hasta ahora, si deseábamos pasar los primeros 1000 elementos de una matriz de 10.000 elementos, debíamos realizar una copia de esos 1000 elementos y pasar la copia a la función que vamos a llamar. Esa operación es costosa en tiempo y memoria. El nuevo tipo Span<T> nos permite proporcionar una vista virtual de esa matriz sin el coste asociado. Span<T> es una estructura (un tipo por valor), lo que significa que es posible habilitar pipelines complejas de análisis u otros cálculos sin necesidad de asignarlo en memoria fuera de la pila. Este nuevo tipo se está utilizando ya extensivamente en corefx por este motivo.

En este artículo de Stephen Toub puedes conocer Span<T> con mucho detalle.

Compresión Brotli

Brotli es un algoritmo de compresión sin pérdidas, de propósito general, que comprime datos tan bien o mejor que los mejores métodos de compresión de uso general actualmente disponibles. Es similar en velocidad a deflate, pero ofrece una mayor compresión. Brotli se define en la RFC 7932. La mayoría de los navegadores web, los principales servidores web y algunos CDN (Content Delivery Networks) admiten la codificación y transmisión de datos utilizando Brotli. La implementación de .NET Core de Brotli se basa en el código C proporcionado por Google en google/brotli.

Nuevas API de criptografía

Se han realizado las muchas mejoras en las API de criptografía .NET Core, entre las que cabe destacar:

  • Nuevas API SignedCms - System.Security.Cryptography.Pkcs.SignedCms ahora está disponible en el paquete System.Security.Cryptography.Pkcs . La implementación de .NET Core está disponible para todas las plataformas .NET Core y tiene paridad con la clase de .NET Framework.
  • Nueva sobrecarga de X509Certificate.GetCertHash para SHA-2 - Las nuevas sobrecargas para X509Certificate.GetCertHash y X509Certificate.GetCertHashString aceptan un identificador de algoritmo hash para permitir que los llamantes obtengan valores de huella digital de certificado utilizando algoritmos distintos a SHA-1.
  • Nuevo API de criptografía basada en Span<T> - Las API basadas en la nueva clase están disponibles para hashing, HMAC, generación de números aleatorios (criptográficos), generación de firmas asimétricas, procesamiento de firmas asimétricas y encriptación RSA, con la consiguiente mejora de rendimiento y uso de memoria.
  • Mejoras de rendimiento en Rfc2898DeriveBytes - La implementación de Rfc2898DeriveBytes (PBKDF2) es aproximadamente un 15% más rápida, ya que se ha utilizado Span<T>.
  • Añadido static RandomNumberGenerator.Fill - El método estático RandomNumberGenerator.Fill rellenará un Span<T> con valores aleatorios utilizando el CSPRNG preferido por el sistema, y ​​no requiere que la persona que llama administre la vida útil de un recurso IDisposable.

Paquete de compatibilidad de Windows

Cuando transfiramos código existente desde .NET Framework a .NET Core, puede usar el Paquete de compatibilidad de Windows. Éste proporciona acceso a 20,000 API adicionales a las que están disponibles de base en .NET Core. Esto incluye System.Drawing, EventLog, WMI, Contadores de rendimiento e incluso Servicios de Windows. Puedes leer el artículo Announcing the Windows Compatibility Pack for .NET Core para obtener más información sobre este asunto.

Compilación escalonada

En esta versión se ha agregado una versión preliminar de una nueva y emocionante capacidad para el tiempo de ejecución llamada compilación escalonada. Se trata de una manera de conseguir que el runtime de .NET Core utilice de forma más adaptativa el compilador Just-In-Time (JIT) para obtener un mejor rendimiento.

El desafío básico para los compiladores de JIT es que el tiempo de compilación es parte del tiempo de ejecución de la aplicación. Producir un mejor código nativo generalmente significa pasar más tiempo optimizándolo. Pero si una determinada parte del código solo se va a ejecutar una vez (o unas pocas veces), el compilador podría dedicar más tiempo a optimizarla que el tiempo que gastaría ejecutando la versión no optimizada, por lo que es absurdo hacerlo en este tipo de fragmentos de código.

Con la compilación escalonada, el compilador primero genera código lo más rápido posible, con solo optimizaciones mínimas (primer nivel). Luego, cuando detecta que ciertos métodos se ejecutan mucho, produce una versión más optimizada de esos métodos (segundo nivel) que se utilizarán en lugar de la compilación original. La compilación de segundo nivel se realiza en paralelo, lo que elimina la tensión existente entre las velocidades de compilación rápidas y la producción de código óptimo. Este modelo se puede llamar genéricamente Optimización adaptativa.

Puedes probar la compilación escalonada estableciendo una variable simple de entorno:

COMPlus_TieredCompilation = "1" 

Puedes habilitarla para una aplicación concreta configurando la propiedad TieredCompilation, como puede ver en este proyecto.

SourceLink

SourceLink es un sistema que habilita experiencias de depuración de los binarios .que distribuimos o consumimos que se asemejan a si tuviésemos el código fuente disponible. Necesia que dispongamos de información de SourceLink producida por el compilador, y depuradores que la soporten. El depurador de Visual Studio ya es compatible con SourceLink, comenzando con Visual Studio 2017 15.3. Se ha agregado soporte para generar información de SourceLink para símbolos, binarios y paquetes NuGet en el SDK de .NET Core 2.1.

Puedes comenzar a producir información de SourceLink siguiendo el ejemplo en dotnet/sourcelink . Puedes ver cómo está habilitada en este proyecto.

El objetivo de Microsoft con esto es permitir que cualquiera pueda construir Las bibliotecas NuGet para proporcionar depuración de fuentes para sus usuarios casi sin esfuerzo.

La siguiente captura de pantalla muestra la depuración de un paquete NuGet al que hace referencia una aplicación, con la fuente descargada automáticamente desde GitHub y utilizada por Visual Studio 2017:

Publicación de aplicaciones autocontenidas

dotnet publish ahora es capaz de publicar aplicaciones autocontenidas que incluyen en el ejecutable una versión del runtime concreta. Cuando publiquemos una aplicación autónoma con el nuevo SDK, ésta incluirá la última versión del runtime  conocida por ese SDK. Gracias a esto no es necesario disponer de .NET Core en la máquina de los usuarios. Se obtiene un ejecutable (de tamaño considerable, eso sí), que es lo único que se necesita distribuir y funcionará sin problema en todos los equipos.

Docker

Las imágenes de Docker para .NET Core 2.1 están disponibles en microsoft/dotnet en Docker Hub . Se han consolidado el conjunto de repositorios de Docker Hub que utiliza Microsoft para .NET Core y ASP.NET Core. A partir de ahora se utilizará microsoft/dotnet como el único repositorio en el que Microsoft publicará imágenes de .NET Core 2.1 y versiones posteriores.

Se han añadido un conjunto de variables de entorno a las imágenes .NET Core para que sea más fácil alojar sitios ASP.NET Core con cualquier imagen de .NET Core y para habilitar el dotnet watch en las imágenes del contenedor del SDK sin necesidad de configuración adicional.

Los ejemplos de .NET Core Docker se han movido al repositorio dotnet/dotnet-docker de GitHub, y se han actualizado para .NET Core 2.1. Se han añadido nuevos ejemplos, incluido el alojamiento de imágenes ASP.NET Core con Docker a través de HTTPS .

Más detalles aquí.

Compatibilidad de .NET Core 2.1

.NET Core 2.1 es una versión altamente compatible. Las aplicaciones .NET Core 2.0 se ejecutarán en .NET Core 2.1 en ausencia de .NET Core 2.0. Este comportamiento de "upgradde" de versión del runtime solo se aplica a revisiones menores.  Es decir, una aplicación .NET Core 1.1 no hará el salto a 2.0, lógicamente, ni tampoco se pasará en el futuro de .NET Core 2.0 a 3.0 automáticamente. Sin embargo si compilamos una aplicación para .NET Core 2.1 y en el futuro sale .NET Core 2.2 y ésta se ejecuta con esta versión del runtime, no hará falta hacer nada para que lo utilice.

Soporte de instalación de Early Snap

Microsoft ha llevado .NET Core a Snap . Se trata de una tecnología de instalación y aislamiento de aplicaciones muy interesante, pensando sobre todo en dispositivos de Internet de las Cosas (IoT). Las instalaciones Snap funcionan bien en sistemas basados ​​en Debian pero en otras distribuciones Linux como Fedora todavía presentan problemas que Microsoft está intentado solucionar.

En resumen

.NET Core 2.1 es un gran paso adelante para la plataforma. Se ha mejorado muy significativamente el rendimiento, se han añadido muchas APIs así como una nueva manera de crear herramientas para la plataforma. También se ha dado soporte para nuevas distribuciones de Linux y, sobre todo, para ARM32, otro tipo de arquitectura de CPU. Esta versión amplía los lugares donde puede usar .NET Core y la convierte en una plataforma mucho más eficiente en todos ellos.

.NET Core 2.1 está también disponible en Azure App Service.

Post basado en el anuncio oficial del lanzamiento por parte de Microsoft.

Kotlin con curry

31/05/2018
Artículo original

Si no han probado el Curry, deberian, es una especie de mole Indio muy sabroso, y también en programación se usa, principalmente en programación funcional, es increíblemente util y ayuda a tener menos errores y simplificar por mucho el código.

Aqui solo presento un pequeno ejemplo de como usar esta técnica con kotlin y despues lo compararemos con javascript, la verdad con java ya no me gusto :P pero se que se puede.

Simplemente a una lista de precios le calcularemos el Iva del 16%. No se vera mucho la ventaja de porque usar currying pero si como usarlo.

Con kotlin

data class Total(val precio: Double, val iva: Double, val total: Double)

val getImpuesto = { t: Double -> { i: Double -> t * i } }

val getIva = getImpuesto(0.16)

val precios = listOf<Double>(10.2, 12.3, 10.0, 11.0)

val resultados = precios.map({i: Double ->
    val imp = getIva(i)
    Total(i, imp, i + imp)
})

println(resultados)

Eso solo se pega en la función main de Kotlin y la salida es:

 

leer más

Programación funcional: Funciones de primera clase y de orden superior

30/05/2018
Artículo original

(Fotografía de base de la Nave clase Lambda  de Lego por Ben Rollman, CC BY-NC-SA 2.0)

Hoy vamos a conocer otra de las claves que hace a la programación funcional una herramienta verdaderamente potente, que permite simplificar mucho el código y que cada vez llega a más lenguajes: el soporte de funciones de primera clase y las funciones de orden superior. Como siempre, trataré de llegar a todo tipo de programadores, especialmente los que no trabajan frecuentemente con lenguajes funcionales, de forma que veremos ejemplos de aplicación en distintos lenguajes no funcionales.

Funciones de primera clase

Se dice que en un lenguaje las funciones son de primera clase (o que son "objetos de primera clase") cuando se pueden tratar como cualquier otro valor del lenguaje, es decir, cuando se pueden almacenar en variables, pasar como parámetro y devolver desde funciones, sin ningún tratamiento especial. El ejemplo más claro en un lenguaje popular lo encontramos en JavaScript, donde estas operaciones con funciones son muy comunes:

// Asignación a variable
var get_post = function(post_number) {
  return fetch(`https://example.org/posts/${post_number}`)
    // Paso como parámetro
    .then(response => response.json())
    .then(function(data) {
      console.log(data);
    });
};

var custom_exp = function(base) {
  // Valor de retorno
  return function(exponent) {
    return Math.pow(base, exponent);
  };
};

En este ejemplo he usado algunas características modernas de JavaScript: template strings y funciones flecha. Si tienes interés en aprender más tal vez quieras consultar el curso sobre Programacion avanzada en JavaScript y ECMAScript .

Como podemos ver, en JavaScript es natural utilizar funciones como parámetros, valores de retorno y en variables. Esto también es así en otros lenguajes como R o Scala. Muchos otros introducen un tipo de funciones denominadas lambdas (o funciones anónimas), que en ocasiones se comportan de forma distinta a las funciones usuales para permitir esas operaciones. Por ejemplo, en Ruby las lambdas son objetos pero no así el resto de funciones:

def greet who = "Mundo"
  "¡Hola #{who}!"
end

greet2 = -> who { "¡Hola #{who}!" }

greet  # => "¡Hola Mundo!"
greet2 # => #<Proc:... (lambda)>

En el ejemplo anterior, greet no hace referencia a la función sino que la ejecuta, devolviendo el mensaje "¡Hola Mundo!", mientras que greet2 sí nos indica que es un objeto de tipo Proc, el cual se puede pasar como argumento, devolver, etc.

Una aplicación interesante de la propiedad de funciones de primera clase es escribir versiones parcialmente aplicadas de otras funciones. Por ejemplo, supongamos que queremos evaluar la función de densidad de una distribución normal para una media y desviación dadas. Podríamos escribir nuestra función de la siguiente manera:

function gaussian(mean, variance, x) {
  return 1 / Math.sqrt(2 * Math.PI * variance) *
    Math.exp((x - mean)**2 / (-2 * variance));
}

Esta implementación nos impide reutilizar la media y la varianza de la distribución para evaluar en varios puntos sin escribir de nuevo los parámetros. En su lugar, consideremos la siguiente versión:

function gaussian_alt(mean, variance) {
  return function(x) {
    return 1 / Math.sqrt(2 * Math.PI * variance) *
      Math.exp((x - mean)**2 / (-2 * variance));
  };
}

var standard_normal = gaussian_alt(0, 1);
console.log(`N(3 | 0, 1) = ${standard_normal(3)}`);

Ahora podemos reutilizar la standard_normal tanto como queramos. Esto es aplicable a muchas otras situaciones donde conviene que nuestras funciones estén parametrizadas a varios niveles y podamos proporcionar los argumentos poco a poco. En ocasiones, el lenguaje proporciona la funcionalidad necesaria para obtener dichas versiones parcialmente aplicadas sin necesidad de reescribir la función:

// Aplicamos la media y varianza
standard_normal = gaussian.bind(null, 2, 1);
console.log(`N(3 | 0, 1) = ${standard_normal(3)}`);

La sintaxis para la aplicación parcial de funciones suele diferir entre lenguajes: en JavaScript usamos bind como en el ejemplo, en C++ está disponible std::bind, en Python functools.partial...

Funciones de orden superior

Cuando una función no recibe otras funciones como parámetro, se la denomina de primer orden. En el caso en el que sí las reciba, se llama de orden superior.

Muchos lenguajes nos proveen con una serie de funciones de orden superior para trabajar con estructuras de datos. De entre ellas, las más conocidas son map y reduce: la primera aplica la misma función sobre cada elemento de una colección, y la segunda acumula los elementos en un único valor según una función dada. Veamos un ejemplo:

const list = [1, 2, 3, 4, 5];

const squared = list.map(x => x ** 2);
// => [1, 4, 9, 16, 25]

const product = list.reduce((acc, item) => acc * item, 1);
// => 120

Es importante notar que map no modifica la colección original sino que devuelve una nueva, esto se verifica también en la mayoría de lenguajes que la proporcionan. También es de uso común una función filter, que seleccione elementos mediante un predicado booleano:

const even = list.filter(x => x % 2 == 0);
// => [2, 4]

Casos interesantes de uso de funciones de orden superior son el módulo Enumerable de Ruby, los métodos de la interfaz Stream de Java y los decoradores de Python.

Una última función de orden superior que resulta muy obvia pero no siempre viene integrada en los lenguajes es la composición de funciones. En JavaScript, por ejemplo, podríamos implementar la composición de dos funciones como sigue:

const comp2 = (f, g) => ((...arg) => g(f(...arg)));
const abs = comp2(x => x * x, Math.sqrt);
abs(-4); // => 4

Para componer más de dos funciones, podemos componerlas dos a dos aprovechando el ejemplo anterior y una variante de la función reduce que acabamos de aprender:

const compose = function(...functions) {
  return functions.reduceRight(comp2);
};

// Las funciones se aplican de derecha a izquierda
const f = compose(Math.floor, Math.log, Math.max)
f(10, 20) // => 2

Relación

Los lenguajes que tienen funciones de primera clase ya proporcionan la funcionalidad suficiente para tener funciones de orden superior; sin embargo, un lenguaje con funciones de orden superior no necesariamente tiene funciones de primera clase.

Por ejemplo, en Ruby hemos visto que las funciones se deben tratar de forma especial para poder pasarlas como parámetro o almacenarlas en una variable, así que no son objetos de primera clase. Además, otros lenguajes proporcionan sólo parte de la funcionalidad, puedes consultar el soporte en esta tabla.

En este artículo hemos aprendido a aprovechar características funcionales disponibles en gran parte de los lenguajes de programación, espero que te sirva para facilitarte el trabajo de ahora en adelante.

7 motivos para utilizar Docker en general y con ASP.NET Core en particular

28/05/2018
Artículo original

Microsoft ama a Docker - Imagen ornamental

Como explicamos ya hace un par de años en el artículo ¿Qué es Docker?, el objetivo de Docker es permitirte la creación "paquetes estándar" pensados para despliegue llamados "contenedores" que incluyen todo lo necesario para que una aplicación funcione (dependencias, servicios...) y que se aíslan del sistema subyacente para lograr que siempre funcionen exactamente igual.

Docker no es el único sistema de contenedores. Ni siquiera es el primero. Pero se ha convertido en el estándar de facto, y el que tienen en cuenta todos los fabricantes y proveedores de sistemas operativos y de Cloud.

Cuando se piensa en Docker, por lo general no se asocia con tecnologías Microsoft como .NET o Windows, pero en realidad existen un montón de buenos motivos para usar Docker con ASP.NET, especialmente con .NET Core y .NET Core MVC.

En este artículo vamos a repasar las principales razones para utilizar Docker en general en tu proceso de desarrollo, y Docker con .NET en particular, mostrándote cómo te puede ayudar en tus desarrollos.

1.- Olvídate del sistema operativo y las configuraciones manuales

Normalmente cuando configuras una máquina física o virtual, tienes que instalar el sistema operativo, el software que necesite tu aplicación (servidor web, SDKs, bibliotecas,...) y realizar las configuraciones específicas que necesite la aplicación.

Si usas Docker puedes especificar todo esto en tu dockerfile y cada vez que se arranca el entorno, garantizará que el software apropiado esté instalado en el contenedor.

Cuando se necesiten actualizaciones, puedes actualizar simplemente la definición del contenedor y volver a desplegarlo. Esto puede disminuir mucho los tiempos de mantenimiento.

2.- Adiós al "Pero... en mi máquina funciona"

Si trabajas en programación lo has dicho muchas veces seguro. Y si también estás en el otro lado te lo habrán dicho muchas más veces todavía.

Y es que no hay nada más frustrante que tener una aplicación lista y más que probada (en tu máquina) y llevarla a producción y que empiece a fallar. Y luego averiguar el motivo :-S

Bueno, pues con Docker eso se acabó. Lo que te ofrece es, sobre todo, consistencia. Garantía de que lo que va dentro de un contenedor se va a ejecutar de la misma manera en tu máquina y en cualquier otra del mundo, aquí y en la China. Y eso vale millones.

Si funciona en desarrollo, funcionará en producción porque son la misma cosa.

3.- Mucho más ligero y escalable que una máquina virtual

Cuando defines una máquina virtual tienes que especificar cuántos recursos (memoria, procesadores, disco...) de la máquina host vas a destinar en el momento en el que la creas. Esos recursos además dejan de estar disponibles para el sistema operativo subyacente.

Por el contrario, un contenedor Docker utiliza tan solo los recursos que necesita en cada momento. Y además se pueden desplegar varias instancias del mismo contenedor al mismo tiempo, sin que la única opción sea darle más y más recursos de hardware a un contenedor pre-existente.

Además, puedes controlar el consumo de los recursos del host a los que tendrá acceso un contenedor o conjunto de ellos. Si un contenedor en concreto está sobrepasado de capacidad porque tiene mucho uso, no acaparará todos los recursos de la máquina ni hará que se caigan otros contenedores en ese host.

Transformar un único contenedor Docker en una granja en ejecución no podría resultar más sencillo. Solo es cuestión de actualizar los archivos docker-compose.yml con instrucciones sobre cuántas instancias del contenedor se deben ejecutar y cómo, y crear un contenedor para usar como proxy inverso y balanceador de carga. NGINX ha creado muchas imágenes prefabricadas para ayudarte en este escenario, por ello la mayoría de las veces solo hay que añadir ese contenedor al archivo compose y configurarlo.

Si además quieres características más potentes, Kubernetes te permite orquestar todos tus contenedores, monitorizarlos, asegurarlos, ejecutarlos periódicamente, y muchas cosas más, para crear entornos empresariales con la complejidad que necesites.

4.- Tan seguro como una máquina virtual

Los contenedores Docker usan los recursos de la máquina host, pero tienen su propio entorno de tiempo de ejecución (runtime). Disponen de una versión reducida del espacio de usuario del sistema operativo. Esto significa que puedes asegurar un contenedor de una forma muy similar a la que utilizarías en una máquinas real, ya que en el fondo es casi como si fuera una máquina real.

Un contenedor no puede acceder a otros contenedores ni al sistema operativo subyacente (a excepción de los volúmenes de almacenamiento a los que les des permiso), y se comunicará con otras redes y contenedores, con la configuración de red concreta que le quieras otorgar.

Además, si le das acceso a una carpeta o unidad del sistema operativo host, lo verá realmente como si fuera una carpeta en su sistema operativo interno, no teniendo constancia (ni acceso) de nada de lo que haya en la ubicación original fuera de esa carpeta.

Quédate con que un contenedor te aísla tanto como una máquina virtual, pero es mucho menos pesado, requiere menos configuración y además puede abrir "agujeros de gusano" a carpetas concretas si lo necesitamos, con total seguridad.

5.- Control de versiones para la Infraestructura

Para mí este es un concepto rompedor. Siempre se piensa en control de versiones para el código fuente, claro. Pero teniendo en cuenta que en Docker (y Kubernetes) todo se gestiona mediante archivos de texto plano, y esto es lo único que necesitas para desplegar, pueden ir al control de código fuente también.

Esto significa que, en la práctica, ¡puedes versionar tu infraestructura!.

Cuando actualizas una versión del software requerido para ejecutar la aplicación que veíamos en el apartado anterior (servidor web, bibliotecas, etc.), ese entorno se actualiza junto con el código de la aplicación.

Esto es muy útil cuando estás intentando saber por qué una versión anterior de una app tenía un comportamiento determinado: simplemente tienes que ir a la versión de ese código que te interese, iniciar el contenedor Docker y tienes replicada la aplicación y la infraestructura. Genial.

6.- Concebido para trabajar en la nube

Los contenedores se pensaron con la nube en mente. Y en la actualidad los principales actores Cloud, ofrecen estupendas opciones para el despliegue de contenedores en sus infraestructuras.

Así, tanto Amazon Web Services, como Microsoft Azure o Google Compute Engine (entre muchos otros) te permiten desplegar contenedores en la nube desde la comodidad de tu silla, usando la línea de comandos o herramientas visuales. Incluso te permiten facturar los contenedores por segundos, lo cual abre un mundo de posibilidades.

Además todos ellos soportan Kubernetes para poder hacer despliegues complejos de múltiples contenedores orquestados para trabajar y escalar de manera independiente.

Desplegar infraestructuras simples o complejas nunca ha sido tan fácil que ahora.

7.- Ventajas concretas para .NET

Otra de las ventajas de Docker es que puede utilizarse para unificar también los entornos de desarrollo y el flujo de trabajo en éstos. Es decir, ni siquiera tienes que instalar en tu equipo los SDKs de trabajo, ni los compiladores: definís un entorno de trabajo basado en imágenes Docker para todo el equipo, y os aseguráis de que todos tenéis exactamente lo mismo y que todo funcionará exactamente igual. Microsoft está contribuyendo mucho a la comunidad Docker, y ofrecen una integración muy buena de Docker y estos flujos de trabajo en sus herramientas para desarrolladores, tanto en Visual Studio y Visual Studio Code, como en Team System.

Si creas aplicaciones .NET Core, y en especial aplicaciones web con .NET Core MVC, pueden funcionar en contenedores Linux de la misma manera que cualquier aplicación de lenguajes com Node.js, Go, PHP u otros que tradicionalmente se han usado en este sistema.

Desde hace ya tiempo, los contenedores tradicionales Linux funcionan en Windows Server (y en Windows 10: no necesitas Linux o Mac para trabajar con Docker), pero es que además ahora existen también contenedores nativos de Windows, que te permiten ejecutar en forma de contenedor aplicaciones de este sistema operativo. Esto implica que si, por ejemplo, tienes una aplicación antigua de ASP.NET Web Forms, podrás utilizarla dentro de un contenedor y obtener todas las ventajas que ello te brinda y que hemos repasado más arriba, combinándola a lo mejor con contenedores de otro tipo de aplicaciones, y desplegándolos en la nube.

De hecho, como sabes, ASP.NET Core utiliza Kestrel para servir las aplicaciones, y debes usar algún proxy inverso para Kestrel para dotarlo de las capacidades de un servidor de aplicaciones real. Si tus aplicaciones se despliegan en contenedores, puedes conseguir esto de muchas maneras estandarizadas: desde utilizar un proxy NGINX específico partiendo de una imagen ya hecha, a utilizar Ingress en Kubernetes.

Aunque Docker se creó en y para Linux, su uso en .NET y Windows no para de crecer y es cada vez mejor. Microsoft trabaja muy de cerca con el equipo de Docker y su comunidad.

Espero que te haya aclarado las principales ventajas de usar Docker y que tengas ganas de desarrollar y desplegar tu siguiente aplicación en .NET (o en otra plataforma o lenguaje) en un contenedor Docker. Honestamente creo que en los próximos años todas las aplicaciones web se van a desplegar usando Docker. Y muchas otras también.

Y recuerda, si tienes interés en aprender a fondo tanto Docker como Kubernetes, tenemos el curso que necesitas.

Programación funcional: Inmutabilidad y funciones puras

24/05/2018
Artículo original

Anteriormente en este blog ya hemos hablado de programación funcional, concretamente sobre currificación y pattern matching. En esta ocasión estudiaremos un par de conceptos adicionales de la programación funcional y veremos cómo se pueden aplicar a la programación cotidiana.

Inmutabilidad de objetos

La inmutabilidad es la propiedad que tiene un objeto que no puede cambiar su estado. Como consecuencia, la inmutabilidad aporta muchas facilidades a la hora de razonar sobre nuestro código, ya que nos libera de pensar en los cambios sufridos por objetos a lo largo del programa. Además, los objetos inmutables son automáticamente seguros en hilos (o thread-safe), ya que pueden ser accedidos de manera concurrente sin consecuencias, al no poder modificarse.


Foto: "Inmutable" de dominio público.

En programación orientada a objetos generalmente asumimos que el estado de un objeto puede cambiar según los métodos que se llamen sobre el mismo. Sin embargo, en ocasiones podemos construir clases que den lugar a objetos inmutables. Aunque a priori esto pueda parecer poco útil, veamos algunos ejemplos de lo que se puede hacer aprovechando la inmutabilidad. En Java, por ejemplo, la clase String es inmutable:

String saludo = new String("¡Hola campusMVP!");

// no modifica la cadena:
saludo.replaceAll("Hola", "Buenas");

Aunque podríamos esperar que la cadena ahora contuviese "¡Buenas campusMVP!", no es así, sino que el método ha devuelto una nueva cadena:

saludo = saludo.replaceAll("Hola", "Buenas");

Ahora la cadena referenciada por la variable saludo sí contiene el resultado esperado, pero en un objeto distinto al inicial.

Nota: dadas sus ventajas, la inmutabilidad de las cadenas de texto es algo que comparten muchos lenguajes de programación y que no es exclusivo de Java. También lo son en C#, C++, Perl, Python... ¡Incluso JavaScript!

En Java podemos crear nuestras propias clases inmutables con la palabra clave final, que evita que haya clases descendientes, y usando métodos que no cambien el estado de los datos miembro. Por ejemplo:

public final class Person {
  private final String name;
  private final int age;

  // ...
}

En otros lenguajes, la inmutabilidad es una característica clave diferenciadora. Por ejemplo, R, un popular lenguaje orientado a análisis estadístico, es conocido por su extenso uso de la inmutabilidad, sin ser puramente funcional. En Rust, todas las variables son por defecto inmutables. La mayoría de lenguajes funcionales incorporan inmutabilidad y ausencia de variables, de forma que un identificador sólo puede hacer referencia a un valor y ese valor no se puede modificar.

En cualquier caso, la idea de usar objetos inmutables puede ser útil en diversos contextos, para proporcionar mayor seguridad y eficiencia así como facilidades para concurrencia sin necesidad de sincronización.

Funciones puras

Los lenguajes funcionales generalmente tratan de asegurar la transparencia referencial, es decir, que cualquier expresión del lenguaje se pueda sustituir por su valor sin que eso altere el comportamiento del programa. Para ello son necesarios objetos inmutables, pero también funciones que siempre devuelvan el mismo valor ante las mismas entradas.

Por ejemplo, consideremos una función que cuenta los caracteres de una entrada por pantalla, que se correspondería con el siguiente código Python:

def input_length():
  len(input())

¿Podemos asegurar que la llamada input_length() devolverá siempre el mismo valor? No, puesto que el usuario podría introducir distintas cadenas. Esto se debe a que la función accede a información externa a los parámetros que recibe.

Adicionalmente, una propiedad deseable sería que una función no modificase elementos fuera de su ámbito, es decir, no tuviese efectos secundarios, como pueden ser escribir a un archivo o modificar variables globales. Una vez que una función siempre devuelve las mismas salidas para las mismas entradas y no tiene efectos secundarios, se la denomina función pura.

Las funciones puras son útiles porque se pueden ejecutar desordenadamente y en paralelo, cuando no hay dependencias de parámetros entre ellas. Ejemplos de estas son cualquier función matemática y algoritmos deterministas. Son funciones impuras, por otro lado, los generadores de números aleatorios.

Espero que este artículo te haya ayudado a entender las ventajas de usar ideas provenientes de la programación funcional, y que las puedas aplicar en tu día a día de la programación.

Fuentes y más información:

Angular 6: un repaso a las novedades

22/05/2018
Artículo original

El pasado 3 de Mayo de 2018 se publicó oficialmente la versión 6 de Angular bajo las palabras:

The first release of Angular that unifies the Framework, Material and CLI.

Esta frase resume perfectamente la finalidad que persigue esta release, en la cual se hizo un gran esfuerzo por parte del equipo de Angular por aunar el framework, la biblioteca de estilos y la línea de comandos en una misma versión, la 6.0.0.

Superman con un logotipo de Angular

Novedades

A continuación encontrarás un resumen de las principales novedades de esta nueva versión centrándonos tanto en el framework (que puede ser lo que más te interese) como en la línea de comandos (la parte que más novedades ha recibido).

Para ver el log completo de lo que se ha introducido en esta versión te invito a leer el CHANGELOG de Angular.

TypeScript 2.7 y RxJS 6

Este punto puede que sea el más conflictivo porque abarca los denominados Breaking Changes o cambios no compatibles con anteriores versiones.

Por suerte Angular 6 ha introducido pocos cambios que afecten a su "exterior", es decir, a la manera de utilizarlos, y éstos son bastante suaves.

La principal incompatibilidad surgió de un cambio en los imports de RxJS 6, la biblioteca para desarrollo Reactivo de Angular, ya que se simplificaron las rutas de cada una de las clases (Observable, por ejemplo) y operadores (map, por ejemplo).

Este cambio resulta en la siguiente actualización:

// Angular 5 Observable
import { Observable } from 'rxjs/Observable';

// Angular 6 Observable
import { Observable } from 'rxjs';

Como ves, el cambio es mínimo de cara a nosotros, los desarrolladores. Pero por detrás esto da como resultado una optimización en el tamaño del paquete que se genera, aspecto muy importante en los frameworks de hoy en día, que sufren continúas comparaciones sobre lo rápidos / pesados que son.

Dicho esto, es comprensible que si tu código es de un tamaño considerable o tienes también que dar soporte a diferentes bibliotecas, sea un cambio como mínimo tedioso de implementar, ya que hay detalles (como bibliotecas externas) que no dependen de ti. RxJS 6 ofrece una utilidad para aliviar esa transición y ayudarte poco a poco a introducir los cambios que tu código necesite a través de la biblioteca rxjs-compat, instalable como siempre desde NPM.

Esta biblioteca te permitirá mantener el mismo código durante tu transición.Eso sí, es altamente probable que para la versión 7 (sin fecha todavía) ya no tengas que hacer uso de esta biblioteca.

Angular Elements

Angular 6 también introduce gratas sorpresas como la de Angular Elements. Este nuevo proyecto entra para quedarse ya que son la entidad con la que trabaja Angular para dar soporte a los Custom Elements, una de las patas de los cada vez más famosos Web Components.

La finalidad de estos Angular Elements es que por debajo generen Custom Elements (que no Web Components) que puedan ser reutilizados, no sólo en otros proyectos de Angular, sino incluso en cualquier proyecto JavaScript a través de "Vanilla JavaScript" (o sea, JavaScript puro y duro).

Por otro lado, aunque es un proyecto que suscita un gran interés, no te recomiendo su uso actualmente en producción ya que seguramente se esperen cambios (costosos o no) sobre estos elementos. Pero te animo a probarlos o como mínimo a investigar sobre ellos ya que es una parte de la Web que está cogiendo una relevancia considerable como estándar (que se dice pronto) en los últimos años.

Si te ha interesado este punto te invito a ver una charla del equipo de Angular Firebase en la que tratan los Angular Elements.

Ivy

Angular lleva un tiempo preparando un nuevo motor de renderizado llamado Ivy mucho más pequeño que el actual y que se traducirá en una disminución aún mayor del tamaño de tu aplicación. En esta nueva versión no ha habido novedades sobre este motor, pero seguramente oigamos alguna muy pronto, puede que incluso antes de la versión 7.0.0.

Angular CLI: ng add y ng update

Este es quizás el punto clave de Angular 6 y la motivación de esta release.

El principal cambio que ha sufrido angular-cli es un cambio de concepto. Ahora al ejecutar un ng new ya no podemos hablar de la generación de un proyecto o una carpeta, sino de la creación de un workspace completo en el que poder alojar múltiples aplicaciones. Esto para los desarrolladores nos ofrece un juego y un dinamismo a la hora de desplegar o simplemente "arquitecturizar" nuestras aplicaciones a un nivel muy interesante.

Además el equipo de Angular no sólo han querido aunar sus propias aplicaciones (el framework, la biblioteca de Material, el CLI...) sino que quiere que la comunidad también participe en esa unificación y se mantenga actualizada. Este compromiso lo quieren conseguir a través del comando ng update y ng add. El primero aunque puede parecer el mismo que antes a simple vista, ahora es mucho más potente, ya que las bibliotecas externas pueden suscribirse a este comando y actualizarse automáticamente con la aplicación.

Por otro lado, con ng add se busca evitar esas configuraciones iniciales que muchas veces se sufren al instalar una biblioteca nueva. Lo que se persigue es que simplemente con ejecutar un comando se tenga todo preparado para trabajar.

¿Sabías que... nuestro curso de Angular ya está actualizado con las novedades de esta versión? ¡No te lo pierdas y domina Angular en poco tiempo y creando una aplicación real!

Acceso visual a tareas de npm desde Visual Studio Code

18/05/2018
Artículo original

Creo que ya he dicho en más de una ocasión aquí lo mucho que me gusta Visual Studio Code y que, con el tiempo, se ha convertido en mi editor principal (y casi único). Cada mes lanzan una nueva actualización que ya estoy esperando con ansia porque siempre viene con novedades interesantes. Algunas más grandes y otras más pequeñas, como es el caso de la que nos ocupa hoy.

En la última actualización, la 1.23 de Abril, hay muchos detalles interesantes, pero hay uno que me ha llamado especialmente la atención: la posibilidad de tener una lista en el lateral con todas las tareas definidas en el archivo package.json de Node.js (tareas de npm):

Como vemos, en el explorador de archivos aparece una nueva sección llamada "npm scripts" en la que se listan todas las tareas que tienes en el package.json y puedes abrirlas para verlas, ejecutarlas o incluso depurarlas usando el menú contextual de cada una de ellas.

Cuando manejas muchas de ellas y no las usas todas a menudo, es interesante porque te evita tener que abrir el archivo y ponerte a revisarlas. Y es muy cómodo tener esas acciones ahí para editarlas, lanzarlas o depurarlas.

Esta sección está desactivada por defecto. Para poder sacarle partido hay que habilitarla desde la configuración del entorno. En concreto buscando la opción npm.enableScriptExplorer, de la manera que muestro a continuación en este vídeo muy cortito:

¡Espero que te resulte útil!

¿Seré capaz de convertirme en un buen desarrollador si no programo en mi tiempo libre?

18/05/2018
Artículo original


Foto por Ian Schneider en Unsplash

No sé cómo será en otros países de habla-hispana, pero en España existe, por lo general, la costumbre (mala, en mi opinión) de hacer más horas en la oficina que las estipuladas por contrato. Casi nadie se va a su hora del trabajo, pues está mal visto en muchas empresas y por muchos jefes. Incluso en muchas empresas de programación se espera que estés sentando en tu ordenador aunque no estés programando, porque todo el mundo sabe que es imposible estar más de 8 horas efectivas escribiendo código de calidad.

Y en aquellas pocas empresas de programación donde sí existe la cultura de salir a la hora salvo emergencias o vísperas de plazos, hay trampa. ¿En qué consiste? Pues lo normal en estos casos es que exista cierta expectativa de que mejores por tu cuenta para convertirte en un gran programador. Para ello se te invita a participar en proyectos de código abierto, a modo formativo, o a programar en proyectos de desarrollo internos como en la creación de apps móviles para los miembros de la empresa. Todo en tu tiempo libre claro.

Esto no quiere decir que tengas que dedicarle TODO tu tiempo libre, pero sí tienes que hacerte a la idea de que algo de tiempo le vas a tener que dedicar, en ocasiones mucho más que otras. Y lo normal es que te apetezca, porque llegados a ese punto sentirás curiosidad por aprender ¿o no?

En otras palabras, si te gusta la programación, pero quieres tener un horario regular, predecible, y no le quieres dedicar tiempo fuera del lugar de trabajo, te puede surgir la siguiente duda: ¿seré capaz de convertirme en un buen desarrollador si no programo en mi tiempo libre?

Esta pregunta no tiene una respuesta única, pero detrás de la misma hay muchas más cosas implícitas que debes tener en cuenta a la hora de valorar la decisión de convertirte profesionalmente en desarrollador de software.

Vayamos por partes.

La mejoría no es lineal, es logarítmica

Al igual que nadie puede programar en el trabajo 8 horas seguidas con una productividad lineal, por muchas horas que le dediques a la programación, tu mejoría tenderá a tener un rendimiento decreciente y tu curva de mejora será logarítmica. La gestión del tiempo es una las cuestiones implícitas en la pregunta anterior.

Si eres capaz de gestionar bien tu tiempo como programador de software y trabajas 40 horas a la semana, tienes suficiente tiempo para hacer tu trabajo y dedicarle unas horas a la semana a aprender a hacer cosas nuevas relacionadas con el puesto o con otros puestos de la empresa, todo en horario laboral.

Si te organizas mal y siempre vas fatal con tus plazos de entrega, lógicamente tendrás que hacer cosas fuera del horario laboral para mejorar. Si este es tu caso, te recomiendo que antes inviertas esfuerzos en mejorar la forma en la que gestionas el tiempo, incluso con formación específica para lograrlo. Para ser un buen profesional en cualquier trabajo tienes que aprender a gestionar el tiempo. Por buen programador que seas, si no gestionas bien el tiempo, profesionalmente cotizarás a la baja.

Como decía un poco más arriba, si te organizas bien, no deberías tener problemas. Tomemos el ejemplo de un músico para ilustrar esta afirmación. Muchos pianistas o violinistas practican 8 horas diarias o más, pero es en las primeras 3 ó 4 horas donde se aprecia una mejora sustancial en relación con el ensayo anterior, siempre que el ensayo se haga con la máxima concentración y dedicación plena. A esta conclusión llegó el psicólogo e investigador Anders Ericsson en un estudio llevado a cabo en Alemania en 1993.

En el estudio sobre jóvenes violinistas, el investigador sobre rendimiento descubrió que todos los mejores practicaban de la misma manera: por la mañana, en tres sesiones de ensayo de no más de 90 minutos cada una, con un descanso entre cada una de ellas. Ericsson a posteriori encontró el mismo patrón entre otros músicos, atletas, jugadores de ajedrez y escritores.

Es posible que te preguntes por qué, entonces, los músicos profesionales ensayan 8 horas diarias. La respuesta es sencilla. Supongamos que en las primeras 4 horas mejoran un 0,5% con respecto al día anterior y que en las siguientes 4 horas mejoran un 0,01%. Ese 0,01% les sigue compensando pues como músicos su trabajo es mejorar cada día.

Pero a ti, como programador profesional que además tienes que llevar a cabo tus tareas en el lugar de trabajo, esas horas de más no te compensan. En ese tiempo es mejor hacer otras cosas para desconectar y cargar energías, aficiones, ejercicio, o simplemente descansar.

Ericsson se ha hecho muy popular recientemente por un estudio, al parecer polémico, que afirma que para llegar a ser un experto en cualquier cosa, tienes que dedicarle 10.000 horas. La famosa regla que establece que llegar a ser realmente competente en algo lleva unas 10.000 horas/10 años, también proviene de los estudios hechos por el mismo investigador.

Como todos sabemos, puedes tener 1 año de experiencia multiplicado por 10, pero estar calentando la silla todo ese tiempo no cuenta. Lo que sí cuenta es lo que Ericsson llama el ensayo deliberado, es decir, practicar y ensayar con intensidad, concentración y dedicación plena.

Él ha concluido que esta forma de ensayar también se aplica en atletismo, música, escritura, ajedrez, y matemáticas. Además, define la práctica deliberada como un esfuerzo tan grande, que incluso en los niveles más altos de pericia sólo se puede ejercitar alrededor de 4 horas al día. De lo contrario, se sufre un agotamiento a corto plazo. En otras palabras, tras 4 horas de dedicación plena a la práctica de cualquier actividad, se empiezan a obtener rendimientos decrecientes. El principio de los rendimientos decrecientes en el mundo empresarial es muy conocido, pero quizás no se aplica del todo en relación con los horarios de oficina en las empresas.

En este punto podemos concluir que una buena gestión del tiempo te permite guardar algunas horas semanales para dedicarle a la mejora continua dentro la propia jornada laboral, y te permite tener tiempo libre, que puedes invertir en aprender y en trabajar cuando el trabajo te lo exija, pero también en tus aficiones y en desconectar del trabajo para afrontarlo con mayor motivación.

La curiosidad como activo

Otro concepto que subyace bajo la pregunta "¿seré capaz de convertirme en un buen desarrollador si no programo en mi tiempo libre?" es el de la motivación por descubrir cosas nuevas y ver cómo funcionan.

A muchos programadores entusiastas y motivados precisamente lo que les gusta es explorar, experimentar, hacerse sus propias ideas sobre las cosas. Es así como aprenden y obtienen sus destrezas y su visión de las cosas. Si sale una nueva tecnología y les pica la curiosidad, tienen que probarla, no les basta con leer un artículo de un blog.

Por lo general, los programadores tienen curiosidad por tecnologías que no están directamente relacionadas con las herramientas de desarrollo que usan en su trabajo. Si vas muy sobrado puedes dedicarle tiempo con el permiso de tu jefe, pero no es lo habitual. Si te sobra tiempo en el trabajo, haces lo que se menciona anteriormente en este artículo: formarte en tecnologías que sean útiles para la empresa.

Algunos programadores a medida que adquieren experiencia acaban por tener muy claro con qué tecnologías quieren trabajar y qué tipo de proyectos les gusta hacer. En ese punto estás en una posición de poder elegir, pero cuando empiezas no tienes esa suerte, ni tampoco sabes muy bien qué es lo que de verdad te gusta en la mayoría de los casos. Cuando llegas a ese punto en tu carrera, ya no distingues muy bien qué es trabajo y qué es afición, puesto que se confunden.

Por lo tanto, si no estás haciendo nada extra porque no sientes curiosidad ni motivación, no estás desarrollando todo tu potencial. Y quizás ese sea el problema.

El hecho de no programar en tu tiempo libre no te convierte en un mal desarrollador. Sin embargo, programar en tu tiempo libre te puede hacer sin duda alguna un mejor desarrollador.

Dedicarle tiempo a la programación en tu tiempo libre lógicamente mejorará tus habilidades, pero no tienes que sentirte obligado a hacerlo siempre. La verdad es que la programación parece ser un campo profesional como pocos, porque para muchas personas es su trabajo y su afición, por lo que disfrutan de la programación en su tiempo libre.

Conclusión

Desde mi punto de vista, si quieres llegar a ser buen programador, la flexibilidad junto con una buena gestión del tiempo son fundamentales.

Tienes que estar dispuesto a sacrificar tu tiempo libre tanto para sacar un proyecto de desarrollo en plazo como para aprender nuevas tecnologías y trastear con ellas. Si no "amas" la programación lo suficiente para adaptar tus horarios al trabajo y a la formación continua (en la oficina cuando se pueda y en casa cuando no), quizás este oficio no sea para ti.

Claro que puedes ser un buen programador si solo programas en la oficina, sobre todo si sabes gestionar bien tu tiempo y tomas buenas decisiones para tu carrera profesional. Sin embargo, los mejores desarrolladores también hacen cosas en su tiempo libre.

De todos modos, si eliges buenos puestos de trabajo en cada momento de tu vida profesional, con muchas oportunidades de aprendizaje, gestionas bien tu tiempo en el trabajo y demás, puedes incluso llegar a ser mejor programador que alguien que programa mucho en su tiempo libre porque no consigue buenos puestos o no está en entornos que promuevan el aprendizaje continuo o que no estimulen la curiosidad y la motivación para aprender cosas nuevas. Pero a la larga una cosa lleva a la otra, y al final siempre le dedicas tiempo libre porque te gusta.

Los grandes programadores aprenden tanto en la oficina como en casa, y siempre muestran buenas destrezas de aprendizaje y hacen en muchos casos de mentores de programadores más inexpertos.

Configurar Eclipse/Java para programadores de Visual Studio/C#

16/05/2018
Artículo original

Los que venimos del mundo C++ primero, y C# después, estamos muy acostumbrados a Visual Studio. Así que, cuando nos toca trabajar en Eclipse con Java, nos sentimos como un cerdo en una piscina de barro: nos suena familiar y es divertido, pero no estamos cómodos del todo.

Este post es un resumen de todos los cambios y personalizaciones que he realizado a mi Eclipse en los últimos años para que el desarrollo con Java sea lo más parecido posible a C# con Visual Studio.

Nota: algunos de los cambios que se mencionan son meramente estéticos, mientras que otros afectan al estilo y el formato del código, y pueden entrar en conflicto con directrices de cada equipo de desarrollo.

Colores

Lo primero que un desarrollador Visual Studio suele querer cambiar, son los colores que se utilizan para formatear el código.

Para establecer una configuración de colores similar a la de Visual Studio, lo más fácil es utilizar uno de los temas de color disponibles en el Eclipse Marketplace (Eclipse -> Help -> Eclipse Marketplace).

Allí se pueden buscar temas de color relacionados con Visual Studio e instalar el que más convenga (Windows -> Preferences -> General -> Appearance -> Color Theme):

Si se desea cambiar algún color individual, puede hacerse en: Windows -> Preferences -> Java -> Editor -> Syntax Coloring:

Otros colores no incluidos en el tema

Aunque el tema de color configura la mayor parte de aspectos relacionados con el código, para que Eclipse se parezca aún más a nuestro Visual Studio, hay otras configuraciones que es necesario cambiar. En Windows -> Preferences -> General -> Editors -> Text Editors -> Annotations:

  1. Color de los puntos de ruptura en modo depuración

    Los desarrolladores de Visual Studio estamos muy acostumbrados a esas horribles líneas con fondo rojo para los puntos de ruptura. Aunque en Eclipse también se puede configurar el fondo de un breakpoint en rojo, el color del texto permanece intacto por lo que su lectura se complica. Una buena alternativa es la siguiente:

  2. Color de línea activa

    Del mismo modo, cuando la depuración está parada, estamos también acostumbrados a esa horrible línea con fondo amarillo que denota la siguiente línea que será ejecutada. Podemos configurarla en la misma ventana:

Estilo de código

El segundo aspecto que suele resultar más incómodo para desarrolladores C#, es el estilo de código.

Aquí, es más que probable que cada empresa tenga su propia guía de estilo que habrá que respetar, pero si tu prioridad es que tu código Java se parezca lo más posible a C#, puedes lograrlo en la ventana: Window -> Preferences -> Java -> Code Style -> Formatter.

En lugar de ir cambiando cada valor automáticamente, lo mejor es descargar un profile ya creado que configure todo por nosotros. Te dejo para descarga mi profile personal (en formato ZIP, dentro tiene el XML necesario) que contiene gran parte de lo que se menciona en este apartado.

Con respecto a los profiles que suelen encontrarse por Internet, suelen ser necesarios algunos retoques adicionales. Algunos ejemplos:

Deshabilitar Wrapping

Ésta es otra de esas opciones que puede resultar útil en algunos contextos, pero que yo prefiero desactivar.

Hoy en día las pantallas tienen la suficiente resolución como para que las líneas puedan ser largas y a mí personalmente no me importa que se salgan por el margen derecho de la pantalla.

Si hay casos extremos donde eso resulte un problema, prefiero escoger manualmente cuándo y cómo bajar partes de las sentencias a la siguiente línea. Por eso, personalmente prefiero deshabilitar todo tipo de Wrapping.

Se puede ir categoría por categoría activando y desactivando según tus preferencias en la ventana: Window -> Preferences -> Java -> Code Style -> Formatter -> Edit -> Line Wrapping:

Controlar cómo y cuándo se añaden Nuevas Líneas

Para conseguir un comportamiento lo más parecido posible a C# en lo referente a la inserción de nuevas líneas, debemos ir a Window -> Preferences -> Java -> Code Style -> Formatter -> Edit -> New Lines y marcar las opciones de la siguiente imagen:

Establecer los TABS como método de indentación

La indentación por defecto en Eclipse es bastante confusa, y fácilmente terminas con métodos que están “un espacio” más a la derecha o a la izquierda de donde deberían.

Para mejorar esto, suelo preferir indentar únicamente con TABS completos, en: Window -> Preferences -> Java -> Code Style -> Formatter -> Edit -> Indentation

Atajos de teclado

Toda la personalización del mundo no servirá de mucho si los atajos de teclado no son los que tienes costumbre de utilizar.

Un programador necesita esos atajos como respirar. La buena noticia es que Eclipse ya incluye un mapa de atajos que imita el comportamiento de Visual Studio. Puedes configurarlo en: Window -> Preferences -> General -> Keys, seleccionando el esquema “Microsoft Visual Studio”.

Aun así, el mapeo no es perfecto y será necesario retocar algunos atajos a mano.

Hacer que el asistente de contenido se comporte como Intellisense

En Visual Studio, estamos acostumbrados a que Intellisense nos ofrezca alternativas nada más pulsar el punto (.) y continúe ofreciéndolas según vamos tecleando.

Podemos lograr un comportamiento parecido en Eclipse activando y configurando la siguiente opción en Windows -> Preferences -> Java -> Editor -> Content Assist:

Los valores que tenemos que poner son:

  • Auto Activation Delay (ms): 0

  • Auto activation triggers for Java: .(abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ

  • Auto activation triggers for Javadoc: @#

Deshabilitar la navegación de cursor con varios pasos por palabra

Supongo que es cuestión de gustos y que incluso esta opción puede resultar atractiva para mucha gente, pero personalmente estoy muy acostumbrado a que cuando pulso Ctrl+Izda estando sobre el nombre de una variable, el cursor salte hasta el comienzo del nombre completo de la variable.

Eclipse, por defecto, activa una opción que en algunos sitios se conoce como CamelHumps, según la cual el cursor va deteniéndose dentro de la palabra, cuando detecta mayúsculas, como en el siguiente ejemplo:

|LongCamelCaseWrittenWord -> CTRL+RIGHT_ARROW

Long|CamelCaseWrittenWord -> CTRL+RIGHT_ARROW

LongCamel|CaseWrittenWord -> CTRL+RIGHT_ARROW

LongCamelCase|WrittenWord -> CTRL+RIGHT_ARROW

LongCamelCaseWritten|Word -> CTRL+RIGHT_ARROW

LongCamelCaseWrittenWord|

Dicho comportamiento puede desactivarse en la ventana: Windows -> Preferences -> Java -> Editor, desmarcando la opción “Smart caret positioning in Java names”.

Hacer que la tecla Inicio te lleve al comienzo real de la línea

De forma similar al punto anterior, cuando en Eclipse pulsamos la tecla Inicio o Home, el cursor saltará al inicio de la línea, pero con un comportamiento distinto en función de la línea en la que estemos. Por ejemplo, si la línea es un comentario, el cursor se posicionará a la derecha de las barras que inicia el comentario //.

Este comportamiento puede desactivarse en Window -> Preferences -> Editors -> Text Editors, desmarcando la opción “Smart caret positioning at line start and end”:

Habilitar Folding

Lamentablemente, Eclipse no soporta regiones de forma nativa como Visual Studio y C#. Android Studio sí incorpora esta funcionalidad, pero para lograr algo parecido en Eclipse tendríamos que recurrir a plugins (y la mayoría están descontinuados).

Lo que sí podemos habilitar es un folding básico para comentarios, métodos, etc., en la ventana: Window -> Preferences -> Java -> Editor -> Folding

Formato e indentación automática

Visual Studio incorpora una funcionalidad que me encanta: siempre que cerramos una llave, aplica un formateo automático a todo el bloque de código que comprende dicha llave.

No he encontrado una funcionalidad equivalente en Eclipse. Lo más parecido que he visto es la opción de formateo automático al grabar un archivo, en la ventana: Window -> Preferences -> Java -> Editor -> Save Actions.

Se puede aprovechar para activar también otra opción interesante: Organize Imports, que ahorra trabajo a la hora de gestionar los molestos imports de Java.

Configurar cierres automáticos

Al igual que Visual Studio¸ Eclipse permite configurar cómo y cuándo cerrar automáticamente paréntesis, llaves, cadenas de texto y comentarios. En la ventana: Window -> Preferences -> Java -> Editor -> Typing

Configurar comportamiento de Strings

Por defecto, Eclipse realiza algunas tareas cuando se “pegan” cadenas de texto en el código, como wrapping automático o escapar los caracteres que haya en la cadena.

Son opciones que pueden resultar útiles en algunos casos, pero que por lo general resultan incómodas para un desarrollador de Visual Studio. Pueden desactivarse aquí en: Window -> Preferences -> Java -> Editor -> Typing

Desactivar comprobaciones ortográficas

Esto es algo que Visual Studio no hace por defecto y que, aunque puede resultar de gran utilidad para mucha gente, a mí personalmente no me gusta.

Además, y aunque es poco probable que se note, me parece un gasto innecesario de recursos. Prefiero que Eclipse dedique la CPU a reaccionar con la mayor velocidad posible (por ejemplo a la hora de proponer contenidos con su Intellisense) en lugar de a analizar la ortografía de mi código. Podéis desmarcar la opción en: Window -> Preferences -> General -> Editors -> Text Editors -> Spelling:

En resumen

Eclipse y Visual Studio son entornos muy diferentes, pero se puede conseguir que se parezcan bastante con unos cuantos ajustes estratégicamente aplicados. En este caso hemos visto cómo hacer que Eclipse se parezca a Visual Studio, de modo que si eres fundamentalmente programador de C# o C++ y debes empezar a trabajar con Java, no solo te sentirás mucho más cómodo, sino que además tu productividad aumentará al encontrarte como en casa desde el principio.

Recuerda que puedes descargar el siguiente archivo XML para configurar un nuevo profile de estilo de código que imita el utilizado por Visual Studio en C#.

Espero que te resulte útil.

Página Anterior Página Siguiente