Kotlin es oficial en Android ¿Qué implicaciones tiene para los desarrolladores?

26/06/2017
Artículo original

Kotlin Soporte Oficial Android

Como es posible que ya sepas, el pasado 17 de mayo, durante la keynote del Google I/O 2017, Google anunció que Kotlin sería soportado oficialmente como lenguaje para desarrollar aplicaciones Android.

Ya hemos hablado varias veces de Kotlin en Genbeta Dev, y seguramente sabrás que era perfectamente posible desarrollar Apps Android utilizando Kotlin desde hace ya bastante tiempo.

La única novedad que se anunció al respecto es que Android Studio 3.0 ya traería integrado Kotlin, en lugar de necesitar instalar un plugin para ello.

Aparentemente las novedades son pocas. Parece que nada ha cambiado, ¿o sí?

Soporte oficial para Kotlin: ahora ya tienes las espaldas cubiertas

Hasta este momento era un poco complicado justificar ante el responsable técnico de cualquier empresa la inclusión de un lenguaje no oficial.

Los riesgos con Kotlin eran mínimos, como ya han demostrado algunas empresas como Basecamp o Pinterest. Pero el miedo a lo desconocido es muy razonable, y había muchos equipos que se estaban resistiendo al cambio por esta razón.

Android Studio 3.0 incluirá soporte para Kotlin de serie

La realidad era que si algo no funcionaba como debería, Google se podía lavar las manos perfectamente. Es cierto que Jetbrains y el equipo de Kotlin siempre han sido muy rápidos para solucionar cualquier problema que ha surgido, pero la duda siempre estaba ahí.

Esto ya no es así. Un ejemplo muy claro se puede ver en movimientos como este. Al parecer Room, una librería de persistencia que también presentó Google en el I/O, estaba teniendo algún problema con el plugin de generación de código de Kotlin (KAPT).

En el pasado, esto habría supuesto confiar en la gente de Kotlin para que se solucionase. Ahora el propio personal de Google está implicado y hacen evolucionar las herramientas con ello:

Tweet Yigit

Google ahora está involucrado en la evolución de Kotlin, y gracias a ello, los desarrolladores tenemos las espaldas cubiertas

Kotlin ha venido para quedarse

Otra de las dudas que surgían al respecto es que al fin y al cabo Kotlin ha sido creado por Jetbrains, quienes en un momento dado podrían llegar a olvidarse del lenguaje porque no les fuera rentable.

Siempre ha sido un lenguaje open-source, pero es evidente que no es lo mismo que una empresa tenga a 40 personas trabajando a tiempo completo a que lo tenga que mantener la comunidad.

Este problema desaparece de un plumazo también. Jetbrains y Google van a crear una fundación sin ánimo de lucro para preservar que el lenguaje siga siendo abierto y que no haya problemas de este tipo en un futuro.

Las empresas van a empezar a demandarlo aún con más fuerza

Ya había algunas ofertas de trabajo que valoraban conocimientos sobre Kotlin. Pero este lenguaje aplicado al desarrollo de Android era un futuro incierto.

En junio, Kotlin es el lenguaje #39 en Github, #60 en StackOverflow y #43 en TIOBE index

Ahora es el presente, y las compañías están como locas por buscar a personas con experiencia en este lenguaje, y por formar a sus propios empleados.

Claro lo dejan los saltos que está dando el lenguaje en tan poco tiempo en lugares como Github o StackOverflow según The RedMonk, o que haya entrado en el top 50 de los lenguajes más usados según el TIOBE index.

Así que si eres desarrollador Android, piensa en no quedarte atrás mucho tiempo. El mercado de Kotlin está explotando, y es vital moverse hacia el futuro.

¿Google abandonará Java en el futuro? Es posible

Durante el I/O, Google afirmó que seguirá evolucionando el soporte a Java, y que se podrán seguir usando ambos lenguajes para el desarrollo Android. Eso es lo que dijeron de Eclipse como entorno de desarrollo, y con el tiempo esto no fue así.

Y también es cierto que Google ha tenido bastantes problemas legales con Oracle debido a Java.

Kotlin le ha venido como anillo al dedo a Google:

  • Un lenguaje en el que se cubren las espaldas frente a posibles problemas legales
  • No tienen los problemas de verse obligados a anclarse a versiones antiguas del lenguaje
  • Trae al desarrollo Android todas las ventajas de un lenguaje moderno
  • Y además ya está maduro y se ha demostrado su validez en proyectos reales y de gran envergadura.

Imagina todo lo que supone crear un lenguaje desde cero (se podría equiparar al ejemplo de Apple con Swift). A Google le han dado el trabajo hecho.

Nada de esto quiere decir que Java vaya a dejar de ser soportado, ya que su dependencia con el lenguaje es muy grande. Para empezar todo el framework y librerías de Android están implementadas en Java.

Con esta adopción, Google ha conseguido con Kotlin lo que a Apple le está llevando años de trabajo con Swift

Pero es algo que puede llegar a ocurrir, y nunca está de más calcular las consecuencias.

Empieza desde hoy con Kotlin

Kotlin es ya una realidad en el mundo Android, así que te animo a que empieces a aprender Kotlin desde hoy. Si aún eres un poco reticente al cambio, cuando lo pruebes te darás cuenta de todas las ventajas que aporta. Y pronto no querrás volver a mirar atrás.

Si no sabes por dónde empezar, en la web de desarrolladores de Android tienes una pequeña guía por la que empezar, así como una sección de recursos, donde encontrarás recursos, vídeos y libros para empezar con ello.

También te recomendamos

El alucinante proceso que vive tu cerebro cuando ves un programa de cocina

Kotlin: La Máquina Virtual de Java tiene un nuevo aliado

Kotlin llega a Gradle: Escribe tus scripts de Gradle usando Kotlin script

-
La noticia Kotlin es oficial en Android ¿Qué implicaciones tiene para los desarrolladores? fue publicada originalmente en Genbeta Dev por Antonio Leiva .

Solución al problema de pérdida de conectividad en Windows Server con errores de Sockets y espacio de buffer

23/06/2017
Artículo original

Desde hace un par de meses uno de nuestros servidores nos estaba trayendo por la calle de la amargura. Resulta que de manera aleatoria pero con una frecuencia aproximada de 1 semana o semana y pico, de repente empezaba a dar errores con cualquier web que tuviera que hacer conexiones hacia el exterior. Esto significa que todas las webs dinámicas o aplicaciones web que intentasen conectarse con una base de datos, por ejemplo, de repente no podían hacerlo. Lo cual implicaba aplicaciones ca´´idas, páginas web basadas en algún CMS (como WordPress) dando errores de ejecución y no pudiendo servir páginas, etc...

La única solución era reiniciar la máquina. Al hacerlo todo volvía a la normalidad, pero al cabo de unos días o una semana, vuelta a empezar.

El log del sistema no ofrecía información interesante. Mi experiencia me decía que tenía algo que ver con una actualización del sistema operativo. No es la primera vez que la fastidian a base de bien con una. Pero lo cierto es que tenemos muchos servidores y solo pasaba en este en particular, que por otro lado es también el que más tráfico recibe... Un absoluto misterio. Y una desesperación.

El mensaje de error simplemente decía que no se podía conectar a las bases de datos ninguna de las aplicaciones, con algo como esto:

An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full.

 o en español:

Una operación en un socket no se pudo realizar porque el sistema no disponía de suficiente espacio de buffer o porque una cola estaba llena

 

Lo cierto es que para mi esto no tenía ningún sentido. Se trata de una máquina potente, con espacio en disco y memoria más que de sobra. Lo único que hubiera algún programa fuera de nuestro control que estuviese gastando los sockets, abriéndolos sin parar y no cerrándolos...

Efectivamente el problema era este.

