Hola, soy Dani.

Soy un desarrollador de software y creador de contenido educativo sobre programación.

Me gustan los sistemas de software limpios y ordenados y me interesa la usabilidad y la accesibilidad. Me fascina poder crear experiencias simples y pensadas para seres humanos en primer lugar. Estoy ubicado en la zona de Madrid (España).

Estoy disponible como freelance o como consultor a partir de septiembre de 2022. Todavía esto está por desarrollar, pero si te interesa mucho, podemos ir hablando ya 🙂


Estoy intentando poner orden en los archivos de mi página web, pero mientras tanto puedes encontrar un historial en bruto de las cosas que he escrito aquí.

⬇️ ⬇️ ⬇️

  • iOS tiene varias funciones de bienestal digital relacionadas con lo que ocurre cuando llega la hora de irse a la cama.

    Su existencia en mi móvil siempre me ha resultado curiosa e intrigante. Naturalmente que me parece positivo que el sistema operativo intente proteger la salud de su usuario impidiendo usar ciertas aplicaciones a partir de cierta hora; seguro que habría menos doomscrolling nocturno. Pero el sistema es muy poco flexible.

    Tengo activas pocas opciones del modo nocturno en mi móvil. Las que activan el modo no molestar a partir de cierta hora, y un atajo para activar el modo bajo consumo durante la noche, por si no pongo a cargar el móvil. La idea es que al menos no vibre durante la noche si entran mensajes y ya estoy durmiendo.

    No obstante, es muy complicado declarar excepciones, y esa es la razón por la que no logro terminar de apreciarlo. El modo no molestar y el modo sueño saltan están programados para iniciarse a las 23:00. Es una programación que tengo activa para no lamentarlo si el móvil empieza a vibrar una noche porque alguien decide mandar un mensaje en un mal momento.

    Pero si no estoy en casa porque esa noche estoy fuera, o todavía no he regresado a casa porque lo he estado, es complicado decirle de antemano «hoy voy a llegar tarde, no te actives». La única forma es desactivar manualmente el Modo Sueño una vez ya ha saltado. Y lo mismo se puede decir realmente de Tiempo de inactividad. Seguramente sea buena idea apagar las aplicaciones de mensajería a partir de cierta hora en condiciones normales, pero no creo que sea buena idea dejarme incomunicado si una noche estoy fuera.

  • Es posible especificarle al comando sort la columna por la que se quiere ordenar un archivo, en vez de utilizar el criterio por defecto, el de ordenar al fabéticamente por el contenido de toda la fila. Esto resulta útil, por ejemplo, para ordenar archivos de log tabulares por una columna concreta que no sea la primera. Hay que usar la opción -k, que tiene un comportamiento similar a la opción -f de cut cuando se delimita por espacio.

    cat prueba.txt
    3 miércoles
    1 lunes
    2 martes
    4 jueves
    
    sort prueba.txt
    1 lunes
    2 martes
    3 miércoles
    4 jueves
    
    sort -k2 prueba.txt
    4 jueves
    1 lunes
    2 martes
    3 miércoles
  • Dentro del marketing de «lo que hace que un Mac sea un Mac», una de las cosas que bajo mi punto de vista hace que un Mac sea un Mac es el hecho de que tantas partes del sistema operativo soporten desacoplar elementos de la interfaz y abrirlos en una ventana nueva. Doble clic en el e-mail y se abre en una ventana nueva. Lo mismo si haces doble clic en un nombre en la aplicación de Contactos, o en una lista de Recordatorios, o en una nota de Notas.

    El proceso está tan integrado que cuando agregaron soporte para múltiples ventanas en iPadOS, esta función también fue portada. Arrastrar una nota en Notas para iPad hacia el borde de la pantalla permite desacoplar la nota y abrirla como una ventana separada. Por supuesto, Correo para iPad también soporta esta función. Incluso las listas de reproducción de Apple Music o iTunes se pueden abrir en una ventana nueva.

    Permitir desacoplar en ventanas nuevas es un acto de respeto a los power users. Es reconocer que habrá personas que tengan interés en trabajar de forma simultánea con múltiples fragmentos de información procedentes de la misma app y facilitarles el poder escanear de forma simultánea todos esos fragmentos a la vez.

  • Super buenos consejos para escribir código Elixir más manejable.

    Las funciones con side-effects suelen devolver resultados tipo {:ok, term()} | {:error, term()}. Si estás trabajando con funciones que tienen side-effects, no las conectes con la siguiente función con un pipe. Es mejor tratar los resultados con un case o con un with.

    Super de acuerdo en esto. Recuerdo que hace no demasiado me pareció «superapropiado» hacer un fmap monádico en Elixir para poder escribir luego código fancy a lo Haskell:

    # Just don't. Not a very smart idea despite what it looks like
    def fmap({:ok, x}, f), do: {:ok, f.(x)}
    def fmap(whatever, _), do: whatever
    
    def readline(path),
      do:
        File.read(path)
        |> fmap(&String.split(&1, "\n"))
        |> fmap(&Enum.filter(&1, fn line -> line != "" end))

    Pero desde que conozco el with, no sólo no me parece necesario sino que oh dios mío por qué pude pensar que esto era buena idea. En caso de que deje de cumplirse con la secuencia de condiciones, with evalúa el bloque completo al valor devuelto por la primera función que salió mal, dejandolo todo más limpio.

    def readline(path),
      do:
        with {:ok, contents} <- File.read(path),
             {:ok, lines} <- String.split(contents, "\n"),
             {:ok, trimmed} <- Enum.filter(lines, fn line -> line != "" end) do
          trimmed
        end

    Supongo que no será la única epifanía ocurrida en este mundo al conocer la palabra clave with.

  • Ya dije hace un tiempo que era malo para darle títulos para las cosas que escribo. Supongo que es como saber darle asuntos al e-mail, que hay quien vale y hay quien no. El otro día mirando por Wayback Archive he recuperado más cosas mías publicadas hace tiempo por internet que me gustaría limpiar y clasificar en algún momento. Una de las primeras cosas que noto es que siempre he sido malo en esto de poner títulos a las cosas de escribo.

    (También me pasa con los asuntos de los correos.)

  • Tenía problemas para escribir acentos y eñes una vez enciendo mi ordenador en FreeBSD. Tengo configurado mi ordenador para arrancar manualmente el entorno gráfico, por lo que cuando enciendo el sistema lo primero que veo es una consola de vt pidiéndome el usuario y la contraseña. En este punto, todavía puedo teclear la letra ñ en el campo de nombre de usuario, pero después de hacer login, soy incapaz. Tampoco logro hacerlo si arranco X11 y abro terminales.

    La razón de esto parece estar en que no se activa el soporte para caracteres extranjeros si no está establecida la variable de entorno $LANG. Aquí un hilo en el foro donde dicen que la solución es esa. Si tal cual en tcsh ejecuto setenv LANG es_ES.UTF-8, a partir de ese momento puedo escribir caracteres españoles en la consola.

    Para persistirlo entre sesión y sesión, dentro del archivo ~/.login_conf introduje lo siguiente:

    me:\
    	:charset=UTF-8:\
    	:lang=en_US.UTF-8:

    Con esto queda establecido el charset a UTF-8 y la variable de entorno LANG la dejo preparada con el valor en_US.UTF-8. Si quisiese que mi ordenador estuviese en español podría utilizar es_ES.UTF-8 en su lugar, pero considero que es más valioso poder buscar el mensaje exacto en inglés que una traducción.

    Por cierto, el archivo .login_conf no puede ser un enlace simbólico. Tuve la genial idea de tratar de mover ese archivo a mi repositorio de dotfiles una vez lo dejé funcionando para poder incluirlo en mi copia de seguridad, pero se conoce que, por cuestiones de seguridad, este es uno de esos archivos en el que el sistema no resuelve los enlaces simbólicos cuando se pretende utilizar a través de la API del sistema operativo, para evitar posibles problemas de seguridad. Por eso también lo subo íntegro a este post: aparte de para ayudar a posibles almas perdidas desorientadas con esto, para hacer backup en alguna parte, visto que no se integra bien con el resto de mi repo de dotfiles todavía.

  • Al hilo del programa que escribí hace poco para visualizar el fractal de Mandelbrot, puede resultar interesante a simple vista que haya escogido Racket como lenguaje de programación. Fundamentalmente lo elegí porque quería hacer programación visual, y en Racket esto resulta fácil de hacer desde su GUI de forma interactiva. Se puede hacer un (require racket/draw), y ya se pueden usar funciones para dibujar sobre mapas de bits que hasta se pueden visualizar dentro del propio DrRacket. Tengo un curso de Racket en mi canal de YouTube, pero está a medias.

    Racket es una implementación de Scheme, pero existen muchas otras. GNU Emacs es conocido por tener una implementación de Scheme (Emacs Lisp), con la que se pueden hacer hasta plugins; como una alternativa al Vimscript. También se puede activar el modo scratch y programar en Emacs Lisp desde dentro de Emacs, para darle más lore al meme de que GNU Emacs es un propio sistema operativo dentro de otro.

    Sin embargo, GNU tiene otra implementación alternativa de Scheme llamada GNU Guile, que también tiene características interesantes. Guile es como Lua. Se puede incrustar soporte para Guile en otro programa y utilizarlo como una herramienta para fabricar plugins o extensiones. Se puede pedir a código C que interactúe con Guile.

    Además, también Guile tiene un modo independiente para usarlo como una herramienta de línea de comandos más, e incluso para interpretar programas escritos en archivos de código fuente. Lo normal es que tengan la extension .scm (aunque, como siempre, en un entorno GNU esto suele dar igual), y que se invoque GNU Guile en este caso con guile -s codigo.scm.

    ~ $ guile
    GNU Guile 2.2.4
    Copyright (C) 1995-2017 Free Software Foundation, Inc.
    
    Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
    This program is free software, and you are welcome to redistribute it
    under certain conditions; type `,show c' for details.
    
    Enter `,help' for help.
    scheme@(guile-user)> (+ 2 2)
    $1 = 4
    scheme@(guile-user)>

    Existen algunas cosas que me gustan de GNU Guile viniendo de Racket. La mayoría de palabras clave funcionan igual. En GNU Guile existe la primitiva define y la primitiva let. No tienen nombres especiales o diferentes. También existen algunas carencias en GNU Guile, pero son fáciles de subsanar. Por ejemplo, muchas de las funciones para trabajar con listas (foldl o reduce) están declaradas en la librería SRFI-1, por lo que tienen que ser importadas antes de poder usarse con un (use-modules (srfi srfi-1)).

    ~ $ guile
    GNU Guile 2.2.4
    Copyright (C) 1995-2017 Free Software Foundation, Inc.
    
    Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
    This program is free software, and you are welcome to redistribute it
    under certain conditions; type `,show c' for details.
    
    Enter `,help' for help.
    scheme@(guile-user)> (use-modules (srfi srfi-1))
    scheme@(guile-user)> (reduce (lambda (x a) (+ x a)) 0 '(1 2 3 4 5))
    $1 = 15
  • 1995. Microsoft presenta Windows 95, con la barra de tareas como una de sus principales características rompedoras, para hacer más productiva la experiencia ofreciendo botones que permitan cambiar de ventana mucho más rápido, junto con un menú inicio para abrir programas y documentos de una forma mucho más eficiente.

    Barra de tareas de Windows 95.

    2021. Mi gaming rig se actualiza a Windows 10 21H1, que introduce la sección Noticias e intereses, porque la tecnología hoy día no distrae lo suficiente de cara a completar las tareas del día a día.

    Menú Noticias e intereses.

  • No quisiera ofender a nadie, pero a esta pregunta que me salió el otro día respondiendo al survey de Stack Overflow respondí «No lo sé». Supongo que preguntar estas cosas son las costumbres de los estadounidenses y tendré que respetarlas.

  • Hace poco intentando resolver un problema en JavaScript*, puse en Google un par de palabras para describir mi problema esperando encontrar respuestas en Stack Overflow.

    El primer enlace apuntaba a un blog de Medium. No lo pude leer, porque la página me pedía registro.

    El segundo enlace apuntaba a otro blog de Medium. Tampoco lo pude leer, porque la página me volvía a pedir registro.

    El tercer enlace apuntaba a otro blog de Medium. Y no, no lo pude leer tampoco, porque la página otra vez insistía en pedir registro.

    Dejando a un lado que este tipo de páginas probablemente vulnere las normas de Google, a saber qué otros sitios web algún año se quitarán la careta después de convertirse en silos en los que la gente vuelca contenido.

    * Es casualidad que intente conectar JavaScript con Medium. Creo.