Lectura de código: un superpoder para la caza de errores

2025-09-08

Esta publicación describe un cambio significativo en la carrera del autor: de la codificación iterativa a la detección proactiva de errores. En lugar de depender únicamente de la iteración basada en pruebas, el autor aboga por la lectura cuidadosa del código para identificar problemas de forma preventiva. La clave, argumenta el autor, es leer atentamente el código, construir un modelo mental completo del programa y luego identificar las diferencias entre ese modelo y el código real en Git. La publicación sugiere concentrarse en el flujo de control y las estructuras de datos, e identificar patrones potencialmente propensos a errores en el código. Este enfoque reduce drásticamente los errores y mejora la calidad del código.

Leer más
Desarrollo lectura de código

Bucles de reintento elegantes: Cómo evitar la redundancia y las pausas inesperadas

2025-08-27

El autor explora cómo escribir un bucle de reintento elegante que limite claramente el número de reintentos, evite pausas innecesarias después del último intento, reporte el error original si el reintento falla y evite la duplicación de código. Se comparan varios enfoques, decidiéndose finalmente por un bucle `try while` con un límite superior para garantizar la terminación, solucionando problemas de límites y posibles bucles infinitos en soluciones anteriores. Aunque la solución final no es perfecta, representa una mejora significativa en brevedad y robustez con respecto a intentos anteriores.

Leer más
Desarrollo

Un truco ingenioso en Zig: coincidencia parcial de enums

2025-08-09

Zig ofrece una solución elegante para manejar la coincidencia parcial en enums, evitando código redundante y el pánico en tiempo de ejecución. El artículo detalla una técnica inteligente usando `inline` y `comptime unreachable` para permitir que el compilador verifique ramas `else` innecesarias en tiempo de compilación, mejorando la robustez y legibilidad del código. Esto es particularmente útil cuando se trabaja con numerosas variantes de enum, simplificando significativamente la lógica del código.

Leer más

La utilidad incomprendida de `font-size-adjust`

2025-07-26

Este artículo cuestiona la idea errónea común sobre la propiedad CSS `font-size-adjust`. El autor argumenta que `font-size` especifica el tamaño del cuadro alrededor de un glifo, no el glifo en sí, lo que lleva a inconsistencias entre diferentes fuentes. En lugar de centrarse únicamente en la reserva de fuentes, `font-size-adjust` se puede utilizar para garantizar un tamaño más consistente en varias fuentes en una página. El autor recomienda configurarlo en `ex-height 0.53` en un reinicio de CSS para una mejor consistencia tipográfica.

Leer más
Desarrollo

Lector RSS minimalista: Creación de un feed de blog personalizado con Deno

2025-06-26

¿Cansado de los lectores RSS pesados? El autor adoptó un enfoque diferente, creando un lector RSS personalizado usando Deno y un simple archivo de texto. Muestra solo los títulos y enlaces de las tres publicaciones más recientes, sin almacenamiento de texto completo local ni marcadores de leído/no leído, y se actualiza automáticamente a diario mediante GitHub Actions. El código es conciso, fácil de entender y ampliar, el sueño de un minimalista.

Leer más
Desarrollo

Compilaciones Rápidas en Rust: Secretos para un CI Inferior a 10 Minutos

2025-06-20

Es una queja común que Rust compile lentamente, pero el autor argumenta que la mayoría de los proyectos Rust compilan mucho más lentamente de lo que deberían. Usando rust-analyzer (200.000 líneas de código más un millón de líneas de dependencias) como ejemplo, lograron un pipeline de CI de 8 minutos en GitHub Actions. El artículo detalla estrategias para optimizar los tiempos de compilación, incluyendo el aprovechamiento del caché de CI, la división de tareas de CI, la desactivación de la compilación incremental y la información de depuración, la reducción de dependencias, la utilización de `cargo build -Z timings` para el análisis de rendimiento y la arquitectura cuidadosa del código para evitar la instanciación excesiva de genéricos en los límites de crate. El autor destaca el impacto del tiempo de compilación en la productividad del desarrollador y recomienda optimizar regularmente los tiempos de compilación para mantener los tiempos de CI para grandes proyectos Rust en un rango razonable, por ejemplo, alrededor de 10 minutos.