Haciendo un netstat no se averiguaba nada útil, pues las conexiones que había eran las normales. Pero de repente me encontré con un detalle interesante: había una unidad iSCSI intentando conectarse todo el tiempo sin éxito.

Todos los servidores hacen las copias de seguridad como mínimo a dos unidades de copia de seguridad diferentes, utilizando iSCSI para ello. iSCSI es un protocolo que permite utilizar espacios de almacenamiento remotos, como si fueran locales. Es decir, tienes un espacio reservado en una unidad de almacenamiento remoto pero tu servidor la ve coo si fuera un disco duro local. Esto tiene diversas ventajas y se suele utilizar mucho (te remito al artículo anterior de la Wikipedia si quieres saber más).

El caso es que una de las unidades de backup se estropeó hace unos meses. Como era vieja decidimos deshacernos de ella y utilizar una de las otras. Pero, el enlace existente entre el servidor y la LUN (la unidad remota) que utilizaba no se rompió. Lo que esto provocaba era que todo el tiempo estuviese intentando conectar con ella:

Esto en condiciones normales, si bien no es lo ideal, no supone tampoco un problema.

El problema surgió el pasado mes de mayo, cuando Microsoft liberó las actualizaciones mensuales de Windows. Éstas incluían el "Monthly Rollup" de Windows, que incluye multitud de parches para varias cosas y que viene incluido también en actualizaciones acumulativas posteriores. Uno de ellos provoca una fuga que provoca que al cabo de un tiempo agoto todos los puertos efímeros del sistema pudiendo llegar a provocar el bloqueo del sistema operativo:

De modo que ahí estaba la causa del problema. ¡Buff! Cualquiera da con ella. Microsoft ha reconocido el problema (como puedes ver en la captura anterior) pero no se da prisa en solucionarlo, puesto que tiene que darse la casualidad de que haya un origen iSCSI no disponible, y no es algo tan frecuente.

Mientras tanto ¿cómo puedes solucionarlo?

Bueno, la solución es bastante obvia: evitar que se intenten las conexiones al LUN mediante iSCSI.

Pero para ello no llega con darle al botón "Desconectar" en la figura anterior. Esto no evitará que cuando se reinicie el sistema, automáticamente se intente la reocnexión de nuevo. Hay que verdaderamente librarse de él.

Ello implica ir a la pestaña "Favourite Targets" y eliminar el servidor de iSCSI remoto de allí con "Remove":

Además sería bueno que fueses a la pestaña "Discovery" y que eliminases el servidor de almacenamiento de allí también:

De este modo se solucionará el problema y ya no dejará tu servidor "frito".

Y es que las actualizaciones automáticas de Microsoft son estupendas para no preocuparse de muchos aspectos de la gestión del servidor, pero muchas veces vienen con "regalos envenenados". Yo llevo muchos años gestionando servidores Windows y en todo este tipo no es la primera vez (ni mucho menos), ni tampoco será la última, que una actualización crea graves problemas operativos en las máquinas.

Es por eso que, si el coste no es un problema a largo plazo, la nube es cada vez más la mejor opción para gestionar tus sistemas. Obviamente no me refiero a servicios de infraestructura y máquinas virtuales, pues eso no te soluciona nada relativo a lo que estoy comentando. Me refiero a servicios de plataforma como servicio, del estilo de los Sitios Web de Azure, donde este tipo de cosas es mucho más difícil que ocurran. De todos modos no siempre es posible recurrir a este tipo de soluciones, si bien con el tiempo (y en gran parte gracias a Docker y los servicios de contenedores) será cada vez una realidad más común y menos problemática.

Espero que si da la casualidad de que estás pasando por lo mismo, este artículo te ayude a solucionar el problema :-)

 

 

GAMBADAS: Unos "inofensivos" subtítulos de vídeo...

23/06/2017
Artículo original

Si pensabas que los archivos de subtítulos eran simples ficheros de texto plano, inofensivos totalmente... estabas en un error. En efecto, los subtítulos suelen venir en un archivo de texto codificado con diferentes formatos. De hecho existen algo así como 25 formatos diferentes, aunque los más comunes son SRT y WebVTT. Hasta ahora se tenían por totalmente inocuos debido a ser simples textos.

Sin embargo, la conocida empresa de seguridad Check Point ha sacado hace poco un informe titulado "Hacked in translation" (juego de palabras con la famosa película de Sofia Coppola) mostrando que algunos archivos de subtítulos pueden llegar a ser extremadamente peligrosos.

El problema está en la manera que tienen los principales reproductores, como VLC, de procesar algunos de estos formatos. Aunque por seguridad no han dado detalles exactos de cómo funciona la vulnerabilidad, sí indican que un atacante malintencionado podría llegar a tomar el control completo de tu máquina, lo cual incluye no solo PCs, sino también dispositivos móviles, Smart-TVs, etc... Podrían robar información confidencial, instalar Ransomware, usar el equipo para lanzar ataques distribuidos de denegación de servicio... Potencialmente podría haber cientos de millones de usuarios expuestos a esta vulnerabilidad.

En el siguiente vídeo se puede ver el ataque en acción:

[youtube:vYT_EGty_6A]

Han identificado vulnerabilidades en VLC, Kodi (XBMC), Stremio y PopCorntime, los cuales han sido avisados y han parcheado el software convenientemente, así que si los usas (sobre todo VLC, el más popular), asegúrate de tener instalada la última versión. Dicen que hay otras plataformas afectadas, aunque no dan detalles porque no están parcheadas todavía.

Así que ya sabes: si descargas subtítulos desde Opensubttiles o Subscene, ten mucho cuidado y échale un vistazo a los archivos antes de usarlos con tu reproductor.

Fundamentos de Java: Cómo programar una sencilla calculadora financiera

21/06/2017
Artículo original

En este vídeo introductorio, perteneciente a nuestro curso, nuestro tutor Francisco Charte nos muestra la creación de una pequeña calculadora financiera en Java. Aprenderemos a utilizar distintos tipos de datos, operadores y expresiones de Java para construir un sencillo programa que nos va a permitir calcular la cuota de un hipotético préstamo bancario.

Vamos a utilizar para ello el entorno de Netbeans. Una vez lo hemos iniciado creamos un New Project en el menú File para crear una aplicación Java simple, le ponemos un nombre y hacemos clic en finish.

[youtube:ldG2HSvdSz0]

Como siempre, Netbeans crea un esqueleto del código en el cual ya tenemos una clase: CalculaPrestamos, que es como hemos llamado al módulo de código, y en él tenemos ya la función main.

Elixir, programación funcional para todos

20/06/2017
Artículo original

Elixir code

La programación funcional está de moda. Cada vez hay más lenguajes que adoptan este paradigma, pero lo que es más importante, los desarrolladores cada vez adoptan más lenguajes de este tipo. Scala, F#, Clojure y otros viejos rockeros como Erlang o Haskell empiezan a estar en boca de muchos de los programadores del sector.

Uno de los nuevos en la ciudad, es Elixir, un lenguaje funcional, concurrente y pensado para hacer aplicaciones mantenibles y escalables.

Elixir

Elixir corre sobre la máquina virtual de Erlang (BEAM). Esto hace que el lenguaje, a pesar de ser muy joven, sea robusto y con mucha funcionalidad

Elixir es un lenguaje creado en 2011 por José Valim, y aunque la sintaxis es nueva, el lenguaje corre sobre la máquina virtual de Erlang (BEAM). Esto hace que el lenguaje, a pesar de ser muy joven, sea robusto y con mucha funcionalidad. Además, como el lenguaje se compila a bytecode de Erlang, se puden utilizar funciones de ese lenguaje, sin ningún tipo de penalización.

