Abrir en una ventana nueva

Minientrada

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.

Good and Bad Elixir ➜

Enlace

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.

Títulos (parte 2)

Estado

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.)

Acentos en la consola de FreeBSD

Minientrada

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.

GNU Guile

Minientrada

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

La barra de tareas de la 21H1

Minientrada

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.

¿Cómo te describirías?

Minientrada

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.

El futuro era esto

Estado

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.

Consideraciones sobre el volcado de posts

Minientrada

A raíz del volcado de posts que cargué el otro día estoy considerando próximos datasets a importar. Exports procedentes de la GDPR, viejas entradas de blog sacadas de Wayback Archive, incluso tal vez puede que crosspost de cosas cargadas a YouTube o Twitter (algo que llevo años persiguiendo).

Algunas consideraciones técnicas que he aprendido para la próxima:

  • Es mejor usar un entorno de staging mientras se hacen pruebas para no ensuciar el sitio web, porque lo más posible es que falle al principio.
  • Por lo tanto, es mejor ir de poco en poco, y no intentar importar un dataset muy grande hasta que no se ensaye con algo más pequeño que se pueda borrar fácilmente si se hace mal.
  • Por si hay que borrar, es mejor ponerles a los posts importados una etiqueta nueva para poder filtrar fácilmente posts con esa etiqueta y borrar todo. En mi caso, esa etiqueta ha sido hn-import.
  • Si el blog lo alojas por tu cuenta, no tienes que dar parte del API Rate Limit a nadie, pero corres el riesgo de causarte un ataque de denegación de servicio a ti mismo. Como casi hago, de hecho, porque mi código JavaScript intentó lanzar las 49 peticiones HTTP POST a la vez.
  • Por asociación de ideas, mejor apagar los hooks externos que se llaman al crear posts mientras se estén importando cosas. No pingbacks, no trackbacks, no webmentions, no ActivityPub. (Aparte que muchos de estos posts tienen unos cuantos años y no tiene mucho sentido generar notificaciones por esto.)
  • El feed RSS va a sufrir.

El problema, como ya he dicho alguna vez, son los títulos. Muchas redes sociales no usan títulos en sus publicaciones, pero algo hay que poner para que la sindicación por RSS o al usar temas y widgets de WordPress que traten de mostrar el título de un post, tenga o no, puedan mostrar algo distinto a (sin título).

Re: Lista de deseos para la WWDC21

Minientrada

Parece que he acertado unas cuantas.

Espero seriamente que iPadOS 15 sea una versión cargada de mejoras para los power users.

Aquí no puedo dar el punto completo. He mirado las notas de la previa y la mayoría de funciones que veo son para consumo, no para creación. Poder integrar mejor una segunda pantalla hubiese estado bien que lo que se ofrece actualmente podría estar mejor…

No obstante, Swift Playgrounds va a pasar de ser una aplicación para “aprender a programar” a ser un entorno donde se va a poder programar de verdad (en Swift) y hasta enviar apps directamente a la AppStore desde iPadOS. Medio punto mientras le hago un seguimiento a esto.

Una mejor forma de lanzar aplicaciones en iPad.

Con lo del cajón de aplicaciones y el nuevo menú para la multitarea esto va a ser una realidad, o al menos mejor que lo que hay ahora mismo. También la llegada a iPadOS del directorio de aplicaciones, para poder eliminar iconos inútiles de la pantalla de inicio o del dock sin recurrir al viejo truco de empujarlos en una carpeta.

En iPadOS e iOS, más atajos para las opciones.

Opinaré sobre esto cuando vea los nuevos atajos. El nuevo modo Focus (que ya veremos cómo se llama en español) podría facilitar una forma flexible de configurar el dispositivo de distintas formas según la hora y el lugar. Es el caso de uso que más se le parece (poder silenciar el móvil en algunos momentos, por ejemplo), por lo que habrá que prestar atención a esto.

Ojalá una versión de Atajos para macOS.

A la orden. Aunque de poco me va a servir porque esta va a ser la primera versión de macOS que no se podrá instalar en mi mid-2014. (No es que me haga mucha falta…)