Leer más

El Problema de Coordinación de Código Abierto: Lecciones del Escritorio Linux y LSP

2025-06-20

El autor utiliza su experiencia con NixOS y una aplicación KDE como punto de partida para discutir los desafíos de coordinar software de código abierto en el entorno de escritorio Linux. Destaca la falta de un estándar de API unificado en el escritorio Linux, lo que lleva a un ecosistema de software fragmentado, descrito como una "máquina de movimiento perpetuo al estilo Escher". Esto se contrasta con el lanzamiento del Protocolo de Servidor de Lenguaje (LSP) por Microsoft hace una década. Si bien la implementación fue mediocre, su mera existencia resolvió el problema de coordinación para las funciones de IDE, impulsando el progreso de la industria. El autor argumenta que la falta de coordinación de la comunidad de código abierto llevó a la oportunidad perdida de crear un protocolo de IDE unificado antes del LSP. El éxito de Linux, sin embargo, se atribuye al estándar de API predefinido proporcionado por POSIX, reduciendo las dificultades de coordinación. Este artículo invita a la reflexión sobre los mecanismos de coordinación de la comunidad de código abierto y los modelos de desarrollo de ecosistemas de software. Categoría: Tecnología

Leer más
Tecnología

Dos Consejos Prácticos para un Código Eficiente

2025-05-17

Este artículo presenta dos consejos prácticos para mejorar la eficiencia del código: mover las condiciones `if` hacia arriba y los bucles `for` hacia abajo. Mover las condiciones `if` a la función llamador reduce la ramificación, simplifica el flujo de control y mejora la legibilidad. Mover los bucles `for` a donde se procesan los datos en lote aprovecha las ventajas del procesamiento por lotes, mejora el rendimiento y potencialmente desbloquea la vectorización. Estos dos consejos se complementan entre sí, mejorando eficazmente la eficiencia del código, especialmente cuando se manejan grandes cantidades de datos.

Leer más
Desarrollo

Más Allá de la Selección Escalar: Procesamiento por Lotes de Flujos de Eventos para la Eficiencia

2025-05-15

El autor describe la ineficiencia del antipatrón de selección escalar en el diseño de servicios con estado, ejemplificado por un servidor LSP. Procesar eventos uno a uno lleva a retrasos y desperdicio de recursos. La solución propuesta es procesar flujos de eventos por lotes. Una función `batch_stream` fusiona eventos entrantes en lotes, mejorando significativamente la eficiencia. Bajo carga baja, se comporta como procesamiento de eventos únicos, pero bajo carga alta, reduce drásticamente la sobrecarga, aumentando el rendimiento.

Leer más
Desarrollo

Comptime de Zig: Metaprogramación potente pero contenida

2025-04-20

La característica comptime de Zig es conocida por sus capacidades: genéricos, compilación condicional y más. Sin embargo, es deliberadamente restrictiva, no permitiendo la generación de código dinámico, extensiones de sintaxis personalizadas, información de tipo en tiempo de ejecución (RTTI) e E/S. Este artículo explora el razonamiento detrás de estas limitaciones, mostrando cómo Zig logra metaprogramación eficiente y fácil de entender mediante la evaluación parcial y la especialización de tipo. Un ejemplo de función de impresión personalizada demuestra cómo Zig realiza la reflexión en tiempo de ejecución con seguridad de tipo sin RTTI. El artículo concluye elogiando la elegancia única de Zig en la metaprogramación; aunque menos potente que las alternativas, es notablemente eficiente y fácil de usar en la práctica.

Leer más

Depurador como REPL: Run to Cursor y Quick Evaluate Expression de IntelliJ IDEA

2025-03-28