Elixir, al igual que Erlang, es un lenguaje dinámico, por lo que los fallos los recibiremos en tiempo de ejecución, por ejemplo si una función no existe, e intentamos llamarla. El tipado de Elixir, aun siendo dinámico, es fuerte, por lo que no están permitidas cosas que sí están permitidas en lenguajes con un tipado más débil, como JavaScript. Por ejemplo, la operación 1 + "1" es perfectamente válida en JavaScript, pero provoca un error de ejecución en Elixir.

Instalación y configuración

Instalar Elixir es muy sencillo y bastan con seguir los pasos que se indican en su página web. Podemos instalarlo en Linux, Windows o Mac sin demasiados problemas.

Una vez lo hayamos hecho, no hay que realizar ninguna configuración adicional. Escribiendo iex en la línea de comandos accederemos al REPL(Read-Eval-Print-Loop) de Elixir, que nos permitirá ejecutar instrucciones de Elixir. De hecho, podríamos escribir una aplicación entera desde esta consola.

Elixir logo

Organización y sintaxis

La sintaxis se basa en la sintaxis de Ruby, por lo que las personas con algo de experiencia en ese lenguaje encontrarán familiar la manera de escribir código en Elixir. Veamos un ejemplo:


defmodule GenbetaDev.Syntax.Example1 do

  def print(option) do
    option
    |> get_message
    |> IO.puts
  end

  defp get_message(opt) do
    cond  do
      opt == 1 -> "Hello"
      opt == 2 -> "Hello, World"
      true -> "Hello planet Earth"
    end
  end
end

Las funciones en Elixir se distinguen por su nombre y número de parámetros (arity)

Todo el código en Elixir, se organiza en módulos con defmodule y dentro de esos módulos se declaran las funciones que compondrán nuestra aplicación. Las funciones pueden ser públicas def y accesibles desde fuera del módulo, o privadas defp y solo accesibles si son llamadas desde dentro del mismo módulo. Las funciones en Elixir se distinguen por su nombre y número de parámetros (arity). La función get_message del ejemplo, es descrita por el compilador de Elixir como get_message/1. Si tuviéramos otra función con el mismo nombre, pero que recibiera dos parámetros sería get_message/2.

Aunque en Elixir no existen los namespaces, por convención, se suelen nombrar los módulos de manera que queden organizados. Por ejemplo en nuestro ejemplo el módulo se llama GenbetaDev.Syntax.Example1, lo que podría ser algo así como el nombre del proyecto o aplicación, luego el grupo de módulos, y al final el nombre concreto del módulo. Cuando estos nombres son demasiado largos, podemos utilizar el operador alias, y así escribir solo la última parte del nombre (en este caso Example1).

La magia del pattern matching

Una de las características más interesantes de Elixir es el pattern matching. Si bien la mayoría de los lenguajes funcionales poseen este tipo de mecanismo, en Elixir se utiliza de una manera muy elegante. El pattern matching o concordancia de patrones, no es más que buscar una similitud con un patrón, para realizar una acción concreta. En Elixir, este pattern matching está continuamente presente, así que por ejemplo podemos ver cosas como estas (desde iex en este caso):


iex(1)> x = 1
1
iex(2)> 1 = x
1
iex(3)> 2 = x
** (MatchError) no match of right hand side value: 1

Primero asignamos el valor 1 a una variable. Luego utilizamos el operador = para comprobar si hay concordancia. En el primer caso sí la hay, ya que x = 1, en el segundo no, y Elixir nos muestra une error.

Si complicamos el ejemplo, podemos ver que el pattern matching funciona también con tuplas:


iex(4)> {a, b, c} = {1, :error, "not found"}
{1, :error, "not found"}
iex(5)> {2, :error, "null exception"} = {a, b, c}
** (MatchError) no match of right hand side value: {1, :error, "not found"}
    
iex(5)> {1, :error, "not found"} = {a, b, c}     
{1, :error, "not found"}
iex(6)> 1 = a
1    
iex(7)> :error = b
:error
iex(8)> "not found" = c
"not found"
iex(9)> :ok = b
** (MatchError) no match of right hand side value: :error

Y que también funciona con listas:


iex(10)> [a, b, c] = [1, 2, 3]
[1, 2, 3]
iex(11)> a
1
iex(12)> 9 = a
** (MatchError) no match of right hand side value: 1
    
iex(12)> [3, 4, 5] = [a, b, c]
** (MatchError) no match of right hand side value: [1, 2, 3]
    
iex(12)> [1, 2, 3] = [a, b, c]
[1, 2, 3]

Como ya he dicho el pattern matching suele ser una característica de los lenguajes funcionales, pero en Elixir está incluido de tal manera, que casi se nos invita a usarlo. De hecho, a la hora de llamar a funciones es terriblemente útil. Por ejemplo este sería el código del típico FizzBuzz.


defmodule GenbetaDev.Examples.FizzBuzz do

  def start(first, last) do
    first..last
    |> Enum.each(fn(x) -> check(x) end)
  end

  defp check(number) when rem(number, 15) == 0, do: IO.puts("FizzBuzz") 
  defp check(number) when rem(number, 3) == 0, do: IO.puts("Fizz")
  defp check(number) when rem(number, 5) == 0, do: IO.puts("Buzz")
  defp check(number), do: IO.puts("#{number}")

end

Si un número es divisible por 3 escribimos "Fizz". Si es divisible por 5 escribimos "Buzz". Si es divisible por ambos escribimos "FizzBuzz". En cualquier otro caso escribimos el número.

En el ejemplo definimos cuatro funciones que se llaman igual, y que reciben el mismo número de parámetros. Con las cláusulas de guarda when definimos las condiciones que se debe cumplir para que el pattern matching utilice esa función. Elixir va comprobando de arriba a abajo, que función es la que debe utilizar. Por tanto el caso más específico deberá estar siempre al principio y el más general, al final. Lo bueno del pattern matching en funciones, es que no tiene porque aplicarse con cláusulas de guarda, si no que podemos aplicarlo al valor del parámetro. Por ejemplo con tuplas:


def print_result({:ok, _}), do: IO.puts("operación completada con éxito")
def print_result({:error, message}), do: IO.puts(message)
def print_result(_), do: Io.puts("Error en el parámetro recibido")

En definitiva, el pattern matching nos evita tener que escribir multitud de sentencias condicionales que harían el código más complicado de seguir. De hecho, la recomendación general, es utilizar pattern matching siempre que se pueda. Y de hecho es tan sencillo hacerlo, que no solemos encontrar impedimentos.

Funciones como ciudadanos de primera clase

Como buen lenguaje funcional, Elixir utiliza las funciones como ciudadanas de primera clase. Esto quiere decir que las funciones pueden pasarse como parámetros, asignarlas a variables o recibirlas como resultado de una función.

Ya hemos visto antes que podemos definir funciones con def y defp. Además podemos también definir funciones anónimas:


iex(18)> myfun = fn(x) -> x * 2 end
#Function<6.87737649/1 in :erl_eval.expr/5>    
iex(19)> myfun.(2)  
4
iex(23)> myfun3 = fn(x) -> myfun.(x) + 1 end
#Function<6.87737649/1 in :erl_eval.expr/5>
iex(24)> myfun3.(2)
5

En cualquier caso, las funciones las podemos asignar a variables, o incluso pasarlas como parámetro de otra función. Por ejemplo:


defmodule GenbetaDev.Examples.FirstClassFunctions do
  def executor(func, n) do
    func.(n)
  end
end

La función del ejemplo recibe otra función como primer parámetro y la ejecuta pasándole el segundo parámetro n. En elixir para ejecutar una función contenida en una variable, siempre hay que hacerlo añadiendo .(). Dos ejemplos:


iex(3)> alias GenbetaDev.Examples.FirstClassFunctions
alias GenbetaDev.Examples.FirstClassFunctions
GenbetaDev.Examples.FirstClassFunctions

