No fue el algoritmo. Fue la codificación.

Durante unos días, estuve seguro de que mi sistema tenía un error profundo y misterioso. Mis registros salían como basura. Un paso de conversión de datos producía archivos que salían sutilmente mal. Un subproceso me devolvía sinsentidos en lugar de la salida que esperaba. Salí a cazar un fallo en mi lógica, en algún lugar de la parte ingeniosa del sistema.

No había ningún fallo en la lógica. El error era que mi computadora y yo no estábamos de acuerdo sobre cómo deletrear.

El error que no estaba en el código

Lo que lo volvía enloquecedor era que todo parecía correcto. Podía leer el código que producía la basura y no veía nada malo en él. Los fallos eran extraños e inconsistentes: parte del texto llegaba bien, parte llegaba revuelto, algunos archivos se abrían perfectamente y otros estaban sutilmente rotos. Nada en el patrón apuntaba a una sola línea que yo pudiera ir a arreglar.

Esa inconsistencia, como aprendería más tarde, es una pista común. Pero en ese momento simplemente parecía que mi programa estaba embrujado.

Qué estaba realmente mal: dos programas, dos alfabetos

Aquí está lo que hay debajo. Las computadoras no almacenan el texto como letras. Lo almacenan como números, y para convertir esos números de nuevo en caracteres necesitas una tabla acordada — una codificación — que dice qué número significa qué carácter. Si dos partes de un sistema usan tablas diferentes, los mismos bytes significarán cosas distintas para cada una, y el texto escrito por una será malinterpretado por la otra.

Ese era todo mi error. Mi sistema operativo recurría por defecto a una codificación antigua y heredada, mientras que las herramientas y los archivos con los que trabajaba asumían la moderna, casi universal. Todo funcionaba mientras las dos tablas casualmente coincidían — lo cual ocurre, para los caracteres más simples — y se rompía en el instante en que algo se salía de esa superposición. El texto nunca se corrompía a propósito. Simplemente se leía en un idioma distinto del que se había escrito.

Por qué fue tan difícil de ver

Una discrepancia de codificación es una clase de error particularmente desagradable porque a menudo no falla de forma limpia. En lugar de lanzar una excepción que señale el problema, una conversión permisiva puede producir una salida que es casi correcta, justo hasta que se encuentra con un carácter sobre el que las dos codificaciones discrepan — y entonces destroza silenciosamente solo esa parte y continúa.

Así que los fallos son intermitentes y dependen del contenido, que es exactamente el perfil que te manda a buscar en el lugar equivocado. Los errores intermitentes y dependientes del contenido parecen tener que vivir en tu lógica, en la parte complicada de la que estás orgulloso. Este vivía en las cañerías, en un valor por defecto en el que ni siquiera me había dado cuenta de que estaba confiando.

La verdad poco glamorosa de este tipo de trabajo

Había imaginado que las partes difíciles de construir un sistema de aprendizaje serían las partes interesantes — los modelos, las matemáticas, la estrategia. Resultó que una fracción genuinamente grande de las partes realmente difíciles eran cosas como esta. Codificaciones de texto. Finales de línea. Rutas de archivos que significan cosas distintas en máquinas distintas. La aburrida infraestructura que hay debajo de todo, donde un único valor por defecto equivocado puede devorar silenciosamente una semana de tu vida mientras miras fijamente el elegante código de arriba, convencido de que el problema tiene que estar ahí.

Es aleccionador, de una manera útil. Las matemáticas rara vez fueron lo que más a menudo me detuvo. Lo fueron las cañerías.

La solución: dejar de confiar en los valores por defecto, forzar el acuerdo

La reparación no fue sutil. Dejé de confiar en cualquier codificación que cada parte del sistema casualmente tuviera por defecto, y forcé una explícitamente — la moderna, universal — en cada frontera: cada lectura de archivo, cada escritura de archivo, cada subproceso lanzado. Una vez que se obligó a cada componente a estar de acuerdo, por escrito, en la misma tabla, la basura se detuvo.

Junto a esa solución principal, añadí un hábito defensivo más pequeño: mantener ciertos caracteres problemáticos fuera de mis registros desde el principio — no como sustituto de hacer bien la codificación, sino como red de seguridad. Los registros son el único lugar donde más necesitas poder leer con claridad cuando todo lo demás está en llamas, y no quería que la herramienta de la que dependo para diagnosticar problemas siguiera siendo víctima de la misma clase de problema.

La lección: un valor por defecto es una decisión que no tomaste

La lección más profunda sobrevivió al error. Cada “valor por defecto” en tu pila es una decisión — normalmente tomada por alguien que no conocía tu situación particular, a menudo hace años, por razones que quizá ya no apliquen. La mayor parte del tiempo esas decisiones heredadas están bien, y nunca tienes que pensar en ellas. Eso es parte de lo que las hace peligrosas. Cuando una de ellas resulta estar silenciosamente equivocada para tu caso, es casi invisible, porque nunca la elegiste conscientemente — y lo que nunca elegiste es el último lugar donde piensas en mirar.

Perdí la mayor parte de una semana por una elección que no sabía que había hecho. Ahora, cuando algo falla de una manera que no tiene sentido lógico, una de mis primeras preguntas ya no es solo “¿dónde está mi error?”. También es “¿qué estoy asumiendo que en realidad nunca decidí?”.

— Sin señales, sin retornos, esto no es asesoramiento de inversión.