Cansado de los depuradores tradicionales, especialmente de las limitaciones de gdb y lldb con código nativo, el autor descubrió un flujo de trabajo potente en IntelliJ IDEA. Combinando "Run to Cursor" y "Quick Evaluate Expression", el depurador se transforma en un REPL. "Run to Cursor" ejecuta el programa hasta la posición del cursor, mientras que "Quick Evaluate Expression" permite evaluar expresiones (¡incluso código recién escrito!) dentro del marco de pila actual. Este enfoque reemplaza la ejecución paso a paso por una interacción más experimental y bidimensional dentro del editor, utilizando la finalización del código y ofreciendo una experiencia de depuración significativamente más eficiente.

Leer más
Desarrollo

Utiliza opciones largas en scripts

2025-03-22

Muchas utilidades de línea de comandos ofrecen opciones cortas (-f) y opciones largas (--force). Si bien las opciones cortas son convenientes para el uso interactivo, las opciones largas son muy superiores en los scripts. Su mayor legibilidad y naturaleza autoexplicativa mejoran el mantenimiento y la comprensión. Por ejemplo, en Git, `git switch --create release-{today} origin/main` es significativamente más claro que `git switch -c my-new-branch`, especialmente en scripts complejos.

Leer más
Desarrollo opciones largas

Rust Hardcore: Un Ray Tracer sin Asignación Dinámica de Memoria

2025-01-30

Esta publicación detalla un estudio de caso sobre la escritura de una aplicación Rust usando solo una API mínima, artificialmente restringida (sin asignación dinámica de memoria). El autor critica el RAII (Resource Acquisition Is Initialization) por llevar a un manejo de recursos desordenado y propone un "modo hardcore": dividir el programa en un binario `std` y una biblioteca `#![no_std] no_alloc`, permitiendo solo que el binario solicite recursos directamente del SO. Usando un ray tracer de juguete como ejemplo, el autor explica meticulosamente el manejo de búferes de píxeles, la paralelización, el asignador de memoria y el análisis de escenas en este "modo hardcore", logrando, en última instancia, un ray tracer sin asignación dinámica de memoria.

Leer más
Desarrollo

Invariantes: Una herramienta poderosa para escribir código correcto

2025-01-12

Este artículo explora el concepto de 'invariantes' en programación y sus aplicaciones. Comenzando con un pequeño ejemplo: escribir una variación de búsqueda binaria que calcula el punto de inserción, el autor demuestra cómo definir y mantener invariantes conduce a código correcto. Los invariantes, explica el artículo, son propiedades que se mantienen verdaderas durante toda la evolución dinámica de un sistema, simplificando el razonamiento al evitar las complejidades de considerar múltiples caminos de ejecución. Ejemplos de proyectos como Cargo, rust-analyzer y TigerBeetle ilustran los beneficios del uso de invariantes en sistemas grandes, como una mejor mantenibilidad y rendimiento. El autor concluye resumiendo la importancia de los invariantes tanto en la programación a pequeña como a gran escala, destacando su valor en la escritura de código correcto y eficiente.

Leer más

Idea revolucionaria: Aplicando los principios de Magit al sistema de control de versiones jj

2024-12-13

El autor propone un enfoque novedoso: aplicar la interfaz de control de versiones Magit de Emacs (que usa archivos de texto como interfaz de usuario) al naciente ecosistema de control de versiones jj. El artículo destaca que la interfaz de usuario basada en texto de Magit ofrece eficiencia y portabilidad. Aprovechando el protocolo LSP, se puede implementar una experiencia similar a Magit en varios editores, evitando el desarrollo redundante. El autor prevé la generación de archivos de texto específicos (como .jj/status.jj) y el uso de funciones de LSP, como tokens semánticos, rangos de plegado e ir a la definición, para lograr operaciones de control de versiones similares a Magit. El objetivo final es crear una interfaz de usuario eficiente y multiplataforma para el control de versiones jj.

Leer más
Desarrollo