iex(4)> FirstClassFunctions.executor(fn(x) -> x * 3 end , 4)
FirstClassFunctions.executor(fn(x) -> x * 3 end , 4)
12

iex(5)> FirstClassFunctions.executor(fn({x, y}) -> x <> y  end , {"hola", " GenbetaDev"})
FirstClassFunctions.executor(fn({x, y}) -> x <> y  end , {"Hola", " GenbetaDev"})
"Hola GenbetaDev" 

OTP la killer feature de Elixir

La sintaxis de Elixir es bastante asequible para todo tipo de programadores y el pattern matching, está muy logrado y es fácil de utilizar, pero ¿es esto suficiente para adoptar Elixir? Probablemente no, pero si pensamos en las posibilidades que tenemos con OTP, la cosa cambia.

OTP (Open Telecom Platform) es un conjunto de librerías y funcionalidades de Erlang, que permiten trabajar de forma fácil y asequible con programación concurrente. Y como no podía ser de otra manera Elixir bebe de ello para ofrecernos la posibilidad de utilizarlo. actores

Los procesos concurrentes, son totalmente independientes y no comparten ningún tipo de información

Hay que tener en cuenta que Erlang y OTP estaban pensados inicialmente para su uso en centralitas telefónicas, así que a la hora de diseñar OTP se basaron en un modelo de actores. Esto quiere decir, que los procesos concurrentes, son totalmente independientes y no comparten ningún tipo de información. Cuando un proceso quiere comunicarse con otro, solo puede hacerlo a través del paso de mensajes (a través de un buzón), que el proceso de destino procesará cuando crea conveniente o le sea posible.

Esto hace que los procesos (actores) que arranquemos con OTP sean muy livianos y apenas consuman recursos, a diferencia con otro tipo de lenguajes, en el que los contextos de los procesos son pesados y es más difícil gestionarlos. El resultado es que podemos arrancar cientos de miles de procesos sin apenas penalización para el sistema. Esto nos da una potencia verdaderamente increíble.

Obviamente, con este nivel de de concurrencia, necesitamos herramientas que nos permitan gestionar la ejecución (y fallo) de los procesos que se lancen. Y para esto tenemos los supervisores.

Usando supervisores

Un supervisor se encarga de gestionar tantos procesos hijos como sean necesarios. Los supervisores se configuran con una estrategia determinada, que seguirán en caso de que alguno de los procesos hijos tenga problemas. Por ejemplo, la estrategia puede ser la de reiniciar un proceso cuando falla, reiniciar todos los procesos hijos cuando uno falla, o no reiniciar ningún proceso cuando falla. Y de todo esto se encargan los supervisores, de forma eficiente, por lo que nos deberemos preocuparnos mucho más de ello.

Si lanzamos un proceso, pero este sufre una excepción, su supervisor se encarga de gestionarlo y por ejemplo arrancará un nuevo proceso de forma instantánea. Es posible también que los procesos almacenen un estado que incluso puede conservarse en caso de fallo.

Let it crash

Al ser los procesos de Elixir tan baratos en cuanto a consumo de recursos, y al estar tan controlados en el caso de fallo, aparece un concepto intereseante: let it crash. Algo así, como déjalo que falle. Y es que no tiene ningún sentido llenar la lógica de nuestros procesos con control de excepciones. Es más sencillo y mucho más eficiente, dejar morir el proceso y arrancar otro en su lugar. Y es la práctica recomendada cuando utilizamos OTP.

Macros

Otra de las características importantes de Elixir, son las macros. Las macros, son código que escriben código. Con ellas, podemos expandir el lenguaje tanto como queramos, incluyendo elementos que no existen en la base. Es lo que se conoce, como metaprogramación. De hecho, Elixir está lleno de macros y muchas de las cosas que se encuentran en su núcleo, lo son. Por ejemplo, la cláusula if no es más que una macro. Un ejemplo que nos crea un if personalizado sería el siguiente:


defmodule GenbetaDev.Macro.If do
  defmacro my_if(expr, do: if_block), do: if(expr, do: if_block, else: nil)
  defmacro my_if(expr, do: if_block, else: else_block) do
    quote do
      case unquote(expr) do
        result when result in [false, nil] -> unquote(else_block)
        _ -> unquote(if_block)
      end
    end
  end
end

La parte interesante de las macros está en la cláusula quote do. Y es que todo el código de Elixir puede expresarse como AST (Abstract Syntax Tree). Y es que todo código de Elixir se puede escribir como una estructura de datos similar a la siguiente:


iex> quote do: 1 + 2
{:+, [context: Elixir, import: Kernel], [1, 2]}

Así que como podemos ver con quote podemos acceder a la representación interna del código de Elixir. Si lo usamos en una macro, a la hora de compilar, todo lo que sea definido con esa macro, es sustituido por lo que hay representado dentro del quote.

Volviendo al ejemplo del if personalizado, podríamos usarlo de la siguiente manera:


iex(2)> import GenbetaDev.Macro.If
import GenbetaDev.Macro.If
GenbetaDev.Macro.If
iex(3)> my_if 1 == 1 do "yes" else "no" end
my_if 1 == 1 do "yes" else "no" end
"yes"

La manera que tiene Elixir de acceder al valor de un elemento y no a su representación AST es utilizando unquote. Es importante saber que las macros en Elixir son higiénicas, es decir, que Elixir hace el mapeo de variables como último paso, por lo que las variables definidas por el programador en otros módulos o funciones, no serán sustituidas por una macro. Hay maneras de saltarse esta regla, pero deben ser definidas explícitamente, dando a entender que sabemos lo que estamos haciendo.

Elixir tiene muchas más cosas.

Si bien hemos comentado algunas de las características más interesantes de Elixir, hay muchas más cosas a tener en cuenta. Aquí algunas más:

  • Mix. Herramienta utilizada para la generación de builds y gestión de proyectos. Puede realizar multitud de operaciones como compilar, crear un proyeto, ejecutar los tests, descargar las dependencias etc.
  • ExUnit. Framework de test incluido de serie con Elixir. Con algunas opciones curiosas, como que los nombres de los test, son un string largo diciendo lo que hace el test, en lugar de un nombre corto como en otros lenguajes.
  • Hex. Gestor de paquetes de Erlang/Elixir, que nos permite descargar dependencias al más puro estilo npm y similares.

Con todas estas características podemos concluir que Elixir es un lenguaje bastante potente.

Uso y futuro de Elixir

Como cada vez más desarrolladores de Ruby se pasan a Elixir, la comunidad está creciendo rápidamente

Como cada vez más desarrolladores de Ruby se pasan a Elixir, la comunidad está creciendo rápidamente

Con Elixir podemos escribir cualquier tipo de programa. Sus posibilidades de concurrencia lo hacen ideal para cierto tipos de programas backend. No obstante, y teniendo en cuenta que el desarrollo web es la disciplina predominante, también existe un framework para desarrollar aplicaciones web llamado Phoenix. Al igual que Elixir está inspirado en Ruby, Phoenix está inspirado en Rails, aunque intentando simplificar las cosas y eliminando parte de la magia negra de Rails. El framework es bastante potente y muchos desarrolladores de Ruby están empezando a usarlo, ya que su rendimiento es realmente bueno.

Como cada vez más desarrolladores de Ruby se pasan a Elixir, la comunidad está creciendo rápidamente. Si bien no llega a la amplitud de otras comunidades, es una comunidad bastante activa, que propone cosas y que ayuda a los demás a progresar. En la lista de distribución de Elixir se discuten posibles nuevas funcionalidades o cambios en las existentes; en el foro de Elixir se dicuten problemas más generales y típicos que nos podemos encontrar; en el canal de Slack podemos encontrar programadores debatiendo sobre el lenguaje y los problemas que se encuentran; y como no siempre podremos obtener ayuda en StackOverflow, donde no es raro que el propio creador del lenguaje, José Valim, responda a nuestras preguntas. Por supuesto, Elixir es Open Source y podemos acceder a su código fuente en GitHub.

