4 puntos por GN⁺ 2023-10-07 | 1 comentarios | Compartir por WhatsApp
  • La keynote de Strange Loop de Julia Evans aborda por qué tecnologías que parecen “básicas”, como DNS, Bash, HTTP y SQL, tardan tanto en aprenderse, y cómo reducir las barreras de aprendizaje
  • La dificultad de Bash está en que tiene muchas pequeñas excepciones y trampas, como que set -e se desactiva cuando se llama una función dentro de una condición con ||, y en que mucha gente usa Bash solo de vez en cuando, por lo que es difícil recordarlo con precisión
  • Detrás de la superficie simple de HTTP y SQL se esconden una implementación de navegador de unos 20 millones de líneas, muchos headers y flags, y la diferencia entre el orden en que se escribe SQL y el orden en que se ejecuta, lo que aumenta la carga de aprendizaje
  • En DNS, las bibliotecas, las cachés y la comunicación con los nameservers autoritativos no son muy visibles para el usuario, y la salida de dig también es compleja, por lo que son importantes las herramientas y demos que muestran el comportamiento oculto
  • Un buen apoyo al aprendizaje consiste en compartir herramientas y referencias, reducir listas grandes a pequeñas listas de uso real, explicar en orden cronológico lo que hace la computadora, y compartir también historias de fallas y registros de bugs

Por qué tecnologías que parecen “básicas” tardan tanto en aprenderse

  • La keynote de Strange Loop Making Hard Things Easy trata sobre cómo hacer más fáciles las tecnologías difíciles de aprender
  • El punto de partida fue DNS
    • Encontrar la dirección IP de un nombre de dominio parece algo simple, pero la ponente cuenta que, incluso después de 7 años aprendiendo DNS, tuvo problemas al configurar un sitio web, y que en total le tomó unos 10 años
    • Sus amigos pasaban repetidamente por los mismos problemas, y muchas personas seguían tomándolo como un problema personal, pensando que “ya deberían haberlo entendido”
  • Para explicar estos temas de forma sencilla, la ponente inició una pequeña editorial llamada Wizard Zines, y usa Bash, HTTP, SQL y DNS como ejemplos