Conclusión

Elixir es un lenguaje moderno y potente, pero que corre sobre la máquina de Erlang, creada en los ochenta

Elixir es un lenguaje moderno y potente, pero que corre sobre la máquina de Erlang, creada en los ochenta. Esto lo hace un lenguaje muy robusto y lleno de funcionalidades, a pesar de su juventud. La sintaxis, similar a la de Ruby, lo hace más asequible para todo tipo de programadores, alejándolo un poco del espíritu académico de otros lenguajes funcionales.

En instalar y probar Elixir se tardan minutos, por lo que no lo pienses y dale una oportunidad. Seguro que te lo pasas bien.

También te recomendamos

Elixir, lenguaje de propósito general concurrente

Pliegues, una forma de encapsular las iteraciones en listas

Siete ejemplos que nos muestran cómo el rebranding puede ser la solución que buscabas

-
La noticia Elixir, programación funcional para todos fue publicada originalmente en Genbeta Dev por rubenfa .

Los 10 mandamientos del control de código fuente

16/06/2017
Artículo original

Los 10 mandamientos del control de código fuente

Los sistemas de control de versiones o sistemas de control de código fuente son programas que mantienen el histórico de todos los cambios realizados sobre archivos y carpetas a lo largo del tiempo. Esto permite volver a cualquier punto del pasado en cualquier momento, y también comparar un punto del tiempo con otro para conocer los cambios exactos que se han producido entre ambos. Además almacenan también quién es el autor de cada cambio y facilitan mucho el trabajo en paralelo de varias personas en varias características.

Existen multitud de sistemas de control de código: locales, centralizados o distribuidos. Más apropiados para código fuente o para archivos grandes como gráficos o vídeos. Instalados en un servidor local o utilizados desde Internet...

La lista de software para control de código es extensísima, pero los más conocidos son Mercurial, Subversion, PlasticSCM (que además de ser un proyecto alucinante, está creado desde cero en Valladolid para el mundo), y por supuesto el rey de todos ellos: Git, creado por Linus Torvalds hace ya más de una década y que se ha convertido en el estándar de facto de la industria.

Hoy en día es inevitable usar el control de código fuente en cualquier proyecto. Debería estar castigado con las penas del infierno de los programadores el hecho de no utilizarlo.

Es por esto que he intentado recopilar lo que considero que deberían ser los 10 mandamientos del control de código fuente, tal cual debería haberlos bajado el propio Linus Torvalds desde las montañas para entregarlas a sus seguidores. Las 10 reglas básicas de comportamiento que todo programador debería seguir a la hora de trabajar con este tipo de sistemas.

Ahí van:

1.- Utilizarás control de código sobre todas las cosas para todos tus proyectos

Da igual que sea un proyecto personal en el que solo trabajes tú. Deberías usar control de código fuente, aunque sea con un repositorio local sin respaldo en un servidor. De este modo podrás ir guardando todos los estados importantes del proyecto y volver a cualquier punto anterior, ver qué decisiones y cambios te llevaron al punto actual, etc...

Por supuesto en un equipo, aunque sea de dos, es indispensable. Con servicios gratuitos de repos privados como Bitbucket, Gitlab o el propio Visual Studio Team Services de Microsoft (que también soporta Git) no hay disculpa para no hacerlo.

2.- No te irás nunca a casa sin hacer un commit y un push

Es decir, sin dejar el código perfectamente salvaguardado y recuperable desde cualquier sitio, esté en el estado que esté (más sobre esto luego).

No en vano en algunos sitios el procedimiento anti-incendios incluye un cartel como este:

Cartel de "En caso de incendio"

:-)

Aunque este sea para Git, vale para cualquier otro VCS: confirma y almacena antes de irte, aunque sea a comer.

3.- Inspeccionarás tus cambios con cuidado antes de hacer un commit

Lo de crear un commit es tan sencillo que lo hacemos de manera rutinaria, sin fijarnos. Mal hecho. Debemos prestar atención a que todos los archivos necesarios están en el área de preparación. A veces los archivos nuevos no se han añadido. O puede que se hayan agregado archivos que son temporales y no deberían estar ahí. ¿Y qué pasa con archivos que has editado pero que realmente no han cambiado finalmente tras varios cambios? No deberías subirlos y meter más ruido en el commit.

Para ello, revisa siempre bien los cambios antes de subirlos y asegúrate de que solo va lo que es realmente necesario. Utiliza incluso la herramienta de comparación si tienes dudas.

4.- Harás commit con frecuencia

Muchas personas tienen miedo de hacer commits con cosas a medio terminar y que luego se vean así en el histórico, como si todas las características de un desarrollo de software llegaran a la perfección al mismo tiempo que las escribimos. En absoluto. No pasa nada por tener cosas a medias o feas o con "ñapas" mientras no hemos terminado el desarrollo. Es preferible a tener un solo commit varios días después. Perdemos trazabilidad, ideas, conocimiento de cómo el código llegó a ser como es, y es imposible que otras personas del equipo conozcan el progreso actual del trabajo.

Deberías hacer un commit cada vez que tengas código que deseas guardar, porque tiene algo interesante, está una parte completa o, simplemente, te marchas y quieres dejar el trabajo salvaguardado. No pasa absolutamente nada. Además, si quieres dejarlo bonito más tarde también puedes hacerlo mediante cherry picking u otras técnicas. Pero, ¿para qué?.

Además recuerda que en sistemas distribuidos como Git, el hecho de hacer un commit no implica que debas hacer un push y subirlo al repositorio remoto. Los repos locales son para llevar control de tu trabajo y protegerlo. Los repos remotos son para pasar el trabajo a tus compañeros, controlar el trabajo de todos y, también, tener copias de seguridad.

Deberías enviar el código al remoto al menos una vez al día, pero no necesariamente cada vez que hagas un commit. Por lo demás, no te cortes y haz tantos commits como necesites.

5.- Te asegurarás de que los comentarios valen para algo

No hay nada peor que mensajes en un commit que no dicen nada de valor, como el mensaje de este cartel (clásico en marketing):

Pizaa Hut - We have pizza

¿Qué aporta ese mensaje ahí? Absolutamente nada. Ya sabemos que Pizza Hut tiene pizza...

Pues lo mismo ocurre con los mensajes que se ven en los repositorios muchas veces (por no mencionar en los comentarios de código).

Solo hay algo peor que un mensaje redundante: mensajes tan largos que acaban por no servir tampoco de nada, porque encima dan trabajo extra al leerlos.

Un mensaje de commit debería ser conciso pero al mismo tiempo informativo, aportando valor. Debería tener todo lo necesario pero no más. Por lo tanto debería enumerar los cambios importantes que se han hecho y por qué. Esto ayuda a localizar el punto en el que se cambió un comportamiento, una característica o se corrigió un bug. También ayuda a ver de un golpe rápido de vista el trabajo que se ha realizado recientemente y su progreso.

Si vas a hacer muchas cosas una mañana, no pasa nada: haz varios commits y procura que en cada uno haya un mensaje útil sobre cada cosa.

6.- Harás un Fetch/Pull antes de hacer un commit

Antes de empezar a trabajar en tu código después del último commit, haz un fetch o un pull para traerte los cambios del remoto y traer lo último que hayan hecho tus compañeros. Evitarás muchos conflictos en el futuro, y sobre todo evitarás sobrescribir su trabajo si no los gestionas bien.

Esto es de extrema importancia en sistemas no distribuidos como Subversion, porque directamente podrías cargarte el trabajo de los demás. Otros sistemas como Git no permiten que ocurra tan fácilmente (aunque sigue siendo buena costumbre hacerlo para evitar problemas).

Recuerda: antes de nada, tráete los cambios que haya.

7.- No harás push directamente al master

Esto ya no deberían permitirlo los administradores del repositorio, pero cada característica o bug debería trabajarse en su propia rama, y es ahí en dónde se deberían recibir todos los push. Estas ramas deberían salir a su vez de la rama de desarrollo, así que una vez terminado el trabajo en cuestión, la rama debería mezclarse con la de desarrollo.

Solo el código definitivo, bien probado y revisado debería ir al master, y para ello debería ser necesario un Pull Request que alguien deba aprobar. Algunos sistemas de repositorios como Bitbucket, por defecto ya lo tienen configurado así para evitar problemas.

Si utilizáis alguna metodología de gestión de ramas como Git-Flow (que deberíais), entonces ya será así como trabajarás.

8.- Comprenderás bien la herramienta de mezcla y comparación

Los conflictos son inevitables al mezclar ramas y al recibir actualizaciones desde los remotos. Así que aprende bien a manejar las herramientas de comparación que integres en tu sistema de trabajo. Pueden ser las herramientas de "diff" de tu cliente de Git favorito o alguna herramienta externa potente (y gratuita) como WinMerge, que a mí personalmente me encanta.

Cuando surja un conflicto será tu salvación. Y cuando no haya conflictos pero necesites ver qué ha cambiado en varias versiones de los archivos para descubrir un bug, también.

9.- Versionarás tus bases de datos y otras cosas

Hay quien se piensa que el control de código fuente solo sirve para código, porque lo lleva en el nombre. En absoluto. Deberías gestionar en él todo lo que tenga que ver con el proyecto, como documentación interna y externa (sobre todo si está en Markdown), gráficos, especificaciones, diagramas de flujo... y sobre todo las versiones de tu base de datos.

Para ello no es necesario que guardes la base de datos, sino su esquema en formato instrucciones SQL para poder reconstruirla en cualquier momento y conocer su evolución en el tiempo.

Cada vez que se realice un cambio sobre la base de datos puedes generar su esquema a un archivo de texto y archivarlo con el resto del código fuente. Puedes hacerlo con alguna herramienta especializada que lo automatice o puedes hacerlo a mano. Pero hazlo.

Estos elementos son tan importantes como el código en sí y deben ser guardados y gestionados con el mismo mimo.

10.- Excluirás tus mierdas cosas del control de código

No hay nada más molesto que un compañero que sobrescribe tus ajustes personales en cada commit. Y es que hay muchas cosas que no deberían estar bajo control de código fuente: tus ajustes personales en el editor de código que utilices, los archivos auxiliares que solo utilizas tú, resultados de las compilaciones (las famosas carpetas "bin" y "obj" por ejemplo), dependencias (carpetas "node_modules", "packages" y similares), etc...

Para algo se inventó el archivo .gitignore en Git o la propiedad svn:ignore en Subversion, por citar los más conocidos. Mete ahí los archivos y carpetas (o plantillas de archivos y carpetas) a excluir del control de código, y asegúrate que no incluyes cosas molestas o contingentes.

En resumen

Todos estos mandamientos se resumen en uno solo: amarás al código sobre todas las cosas :-D

En serio. Seguramente muchas de las anteriores te parecen evidentes si has sabido usar este tipo de sistemas de la forma adecuada. Pero en mi experiencia, muchas personas se olvidan de lo básico y fastidian al resto del equipo y al código a largo plazo. También seguro que hay algunos consejos adicionales que se podrían añadir.

¿Cuál es tu experiencia? ¿Algún consejo más o puntualización? Déjalos en los comentarios de más abajo...

Por qué dejé de usar varias pantallas: un manifiesto a favor de tener un solo monitor

15/06/2017
Artículo original

Monitor Trabajar

Muchos programadores piensan que tener varios monitores aumenta la productividad e incluso hay estudios que lo demuestran… pero en realidad muchos de esos estudios han sido encargados por fabricantes de monitores como Dell o NEC.

Me da igual que tener muchos monitores me hagan parecer un hacker molón, hace unos años decidí vender los monitores que me sobraban y pasé a tener una solo pantalla. Y no soy el único.

Estas son mis razones.

Concentración

Los seres humanos solamente nos podemos concentrar en una sola cosa al mismo tiempo ¿Para qué gastar dinero solo para que se nos muestren varias cosas a la vez? Si en todo momento tengo a la vista el correo y las redes sociales, no voy a dejar de distraerme. En un mundo en el que las distracciones son constantes, el hecho de poder concentrarnos en una única tarea durante un periodo largo de tiempo es una capacidad muy valuable.

Cada vez trabajamos de forma menos profunda por la gran cantidad de distracciones a las que estamos expuestos, por eso cada vez es más importante trabajar en profundidad. Aquellos pocos que puedan aprovechar los días trabajando en profundidad serán los que acaban teniendo éxito. — Cal Newport en “Deep Work"

Tener un solo monitor significa que aquello en lo que estoy trabajando (y solamente aquello en lo que estoy trabajando) es lo que se me muestra delante de mis ojos y de forma centrada. Si las distracciones no están a la vista, no suponen un problema.

Monitores Full

¿Acaso alguien se puede concentrar en una sola cosa en un sitio como este?

Leer y escribir son dos de las cosas que hacemos a diario y que necesitan nuestra concentración plena durante un periodo largo de tiempo. Si es lo único que aparece en la pantalla, podremos leer y escribir mejor. Un libro con twitter actualizándose continuamente al margen sería un desastre, pero no deja de haber gente que trabaja de forma parecida. Muchas veces tener varias pantallas solo significa más distracciones y es mucho más probable que te concentres en lo que tienes que hacer si el correo y las redes sociales no están a la vista.

Soy programador y escribo código a diario, por lo que muchas veces me toca leer documentos. Sin embargo, rara vez necesito tener los documentos a la vista mientras estoy escribiendo el código. Primero leo el documento relevante y después me pongo con el código: mi flujo de trabajo sigue diferentes pasos.

Menos gestión de ventanas

Empecé usando un monitor panorámico LG de 34” durante un mes y me encantaba.

Sin embargo, tras varios días de uso empecé a cambiar de opinión: el monitor era demasiado panorámico para maximizar las ventanas y al final siempre acababa perdiendo el tiempo ajustándolas. “¿Qué ventana pongo hoy a la izquierda?” “¿Qué ventana es la más importante y la que debería poner en el medio?”

Vale que la pantalla era lo suficientemente ancha para mostrar varias ventanas a lo largo, pero las cosas que estaban en los laterales estaban muy lejos y no paraba de poner lo que estaba haciendo en el centro, quitándole todo el sentido a tener una pantalla tan grande. Jeff Atwood ya explicaba este problema hace mucho tiempo en “La paradoja de la pantalla grande” y su solución era utilizar algún programa para que fuera más sencillo mover y redimensionar las ventanas. Yo lo que prefiero es usar un monitor que tenga un tamaño más razonable.

Incluso utilizando algún programa para gestionar las ventanas, el uso de varios monitorias presenta un problema: si tengo dos monitores, el contenido no está directamente enfrente de mí, sino que está a la derecha o a la izquierda (algo que es muy molesto si estás trabajando en un escritorio con cinta de andar). Otra opción es poner un monitor en el medio y el otro a un lado, pero el segundo monitor estará demasiado lejos y en un segundo plano, por lo que siempre acabo poniendo lo que necesite en ese momento en la pantalla central.

“Tener opciones no nos ha hecho más libres, sino que nos paraliza; no nos ha hecho más felices, sino más insatisfechos”.

Tal y como escribe Barry Schwartz en “La Paradoja de Elegir”, existe la fatiga por tener que tomar decisiones de forma constante y muchas veces menos es más.