Bash: las excepciones difíciles de recordar deberían quedar a cargo de las herramientas

  • Bash es un lenguaje de programación, pero entre los lenguajes que usa la ponente es de los que tienen más comportamientos raros
  • En el script de ejemplo, aunque mv ./*.txt /tmmpp falle, Bash por defecto no se detiene y ejecuta echo "success!"
    • Con set -e, se puede hacer que se detenga cuando hay una falla
    • Pero si se llama una función dentro de una condición con ||, como f || echo "failed!", set -e se desactiva globalmente dentro de la función y vuelve a imprimirse success
    • Este comportamiento no es un bug de Bash, sino un comportamiento documentado
  • Una de las razones por las que Bash es difícil es que muchas personas escriben scripts de Bash solo una vez cada 6 meses y luego no vuelven a mirarlos
    • Si un sistema que se usa pocas veces está lleno de conocimientos sueltos y trampas, es difícil usarlo correctamente
  • La reacción de “nadie puede usar Bash” no es cierta
    • Mucha gente usa Bash y, aunque no sea perfecto, a menudo resuelve problemas
    • El objetivo es llevar a alguien que está frente a una pila abrumadora de trampas a un estado en el que pueda usarlo “en general correctamente”
  • ShellCheck es una herramienta que recuerda por las personas las trampas de Bash difíciles de memorizar y emite advertencias
    • shellcheck -o all bad-again.sh muestra la advertencia SC2310, indicando que set -e se desactiva en una función llamada dentro de una condición con ||
    • Esta comprobación aparece solo si se ejecuta con -o all
    • Herramientas como esta reducen la carga cognitiva al hacer que la computadora se encargue de esos conocimientos sueltos

Las historias de fallas ayudan más a decidir que las “mejores prácticas”

  • Incluso sin crear herramientas propias, es importante contarles a amigos o colegas sobre herramientas útiles que ya se usan
    • La ponente también conoció ShellCheck tarde, y dice que le dio rabia darse cuenta de que no necesitaba recordar todo en su cabeza
  • Compartir trampas e historias de fallas es casi un servicio a la comunidad
    • El caso de set -e desactivándose en Bash lo aprendió por una experiencia que le contó su amigo Jesse unas semanas antes
    • Conocer los errores de otras personas permite evitar el mismo problema sin tener que vivirlo directamente
  • Más que opiniones fuertes como “nadie debería usar Bash”, son más útiles las historias sobre qué problemas causó Bash en la práctica
    • Al escuchar la misma historia, alguien puede decidir usar ShellCheck y mantener scripts simples de Bash
    • Otra persona puede decidir que no quiere usar Bash en absoluto
    • Está bien que las reacciones ante el mismo caso sean distintas

HTTP: hay que entenderlo asumiendo un navegador de 20 millones de líneas

  • Una respuesta HTTP puede parecer una estructura simple de código de estado, headers y cuerpo
  • Pero la pregunta “¿por qué hay que configurar headers?” conduce enseguida al comportamiento del navegador
    • Firefox tiene alrededor de 20 millones de líneas de código
    • Los navegadores han evolucionado desde los años 90, y su modelo de seguridad también ha cambiado continuamente según los ataques y cambios de la web
  • Para entender por qué un tema es difícil, conviene observar si detrás hay una base de código enorme
    • Esto incluye no solo HTTP, sino también CSS, JS y más, pero la complejidad de los navegadores modernos ayuda a explicar la barrera de aprendizaje de HTTP
  • Las listas grandes deben reducirse a listas pequeñas para que sean más fáciles de entender
    • Hay más de 43 headers de solicitud HTTP, además de headers no oficiales
    • En el cómic sobre HTTP request headers, la ponente cubre los 15 headers que conoce y usa
    • Los “headers más importantes” no son una lista objetiva, sino una lista subjetiva de lo que una persona conoce y usa
    • Por ejemplo, normalmente basta con saber que si se configura Accept-Encoding como gzip, se puede recibir una respuesta comprimida
  • Las herramientas de línea de comandos también pueden abordarse de la misma manera
    • La man page de grep tiene muchos flags, pero la ponente no los conoce todos, aunque lleva 20 años usando grep
    • Ayuda a principiantes que una persona con experiencia diga: “de este sistema conozco solo estas 7 cosas, y son estas”
    • Otra persona con experiencia puede conocer otras 7 cosas distintas

Las referencias deben compartirse con honestidad según lo que realmente se usa

  • La información que no cabe en la cabeza de una persona necesita buenas referencias
  • La ponente dice que, aunque aprendió CSS de forma intermitente durante 20 años, recién conoció CSS-Tricks en los últimos 2 años aproximadamente, y que le habría ayudado conocerlo antes
    • Parece que CSS-Tricks dejó de publicar artículos nuevos desde abril tras su adquisición, pero considera que los artículos existentes siguen siendo útiles
  • Para HTTP usa mucho Mozilla Developer Network
  • Como referencias oficiales de HTTP están RFC 9110, 9111, 9112, 9113 y 9114, escritas en 2022
    • Permiten consultar detalles como el comportamiento exacto del header Connection
    • La referencia principal de la ponente suele ser MDN, pero valora que los RFC oficiales estén bien organizados
  • Al compartir referencias, hay que distinguir entre compartir algo porque se ve sofisticado y compartir lo que realmente se usa en el trabajo
    • Aunque en la práctica se use una referencia “menos sofisticada” como w3schools, es importante decir honestamente si realmente se usa

SQL: explicar en orden cronológico lo que hace la computadora

  • SQL puede resultar confuso para quienes empiezan porque el orden en que se escribe una consulta y el orden conceptual real de ejecución son distintos
  • El modelo mental de SQL que usa la ponente sigue este orden
    • FROM
    • WHERE
    • GROUP BY
    • HAVING
    • SELECT
    • ORDER BY
    • LIMIT
  • Las bases de datos reales tienen optimizaciones, así que son más complejas, pero este modelo cronológico es útil en la mayoría de las situaciones
    • Es casi igual al orden escrito en la consulta, con la diferencia de que SELECT aparece en quinto lugar
  • La forma de preguntar “qué hace realmente primero la computadora” se puede aplicar a otros temas
    • En CORS, se puede entender escribiendo en orden cronológico toda la comunicación entre el navegador y el servidor
    • La ponente menciona el cómic sobre CORS como ejemplo de este enfoque
  • Las explicaciones cronológicas parecen simples, pero en realidad son difíciles, y por eso son útiles para colaborar
    • Behind Hello World on Linux trata sobre lo que ocurre al ejecutar “hello world” en Linux
    • La ponente también escribió un texto parecido hace 10 años, pero el artículo de 2023 era unas 6 veces más largo
    • Considera que no es tanto que Linux se haya vuelto más complejo, sino que en 2013 ella sabía menos sobre lo que ocurría cronológicamente
  • En equipos, crear juntos una línea de tiempo cronológica de lo que ocurre cuando llega una solicitud a un endpoint de API puede conectar lo que sabe cada persona

DNS: hay que mostrar los sistemas ocultos para construir intuición

  • DNS funciona mediante la interacción entre el navegador, las funciones de biblioteca que envían solicitudes DNS, las cachés y los nameservers autoritativos
  • El problema es que muchas de esas partes están ocultas para el usuario
    • No es fácil averiguar qué código de biblioteca envía solicitudes DNS
    • Es difícil inspeccionar los datos almacenados dentro de las cachés, y el usuario no puede controlarlas
    • Tampoco se ve la comunicación entre la caché y los nameservers autoritativos
  • La ponente creó con su amiga Marie un pequeño servidor DNS llamado Mess With DNS
    • Los usuarios pueden crear registros DNS en un dominio
    • Cada vez que llega una solicitud desde un resolver, muestra qué mensaje entró
    • En la demo de Strange Loop, creó un registro CNAME llamado strangeloop que apuntaba a orange.jvns.ca, y confirmó que el resolver DNS canadiense usado por el navegador pedía registros A y AAAA
  • Otro ejemplo de mostrar lo oculto es float.exposed
    • Permite cambiar el significand y el exponent en un número de punto flotante de 32 bits, y ver el siguiente número de punto flotante y el cambio en el espaciado
  • Otra razón por la que DNS es difícil es que es un sistema distribuido enorme
    • La ponente dice algo como que “pueden intervenir más de 5 millones de computadoras”, la mayoría de las cuales el usuario no controla, y algunas pueden comportarse de forma distinta a lo esperado

Cuando herramientas como la salida de dig se vuelven una barrera de aprendizaje

  • La salida de las herramientas DNS también puede aumentar la confusión
  • dig tiene el flag +norecurse
    • Permite pedirle al resolver que devuelva solo resultados que ya estén en caché
    • dig +norecurse jvns.ca puede usarse, por ejemplo, para comprobar si ese resolver cacheó ese dominio en los últimos 5 minutos
  • La salida de dig puede dar a principiantes la impresión de que DNS en sí es más complejo
    • La ponente considera que esto se debe más bien a que es un formato de salida relativamente arbitrario definido en los años 90 y mantenido durante mucho tiempo
  • “eraser eyes” es una forma de ignorar la salida compleja como si se borrara todo excepto la parte que realmente se está mirando
    • En el ejemplo, se presta atención solo al código de respuesta SERVFAIL
    • Según la comprensión de la ponente, en este contexto SERVFAIL significa algo cercano a “no está en caché”
  • Al demostrar una herramienta, ayuda explicar qué salida o UI se está mirando y qué partes se ignoran
    • Aunque la salida de dig es áspera, sus ventajas son que tiene muchas funciones, soporta +norecurse, está en todas partes y se mantiene estable porque lleva mucho tiempo sin cambiar

Roles para facilitar las cosas juntos

  • La práctica de hacer más fácil una tecnología puede compartirse con la gente cercana incluso sin tener un blog
  • Los métodos que resume la ponente son los siguientes
    • Compartir herramientas útiles
    • Compartir referencias que realmente se usan
    • Explicar en orden cronológico lo que ocurre en la computadora
    • Reducir listas grandes a pequeñas listas de lo que uno realmente usa
    • Mostrar comportamientos ocultos
    • Demostrar herramientas confusas explicando qué partes mirar
  • También hay distintos tipos de personas que ayudan
    • El “usuario viejo que se queja” reduce sufrimiento contando qué salió mal en el pasado
    • El “principiante ruidoso” pregunta “¿cómo funciona esto?” y hace que otras personas también se sientan aliviadas
    • Cuando un desarrollador senior pregunta públicamente algo que no sabe, quienes temen ser juzgados por no saber pueden aprender junto con él
    • El “registrador de bugs” documenta qué ocurrió para que el mismo bug no vuelva a pasar
    • El “creador de herramientas” escribe código en vez de repetir explicaciones, haciendo que el problema sea más fácil de forma permanente
    • La persona que “comparte lo que aprendió hoy” comparte una nueva herramienta, un bug que sufrió o una nueva función de una biblioteca que descubrió
    • La persona con “700 pestañas abiertas” probablemente ya sabe dónde buscar información
    • También hacen falta quienes responden preguntas y quienes escriben las cosas para que puedan encontrarse después
  • Que algo que parece básico resulte difícil no es solo un problema individual
    • Muchas personas tienen dificultades en los mismos puntos por las mismas razones
    • Si se identifica la causa de la dificultad, se puede corregir mejor, igual que se corrige un bug en un programa
  • Los factores que generan dificultad incluyen enormes cantidades de conocimiento suelto y trampas, código de 20 millones de líneas, sistemas ocultos y salidas de herramientas confusas que no han mejorado
  • La ponente todavía no entiende bien por qué Git es difícil, pero lo deja como un tema sobre el que quiere seguir pensando e intentando comprender

1 comentarios

 
GN⁺ 2023-10-07
Opiniones en Hacker News
  • La parte que más me resonó fue muestra lo que normalmente está oculto.
    Este tipo de herramientas casi de inmediato hacen que la situación sea más clara. Si pensamos en las herramientas de desarrollador del navegador web, en la “edad oscura” en que no existían, era horrible tener que adivinar qué estaba pasando sin poder verlo.
    Herramientas como Wireshark, que muestran los bytes de los paquetes de red accesibles e incluso parsean su estructura, son muy útiles no solo para depurar redes, sino también para enseñar conceptos de redes, porque no ocultan nada.
    Por eso también me gusta el software open source. Como se puede ver el código fuente para entender la causa de un bug, llenar los vacíos de conocimiento que deja la documentación o aprender más conceptos de programación, no hay nada oculto.

    • En desarrollo de videojuegos, la herramienta que corresponde a esto es renderDoc. Cuando supe por primera vez que existía, me sorprendió muchísimo.
    • Wireshark es excelente, pero no muestra todos los bytes que transportó la red.
      Por ejemplo, nunca muestra el preámbulo de Ethernet, solo a veces muestra el checksum de una trama Ethernet, y nunca muestra el intervalo entre tramas, que es un elemento esencial del protocolo Ethernet.
      Se acerca mucho, pero muestra que en alguna parte siempre hay más detalles escondidos.
    • El sueño es hacer que todo sea visualizable en runtime. Si se pudiera hacer eso, creo que toda la computación se volvería muy simple y mucho menos compleja.
      Ya lo visualizamos en la cabeza, y cualquier explicación de computación termina expresándose como un diagrama. Pero al programar no hay diagramas en absoluto.
      Bastaría con instrumentar dinámicamente todo el código y enviar mensajes a una GUI.
    • A diferencia de frases como “muestra lo que normalmente está oculto” y “esas herramientas casi de inmediato aclaran la situación”, las herramientas DevOps de hoy parecen más bien ocultar cada vez más cosas.
      Los expertos que tenían ese conocimiento y podían enseñarlo ahora tampoco están dentro de las organizaciones, sino concentrados en las empresas que hacen esas herramientas.
    • Esto es justo lo que me gusta de Magit para Emacs. La UI es realmente inteligente y fluida, quizá la mejor interfaz de Git que he usado, pero la forma de interactuar con la UI consiste en alternar flags y opciones que se mapean a los argumentos reales de la línea de comandos de Git.
      Así, cuando pasas naturalmente a la línea de comandos, ya puedes usarla directamente con familiaridad.
  • Julia parece ser una de las personas más agradables de la industria tecnológica.
    Cada vez que leo sus textos, vuelve esa emoción de cuando era niño y empezaba a desentrañar los secretos de la realidad con pequeños experimentos. Es realmente encantador.

    • Es raro encontrar a alguien que tenga a la vez un conocimiento técnico profundo y una gran capacidad de enseñanza y comunicación. Otra persona que se me viene a la mente es Andrej Karpathy.
      Por suerte, últimamente he ido encontrando más personas que encajan en este perfil.
    • Por un momento pensé que hablaban del lenguaje Julia :)
    • Muy de acuerdo. Normalmente no me gustan mucho los posts o tutoriales de blog exageradamente entusiasmados, tipo “omg awesomesauce”, y prefiero mucho más textos secos, con alta relación señal-ruido, concisos y hermosos, al estilo Landau&Lifschitz.
      Pero todos los textos de Julia me hacen sentir esa emoción entusiasmada de la que hablaban antes.
    • En persona también fue realmente encantadora. Me firmó mi libro How DNS Works.
  • Creo que la frase “cuando un recién llegado dice ‘esto es difícil’, alguien con experiencia responde ‘sí, bash es inutilizable; nadie lo entiende bien’” no debe tomarse literalmente.
    El sentido es más bien “no tenemos una comprensión muy fuerte del código bash que escribimos, ni mucha confianza en que se comporte como esperamos en situaciones que no probamos”.
    Significa que, si ocurre algo apenas fuera de lo común, uno en cierta medida espera que algo falle, y que un nuevo dato aprendido sobre bash te haga estremecer o golpear con fuerza algún objeto cercano hasta lastimarlo.
    Bash es un lenguaje complejo y, para la mayoría de los programadores, es completamente distinto de los otros lenguajes que usan habitualmente. En la mayoría de las empresas hay algo de bash en producción en algún lado, pero a menudo no hay ni una sola persona que lo use lo suficiente como para conocerlo bien.
    No creo que sea casualidad que las herramientas de build, las herramientas de CI y las herramientas de orquestación cloud evolucionen en dirección a reducir la necesidad de scripting de shell.

    • Creo que la complejidad de herramientas como bash viene de la falta de evolución.
      Como experimento mental, ¿no se podrían agregar mejores sentencias de asignación a bash? Por ejemplo, si en un modo como set --goodass se pudiera escribir a = string1 + '.' + string2, se podría eliminar buena parte del manejo de comillas del shell.
      Herramientas como make también se beneficiarían. Si se dedicaran seis meses a darle a make variables utilizables, una forma clara de manipular rutas y nombres de archivo, y targets más útiles, podría ser mejor que pasar seis meses creando Makefiles complejos.
    • El problema es si el recién llegado entenderá ese significado implícito o si lo tomará de forma más literal de lo previsto.
      En particular, la intuición de que “para la mayoría de los programadores, bash es distinto de cualquier lenguaje que usan normalmente” no es algo que un principiante necesariamente pueda inferir. Hace falta experiencia para distinguir entre “poco común” y “extremadamente críptico”.
  • Relacionado con eso, la mayor parte del software está sobrediseñado.
    Creo que también se debe a la centralización de la industria. Se empuja a todos hacia unas pocas herramientas, en beneficio de unos pocos que las controlan, y como resultado muchas herramientas se convierten en “la herramienta para todo”, cubriendo muchísimo más que los casos de uso que deberían manejar.
    Las empresas quieren que todos los desarrolladores conozcan las mismas herramientas. Así son fácilmente reemplazables entre proyectos y empresas, y su poder de negociación en la industria se debilita.
    Por eso en el software queda una sola rama dominante, mientras los enfoques alternativos son marginados sin puestos de trabajo. La industria naturalmente querría descentralizarse, pero no se le permite hacerlo.
    Visto de forma positiva, algún día aparecerán enfoques no mainstream mucho mejores que irán erosionando el enfoque dominante. La tecnología no es matemática ni es igual que la ciencia, y puede sostener perfectamente muchas ramas que resuelvan el mismo problema de distintas maneras.

    • Estoy de acuerdo. En cierto sentido, el desarrollo web incluso parece haber retrocedido respecto de los tiempos iniciales de ASP.NET o Rails.
      En aquel entonces las guerras de navegadores nos mantenían ocupados, pero ahora, aunque los navegadores en general son compatibles, hemos creado un montón de complejidad de frontend para web apps que en la mayoría de los casos no hace falta.
      Cosas como DNS, IP y HTTPS son tecnologías fundamentales entrelazadas con compatibilidad hacia atrás y factores políticos, así que no hay mucho que hacer.
      Aun así, siento que aprender bien esas cosas es una mejor inversión que aprender frameworks. Si digo más, terminaré hablando de tokens de innovación.
  • Para hacer fácil algo difícil, hay que encontrar la abstracción adecuada. Se trata de mantener en la cabeza solo una parte del contenido difícil y los detalles que se usan con frecuencia, y consultar el resto cuando haga falta.
    El problema es que la gente no se molesta en crear una compresión cognitiva de un tema grande hasta que realmente la necesita. Como ya carga con otras grandes cargas cognitivas, se resiste a sumar una nueva.
    Si puedes depender de otra persona que conoce bien algún tema X, simplemente lo haces, y quizá no te esfuerces por saber lo suficiente sobre X. La mejor manera de que alguien que conoce bien X reduzca las solicitudes de ayuda es ayudar a los demás a entender lo mínimo de X.
    set -e está roto, también está rota la necesidad de poner todo entre comillas, y el globbing debería ser una función que se pida explícitamente. En la línea de comandos sería molesto, pero en scripts la historia es distinta; hoy, si desactivas el globbing de forma global, se vuelve difícil hacer globbing donde sí lo quieres.
    Estos malos valores predeterminados no están solo en Bash, sino en general en los shells del linaje de Ksh y Bourne shell.
    Con SQL también hay mucha gente que quiere cambiar el orden de las cláusulas. No hay razón para no hacerlo, y parece que sería un cambio relativamente pequeño permitir que los parsers SQL existentes acepten cláusulas en otro orden.
    Aunque personalmente no tengo ese problema cognitivo, quizá porque sé que debo mirar primero las fuentes de las tablas.

    • Las tres trampas —que set -e está roto, que hay que poner todo entre comillas y que el globbing debería ser explícito— las corrige OSH sin dejar de ejecutar scripts de shell existentes.
      Si agregas shopt --set ysh:upgrade al inicio del script, esos tres problemas desaparecen.
      Si quieres ayudar al proyecto, estaría bien que descargues el tarball, verifiques esas afirmaciones y escribas una entrada de blog.
      Hay más detalles en https://www.oilshell.org/release/latest/doc/error-handling.h... y https://www.oilshell.org/release/latest/doc/simple-word-eval....
      La documentación es exhaustiva, pero la mayoría no quiere ese nivel de detalle, así que sería útil que alguien lo probara y escribiera algo breve.
      La razón por la que durante un tiempo no impulsé activamente Oils fue que tenía una dependencia de Python, pero ahora es C++ puro y, desde esta semana, supera a bash en algunos benchmarks centrados en cómputo.
      Los scripts centrados en entrada/salida, como la mayoría de los scripts de shell, siempre tuvieron la misma velocidad. En la documentación todavía hay que cambiar Oil por YSH, así que puede haber confusión por un tiempo: https://www.oilshell.org/blog/2023/03/rename.html
    • El problema es que seguimos usando estos shells antiguos aunque hay shells mejores. Los usuarios no deberían perder tiempo memorizando conocimiento arcano como set -e. Aun así, ahora existen los motores de búsqueda.
    • Una forma algo radical de arreglar el orden de las cláusulas en SQL podría ser introducir project, que funcione como select pero pueda ponerse en la posición correcta.
    • Cuando una explicación incluye detalles innecesarios, resulta muy confusa. Como el arma de Chéjov, uno intenta encajarlos constantemente en la trama, pero no encajan.
      Mi superpoder es una memoria pésima. Por eso, para recordar algo, necesariamente tengo que entenderlo; es decir, necesito compresión cognitiva. No puedo simplemente aprender como la gente normal.
    • Deberíamos poder pelar SQL y acceder a la capa inferior
  • Aprendizaje de hoy: en una lista con && u ||, salvo el comando que va después del último && u ||, el shell no se cierra aunque haya un comando que falle
    Referencia: https://www.gnu.org/software/bash/manual/bash.html#index-set

    • “Fallo” es un concepto de más alto nivel que aquello de lo que se preocupa el shell. Las condiciones de fallo y las reacciones quedan totalmente a criterio del programador, y no están integradas como supuestos en el shell
      Lo único que hace /bin/false es devolver 1. ¿Eso es un fallo? No. Fue diseñado para comportarse así y es una herramienta cuyo propósito es literalmente ese
      He escrito cientos de scripts de shell, y muchos de los comandos en ellos devuelven valores distintos de 0 de forma totalmente normal para hacer su trabajo, como verificar si una cadena sigue cierto patrón
      Un programa puede devolver el código de salida que quiera en cualquier situación y, por convención, éxito es 0 y fallo es un valor distinto de 0. Pero lo único que le importa al lenguaje del shell es que 0 se evalúa como “verdadero” y un valor distinto de 0 como “falso”
      Si el shell se cerrara cada vez que cualquier programa devuelve un valor distinto de 0, las sentencias if y los bucles serían imposibles, lo que sería muy incómodo
      Si un script considera importante el código de retorno de un programa específico, debe comprobarlo y manejarlo explícitamente. Como en el enlace, hay opciones para hacer que el shell se cierre si un comando interno devuelve un valor distinto de 0, y muchos autores de scripts de shell de nivel inicial e intermedio insisten de forma dogmática en que hay que usarlas en todos los scripts
      Pero en scripts complejos siento que hay muchos casos límite algo hacky y difíciles de manejar. Si necesitas esas opciones siempre, quizá sea mejor usar un Makefile
    • Es porque && y || se usan a menudo como condicionales
      [ -e README ] && cat README evita un error cuando no existe el archivo README, y [ -e README ] || echo "You should write a README!" funciona al revés
      Un problema más sutil es que, incluso asumiendo set -e, en un pipeline el shell no se cierra si el último comando no falla
      grep foo README | sort no falla aunque no exista README, a menos que también uses set -o pipefail
    • Considero que este es uno de los mayores defectos de diseño del lenguaje de shell. Porque una función puede llevar a resultados distintos según el contexto en que se la llame, independientemente de sus argumentos
      Incluso si dentro de la función se configura explícitamente set -e, eso se sobrescribe
      Hace tiempo di un ejemplo: https://news.ycombinator.com/item?id=22213830
    • En el shell hay mucho conocimiento arcano más por aprender. En algún momento hay que encogerse de hombros y aceptar que es una herramienta aceptable para obtener resultados rápidos, pero no adecuada para escribir programas robustos
  • Es un texto que describe bien cosas que parecen no deberían ser difíciles, pero que en realidad tienen mucha complejidad
    Sin embargo, la parte de SQL parece empujar aún más un fallo conceptual en vez de desmitificarlo
    La lógica de una consulta es declarativa y define la salida. Lo que tiene un orden de ejecución o una naturaleza procedimental es el plan de consulta. Eso es lo que debería aprenderse primero
    Luego se pueden aprender zonas ambiguas como las subconsultas dependientes. Si puedes ver que not exists y un anti join son equivalentes, puedes entenderlo y razonarlo
    La analogía de entender una consulta escrita de forma procedimental solo pospone el problema, y cuando te topas con algo más complejo ya no tienes cómo deshacer esa mentira piadosa

    • En la parte de SQL se hablaba de un modelo mental que ayuda a entender las consultas, y también se mencionaba que probablemente las bases de datos reales no las procesan así
    • Un episodio reciente relacionado con Postgres, pero que en muchos casos se puede extender mentalmente a otras bases de datos: https://www.se-radio.net/2023/09/se-radio-583-lukas-fittl-on...
  • Fue una presentación excelente. Es cierto que Bash está lleno de “trampas” y datos sueltos difíciles de memorizar todos, pero creo que también conviene memorizar algunos de esos datos
    Por ejemplo, suelo olvidar el orden de los argumentos del comando find, y he perdido tiempo tratando de recordar la sintaxis frente a una máquina sin conexión inmediata a internet
    Así que decidí aprender y memorizar las herramientas de línea de comandos más comunes y algunas de sus trampas, usando Anki y algunas técnicas mnemotécnicas. Creo que el retorno de la inversión valió totalmente la pena

    • Anki es mi salvavidas para entender cosas difíciles como DNS
      De hecho, después de ver una recomendación de libros en jvns.ca, leí Networking for System Administrators de Michael W. Lucas, y extraje tarjetas de Anki con conocimientos técnicos y no poca sabiduría de administración de sistemas
      Ahora, cuando depuro problemas de la capa de transporte, recuerdo de inmediato cómo usar herramientas como netcat y tcpdump, así que quizá sea uno de los libros con mayor retorno de inversión entre los que he leído
    • Mantengo un archivo con comandos que no uso con frecuencia. Por ejemplo, comandos para subir el volumen con ffmpeg o para agregar un borde a una imagen con convert
      También creé un atajo para agregar a ese archivo el último comando ejecutado, y otro para buscar dentro de ese archivo
    • Las páginas man se pueden usar de inmediato
      La página man de bash es enorme y compleja, pero exhaustiva. Si estás familiarizado con las secciones principales y con la forma visual del texto, puedes recorrerla rápido y encontrar la información exacta que necesitas, así que me ha resultado bastante útil
      Muchas veces este método es más rápido que usar un motor de búsqueda en internet
    • Para no depender de internet y al mismo tiempo no tener que memorizar malos diseños, quizá convenga invertir en documentación y chuletas más generales
      Por ejemplo, convertir páginas man antiguas a un formato más amigable para editores de texto, o usar mejores herramientas como tldr o Dash. Porque find no es el único caso
    • Hay que dejar de usar Bash y usar TypeScript en su lugar. Bash es horrible
  • No sé por qué, pero quería que no me gustara este artículo. Tal vez porque veía a jvns demasiado seguido en HN, o porque estaba de mal humor.
    Pero es un artículo realmente bueno y, como alguien con 20 años de experiencia en desarrollo, creo que está bastante cerca de la verdad entre las discusiones de nivel meta sobre programación.
    Lo de la visión selectiva encaja perfecto tanto con dig como con las páginas de man. He abierto man innumerables veces y me he sentido abrumado por un sinfín de opciones de configuración y flags de línea de comandos.
    Un tip que uso en man es la búsqueda estilo Vim con /. Por ejemplo, si quiero encontrar cómo hacer que grep imprima el número de línea de cada coincidencia y no me acuerdo, abro man grep, escribo /line y presiono Enter para buscar las apariciones de “line” dentro de la página man. La siguiente coincidencia es simplemente /.
    También me da un poco de tristeza la noticia de que Strange Loop terminó. Me enteré de su existencia recién por ahí el año pasado, pero muchas de las charlas parecían tener una calidad excepcionalmente alta.

  • No estoy para nada de acuerdo con la postura sobre bash. La mejor solución no es poner herramientas encima de bash ni memorizar sus rarezas, sino no usar bash.
    Esa es la única forma de evitar sus trampas.

    • Todavía no encontré un reemplazo adecuado para bash, especialmente para scripts.
      Las alternativas más comunes son 1) usar un shell nuevo como Oil shell [0], o 2) usar un lenguaje de programación como Python, JavaScript o PHP.
      El problema de un shell nuevo es que hay que instalarlo en cada lugar donde quieras usar scripts. En cambio, bash está en todas partes. Si no es un script que mantienes solo tú, también estás pidiéndole a otras personas que aprendan ese shell para poder mantenerlo.
      El problema de otros lenguajes de programación es que bash es inusualmente cómodo para lo que hace bien: encadenar comandos y manejar la entrada/salida de comandos y archivos.
      Cuando intentas hacerlo en otro lenguaje, de repente se vuelve mucho más complejo o, como mínimo, más verboso.
      Por eso sigo usando bash, pero reconozco que su fortaleza está en ejecutar otros comandos y manejar entrada/salida. Si es lógica compleja que no tiene que ver con eso, la paso a otro lenguaje. A veces no se trata de evitar bash por completo, sino de llamar un script de Python desde bash.
      Si otro enfoque les ha funcionado mejor, sería bueno que lo compartieran.
      [0] https://www.oilshell.org
    • Es un punto válido. bash es una herramienta excesivamente compleja, y resulta raro escribir otra herramienta encima de bash para hacerlo menos complejo.
      Además, esa herramienta nueva no tendrá las décadas de depuración por las que pasó bash. El problema está en bash mismo.
      Tendemos a subestimar la facilidad de uso y a sobrevalorar la “inteligencia”.
      El caso emblemático es Git. Es una herramienta muy inteligente, pero su usabilidad es terrible. Aun así, como la hizo Linus y Linus es inteligente, parece que el problema fuéramos nosotros.
      Obtenemos aquello que valoramos. Deberíamos valorar más la facilidad de uso.
    • Soy un fan entusiasta de shellcheck y he usado bash en serio y en profundidad, pero ningún linter ni herramienta encima de bash puede arreglar esto.
      La mejor solución es simplemente mantenerse lejos. En serio, hay que parar. No hay que hacerse el macho.
      Todo el modelo del lenguaje está fundamentalmente roto. Tipos centrados en strings, switches de modo globales, flags de una sola letra en los operadores de comparación básicos, comportamiento por defecto que ignora errores en todas partes, y especialmente las funciones.
      Una sola de estas rarezas bastaría para descartar un lenguaje, pero bash las tiene todas y más.
    • bash es raro porque no es un lenguaje de propósito general. Las cosas mencionadas en el artículo también tienen sus buenas razones. Por ejemplo, el hecho de que set -x pueda romper el comportamiento esperado de || y &&.
      Para empezar, ¿qué lenguaje se cae porque una función devuelve false? Hay lenguajes que lanzan excepciones, pero “false” es un valor válido que se puede devolver, ¿no?
      En los Makefile se ve lo mismo. La gente no entiende lo que está haciendo y, como nunca pensó profundamente en los sistemas de build, espera que se comporten de cierta manera.
      Por ejemplo, la asignación recursiva de Make hace tropezar a casi todo el mundo.
      FLAGS=-b, COMPILE=compile $(FLAGS), $(info compile command=$(COMPILE)), FLAGS=-a, myfile:, echo $(COMPILE) $? -o $@ imprime compile -b en la primera salida de información, pero la ejecución real termina siendo compile -a -o myfile.
      Aun así, si hiciéramos que todas las asignaciones se evaluaran de inmediato para alinearlas con otros lenguajes de programación, estaríamos quitando una herramienta muy útil. Mientras más entiendes estas herramientas, mejor sabes dónde usarlas y cuánto esfuerzo dedicarles.
    • No es tan fácil como suena, y eliminar bash por completo no siempre vale la pena en relación con el tiempo y el esfuerzo.
      Aun así, en general estoy de acuerdo. Intento pasar cualquier cosa mínimamente compleja a scripts escritos en un lenguaje menos raro.
      En esos casos, las herramientas que ayudan a evitar errores en el último 5% que queda en bash son muy útiles.