Con una sola pantalla tengo que tomar menos decisiones y no pierdo el tiempo decidiendo dónde poner las ventanas o arrastrándolas. Simplemente maximizo la aplicación o el programa que estoy utilizando y me olvido del resto de distracciones para poder trabajar sin perder el tiempo.

Lo mejor son los escritorios virtuales

Tanto Mac como Windows soportan los escritorios virtuales. En mi Mac puedo cambiar fácilmente de escritorio virtual, algo que me lleva menos de un segundo y no tengo que girar la cabeza y ajustar la vista en otro sitio. Tampoco pierdo mucho tiempo en los escritorios virtuales: a la izquierda del todo está el navegador y a la derecha el editor. Para mí los escritorios virtuales son como pantallas físicas que representan el mismo contenido.

Multi Ventana Las tres cajas de la parte superior representan tres escritorios virtuales. Basta un simple atajo de teclado para intercambiarlos y no lleva más tiempo de lo que tardaría en pasar la vista a otro monitor.

A propósito, si usas un Mac, asegúrate de desactivar la opción de reajuste automático.

El mismo método de trabajo fuera de casa

A veces trabajo fuera de casa: en cafeterías, bibliotecas, parques, aviones, etc. Me llevo mi MacBook Pro de 15” (análisis) a todas partes y, como ya estoy acostumbrado a trabajar con una sola pantalla en casa, puedo trabajar de la misma forma cuando estoy fuera gracias a los escritorios virtuales.

Remoto Pantalla La semana pasada pude trabajar desde la playa sin tener que cambiar la forma en la que trabajo

Cuando tenía varios monitores, tenía que reorganizar mis ventanas cada vez que encendía el ordenador y ahora con los escritorios virtuales las ventanas permanecen en su sitio cada vez que me pongo a trabajar. Es como si tuviera un número ilimitado de monitores virtuales que siempre están organizados de la misma forma trabaje donde trabaje.

Mi monitor preferido para trabajar de forma productiva

Prefiero usar un monitor de 24” y 4K porque, si lo que buscas es productividad, en este caso más tamaño no tiene por qué ser mejor. Una pantalla de 24 pulgadas es lo suficientemente grande para mostrar dos aplicaciones al mismo tiempo si fuera necesario (utilizo BetterTouchTool en Mac y en Windows basta con Win+flecha). A su vez, un monitor de 24" es lo suficientemente pequeño como para maximizar todas las aplicaciones sin necesidad de tener que mover la cabeza o los ojos mucho para alcanzar con la vista los márgenes de la pantalla. Recuerda maximizar todo. Maximizar = concentración.

Este es mi escritorio actual:

Walking Desk Dell 2415q con un brazo para monitor Ergotron. Caminar en cinta me ayuda a concentrarme, me mantiene en forma y me ayuda a permanecer despierto durante el día. Ya no tengo problemas de quedarme amodorrado si la silla es muy cómoda y puedo quitar la cinta si estoy muy cansado y necesito sentarme.

¿Por qué 4k? A mayor resolución, menor fatiga. El texto es mucho más nítido y los precios ya son razonables, así que si no tienes un monitor de alta resolución, hazte con uno. Un monitor de 24” con 4K tiene más puntos por pulgadas que las pantallas de 4K más grandes, de ahí su nitidez. Todos los MacBook Pros que han salido en los últimos años tienen salida para 4K con 60hz a través de DisplayPort y muchos portátiles con Windows recientes también.

“Demasiado de cualquier cosa se acaba convirtiendo en lo contrario”. (Tim Ferriss)

¿Por qué muchos trabajadores se empeñan en utilizar varios monitores? Creo que se trata de la atracción ilógica por los extremos.

Demasiada pantalla no es más que una distracción y para mí lo que realmente importa es:

  • Menos es más.

  • Calidad más que cantidad.

  • No tener problemas de movilidad.

Post original escrito por Cory House: Pluralsight Author, Principal en reactjsconsulting.com, Software Architect, Microsoft MVP, Speaker, Clean Coder, Aspiring Outlier.

También te recomendamos

Crea un Terminator que no detecten los perros con Microsoft Robotics Developer Studio

Las espectaculares células impresas que regenerarán tu cuerpo son de una pionera española

Entrevistamos a los desarrolladores detrás de Karumi: "Lo que más nos motiva es hacer software del que nos sintamos orgullosos"

-
La noticia Por qué dejé de usar varias pantallas: un manifiesto a favor de tener un solo monitor fue publicada originalmente en Genbeta Dev por Cory House .

El desarrollador "estrella del rock" 10X NO es un mito

14/06/2017
Artículo original

Estrella del rock - Imagen Ornamental

Este artículo es una traducción del original de Yevgeniy Brikman, realizada con su permiso. El énfasis es nuestro. La imagen de portada es CC0, obtenida aquí.

Ayer por la noche publiqué este tweet:

Recibí muchísimas respuestas y preguntas, pero Twitter es un medio horrible para el debate, así que retomo el tema por medio de esta entrada en el blog.

Se han escrito un montón de artículos que sostienen que el desarrollador "10x" o "estrella del rock" no existe. Los argumentos en contra normalmente se pueden clasificar en tres grupos:

  • El número x10 original vino de un único estudio (Sackman, Erikson, and Grant (1968)) que está errado.
  • La productividad es un concepto difuso que es muy difícil de medir, así que mejor no hacer teorías como la de x10.
  • El talento está distribuido de forma desigual, pero de ninguna manera puede un solo ingeniero hacer el trabajo de 10.

Yo estoy en desacuerdo con todas estas. Repasemos estos argumentos uno a uno.

No hay solo un estudio

Aunque a muchos científicos de sofá en Twitter y Hacker News les encanta desmontar los estudios con revisión por pares (peer-reviewed), en este caso las pruebas son bastante convincentes y no se basan en un único estudio. Voy a citar la respuesta más valorada en StackOverflow en relación con este debate:

...El estudio original que halló enormes variaciones en la productividad de programación entre individuos fue llevado a cabo a finales de los años 60 por Sackman, Erikson, y Grant (1968). Tomaron como muestra a programadores profesionales con una media de 7 años de experiencia y vieron que el ratio en tiempos de programación entre los mejores y los peores programadores era de 20 to 1; el ratio en tiempo de corrección de errores era de 25 to 1; el del tamaño del programa de 5 a 1; y el de velocidad de ejecución de programa era de 10 a 1. No hallaron ninguna relación entre la cantidad de experiencia del programador con la calidad del código o la productividad.

Un análisis pormenorizado de los hallazgos de Sackman, Erickson, y Grant muestran algunos defectos en su metodología... Sin embargo, incluso tras tener en cuenta dichos defectos, el estudio muestra que hay una diferencia de x10 entre los mejores y los peores programadores.

Años después del estudio original, la conclusión general de que hay "diferencias de orden de magnitud entre programadores" ha sido ratificada por muchos otros estudios sobre programadores profesionales (Curtis 1981, Mills 1983, DeMarco y Lister 1985, Curtis et al. 1986, Card 1987, Boehm y Papaccio 1988, Valett y McGarry 1989, Boehm et al 2000)...

Puedes leer más aquí y aquí.

Cuando no lo puedes medir, al menos puedes argumentar razonadamente

Incluso si ignoras los estudios mencionados arriba y sostienes que la productividad en programación es difícil de medir -que lo es- podemos aún así debatir sobre los programadores x10. Porque algo sea difícil de medir no significa que no podamos razonarlo.

Por ejemplo, ¿cómo elegiste el lenguaje de programación para tu proyecto más reciente? ¿Buscaste un estudio que "demuestra" que el lenguaje es más efectivo que otras alternativas? Personalmente, no necesito un experimento para concluir que Ruby será una elección un orden de magnitud más productivo para crear una página web que, digamos, C. Podrías juntar grosso modo cuatro métricas (disponibilidad de bibliotecas, el peso de la comunidad, documentación, etc...), pero la realidad es que la mayoría de las personas toman estas decisiones basándose en un razonamiento intuitivo y no en un estudio exhaustivo. A pesar de que no hay datos concluyentes, apostaría que elegir Ruby sobre C para el desarrollo de páginas web resulta ser la mejor decisión en la mayoría de los casos.

Por supuesto, esto no solo se puede aplicar a la programación: ¿qué "métrica" te puede indicar que un escritor, artista, profesor o filósofo es mejor que otro? Simplemente observándolos, no puedo dar una "métrica de productividad" que sugiera que Shakespeare, Nabokov, o Orwell fueron un orden de magnitud mejor que el escritor medio, pero una amplia mayoría de personas estarían de acuerdo en que lo son.

La programación no es un trabajo manual

El mayor problema de los argumentos que niegan la existencia de programadores x10 es que algunas personas se creen que la programación es un trabajo manual y que los programadores son trabajadores en una cadena de montaje. Algunos programadores son un poco mejores que otros, pero, por supuesto, ¡un solo programador no puede de manera regular cerrar 10 veces más incidencias que otro! y ¡un equipo de diez programadores siempre rendirá más que un único programador! Nueve mujeres no pueden dar a luz a un bebé en 1 mes...

La lógica mencionada arriba hace parecer que la productividad en programación versa sobre la velocidad con las teclas; como si el programador x10 es simplemente el que produce diez veces más código que el programador medio. Esta línea de razonamiento ignora que la programación es un trabajo creativo y no manual: hay muchísimas formas de solucionar un mismo problema. En vez de la analogía del bebé, piensa más en una analogía de la resolución de un crimen: diez investigadores medios contra un Sherlock Holmes. ¿Quién resolverá el crimen antes?

Un desarrollador x10 tiene ideas y encuentra soluciones que nunca se le ocurrirían a un programador medio; evitarán toda una serie de problemas que le comen el tiempo al programador medio. Diez ingenieros picando el código equivocado pueden ser claramente superados por uno solo que escribe el código apropiado.

En programación hay que saber elegir bien

Piensa en todas las decisiones que hay que tomar a la hora de crear un producto de software, como por ejemplo una página web: ¿qué lenguaje de programación usas? ¿qué frameworks web usas? ¿cómo almacenas los datos? ¿dónde la alojas? ¿cómo la monitorizas? ¿cómo introduces mejoras? ¿cómo guardas código nuevo? ¿qué tipo de testeo automatizado configuras?

Diez programadores medios tomarán decisiones de calidad media en cada paso del proceso y los costes o los beneficios de estas decisiones se multiplicarán. Imagina que el tráfico aumenta de forma exponencial, y este equipo medio monta una web media, con un motor de almacenamiento de datos que es difícil de fragmentar, un alojamiento que no tiene suficiente redundancia, control de versiones sin copias de seguridad bien implementadas, sin entorno CI, y sin monitorización. ¿Cuán productivos serán esos diez programadores si se pasan el día apagando fuegos?

Un solo programador puede rendir más que este equipo de 10 si es capaz de modelar el problema y la solución de forma que hay menos trabajo que hacer en un orden de magnitud. Tras años de experiencia, un gran programador sabrá que los errores son una lacra de muy difícil solución a posteriori. Tomando buenas decisiones al principio, un programador x10 puede evitar meses de trabajo a la larga.

No se trata de escribir más código: se trata de escribir el código apropiado. No te conviertes en programador x10 haciendo más trabajo en un orden de magnitud, sino tomando mejores decisiones y más a menudo en un orden de magnitud.

Esto no quiere decir que los programadores x10 no cometan errores nunca; pero los programadores toman un gran número de decisiones al día y los grandes programadores toman mejores decisiones con mucha más frecuencia que los programadores medios.

Esto no solo es aplicable a la programación. ¿Preferirías tener diez científicos medios o un Isaac Newton? Diez científicos medios no idearon las leyes del movimiento, la teoría de la gravedad, las series binomiales, cálculo, etc... Fue un único Isaac Newton. ¿Prefieres tener a un Michael Jordan en tu equipo o diez jugadores medios? (nota: Jordan cobraba ~x10 el salario medio de la NBA). ¿Preferías que Steve Jobs o Elon Musk dirigieran una empresa o dejarla en manos de diez emprendedores medios?

Los programadores x10 son una especie poco común

Superman - OrnamentalImagen por Kooroshication CC-BY

Es importante poner las cosas en perspectiva. Los programadores estrella, al igual que los atletas, escritores o científicos estrella, son extremadamente poco comunes. No aconsejaría montar una política de contratación solo de estrellas del rock; te acabarías encontrando solo y sintiendo tonto. No dejes que lo perfecto sea enemigo de lo bueno: contrata a los mejores programadores que puedas y dales abundantes oportunidades para desarrollarse y mejorar.

No obstante, no caigas en la farsa de que todos los programadores son iguales. Hay un gran espectro de destrezas en cualquier profesión creativa. Por un lado están los tipos de contrataciones que pueden hundir cualquier empresa, activamente incrementando la deuda tecnológica con cada línea que pican. Y por el otro están las personas que pueden escribir código que cambia lo que antes era imposible y que tiene un impacto que es un orden de magnitud mayor que la media.

Kotlin, parte 3: Métodos de extensión y sobrecarga de operadores

13/06/2017
Artículo original

Kotlin permite la sobrecarga de operadores, como Scala y C++, pero de manera controlada, como Groovy. Es decir, no se pueden definir operadores de manera arbitraria como en Scala, donde se puede definir un método ~->, pero sí se pueden tener métodos que se puedan invocar con operadores como +, -, *, [] etc.

Es curioso que siendo un lenguaje con tipado estático, no se fueron por el camino "limpio" para implementar esto, que era definir interfaces para los operadores (por ejemplo, Summable, o Plus, Minus, etc), sino que lo implementaron de igual manera que en Groovy, sólo que pues en Groovy funciona porque es un lenguaje dinámico. Esto presenta dos problemas: primero, que hay que saberse muy bien cuáles son los operadores que se pueden sobreescribir, junto con los nombres de los métodos correspondientes, los cuales no siempre son obvios a la hora de estar implementado uno (Para usar / ¿es divided, quotient, div o qué?) y el otro, que es más difícil saber si una clase tiene operadores sobrecargados o no, ya que hay que revisar los métodos que implementa, en vez de simplemente revisar las interfaces que implementa, y honestamente es más fácil simplemente hacer prueba y error (a ver si funciona si le pongo un +).

leer más

Kotlin, parte 2: (not so) typesafe null y otras monerías

13/06/2017
Artículo original

Una característica importante de Kotlin es que maneja seguridad en nulos. Esto es algo que varios lenguajes han estado implementando últimamente, porque ahorra muchos dolores de cabeza.

Normalmente, una variable de cualquier tipo que sea objeto, acepta null. En Kotlin no es así; para que una variable acepte null, se necesita especificar de esa forma. Esto no compila:

var x:String = "hola"
x = null

Porque x ha sido definida como de tipo String, y no acepta nulos. Para que acepte nulos, se tiene que definir así:

var x:String? = "hola"
x = null

Los tipos opcionales se pueden usar en parámetros de funciones, tipos de retorno y declaraciones locales.

Cuando se tiene un valor que puede ser null, no se puede usar de manera directa. Hay que verificar que el objeto exista; esto se puede lograr de varias formas:

var x:String? = "hola"
if (x != null) {
  //Aquí dentro, x ya se considera String
  println(x.length)
}
val largo = x?.length //largo será tipo `Int?`
//Se puede usar el operador "Elvis" con tipos opcionales
println(x ?: "no hay x")

leer más

Página Siguiente