Metáforas con las que programamos

becquer

Existen múltiples metáforas posibles para el desarrollo de software que se reflejan en el lenguaje que usamos los programadores, y encauzan subrepticiamente la manera en la cual abordamos nuestro trabajo.

Inspirados por el lingüista George Lakoff y su libro "Metaphors we live by", en el post de hoy vamos a examinar en detalle algunas de ellas.

Arquitectura

La metáfora más popular quizá sea el desarrollo de software como arquitectura, de ahí sonoros títulos como "arquitecto de software". El concepto de "patrones de diseño" proviene originalmente de un libro de arquitectura, "A Pattern Language" de Christopher Alexander.

Pensar en nuestro software como si fuese un sólido edificio, desanima a emprender cambios radicales. Una reescritura completa corresponde a derribar el edificio y volverlo a construir, lo cual refleja acertadamente lo arriesgado del proceso y el coste que implica. No derribamos una gran mansión porque carezca de ascensor, intentamos dentro de lo posible inserir la nueva funcionalidad en la estructura existente, realizando inevitables compromisos. Claro, que si hablamos de una pequeña caseta en el campo (o sea, de un microservicio), el riesgo que representa el "derribo" es menor.

La idea de software como edificio no encaja muy bien con las metodologías ágiles. No es común que el cliente cambie sobre la marcha sus ideas sobre lo que hay que construir. Quizás, como una obra en construcción es algo tangible, las consecuencias que tendrá un cambio de planes se vuelven más evidentes. Por otra parte, es más fácil para un albañil comunicar el peligro de una pared mal construida que se inclina, que para un progamador comunicar el de un método mal escrito que se "inclina" debido a siete condicionales anidados.

 

Fontanería

Otra rica fuente de metáforas es la fontanería. Las tuberías ("pipes") son omnipresentes en la informática, tanto a nivel de sistema operativo, como a nivel de lenguajes de programación—especialmente los lenguajes funcionales, que gustan de representar la lógica de la aplicación como un encadenamiento de funciones por las que fluyen los datos. ¿Y qué es un proceso ETL sino una serie de tuberías, muchas veces explícitamente representadas en la interfaz de gestión? El creciente énfasis en las secuencias de eventos como concepto central de las aplicaciones no hará sino aumentar la aplicabilidad de la tubería como metáfora.

Donde hay tuberías, hay fugas. Las fugas de memoria ("memory leaks") son una metáfora curiosa. ¿Qué es lo que tiene la fuga? Presumiblemente la memoria libre disponible en el sistema, que imaginamos como una especie de líquido. Entonces, la fuga va hacia el programa que acapara la memoria, no desde el programa, ¿no? Hay varias teorías sobre el origen de la expresión.

La expresión "prueba de humo" ("smoke test", más frecuente en inglés) se refiere a un test preliminar no muy exhaustivo que pretende detectar problemas graves. Puede que tenga su origen en la fontanería: a veces se inyecta humo en tuberías para identificar posibles fugas. Hay una teoría alternativa según la cual el origen está en la electrónica: si un dispositivo se incendia tras activarlo por primera vez, es mala señal.

Cuando trabajamos con un sistema de control de versiones, no solemos pensar en el flamante lavabo de porcelana que tenemos en el baño. Pero los creadores de Git parece que sí, ya que ellos denominan "porcelain" a los comandos de alto nivel que el usuario invoca normalmente, en contraposición al "plumbing", que es como llaman a los comandos de bajo nivel, más difíciles de usar y que los usuarios normalmente no ven. Relegar una parte de tu programa al "plumbing" es casi una excusa para no esforzarse en hacerlo inteligible.

 

Costura

Fuentes de metáforas que me parecen insuficientemente explotadas son la costura y la confección. Cierto que ya usamos alguna que otra con esos orígenes, como por ejemplo la de "hilo de ejecución" que debemos a Victor A. Vyssotsky. Un hilo que se asoma y se oculta con cada puntada nos recuerda a un proceso que ocupa y desaloja el procesador.

En su clásico libro "Working Effectively with Legacy Code" Michael C. Feathers propone el concepto de costura ("seam"): un lugar donde dos partes de nuestro software entran en contacto y donde podemos insertar una interfaz que abra paso al uso de "mocks" o "fakes" para realizar pruebas. Quizás debiésemos disociar el concepto de "patrones de diseño" de la arquitectura, y basarlo más en los patrones de costura, que tienen incorporada esta noción de frontera entre componentes.

Y es que en la costura, como en el desarrollo de software, trabajamos con componentes modulares que permite infinitas combinaciones. Cuando programamos, recombinamos componentes mediante inyección de dependencias, que a decir verdad es más fácil que descoser a mano y recoser con la Singer.

La costura se ajusta mejor que la arquitectura a los métodos ágiles. Hay que tener trato directo con el cliente, "tomarle las medidas". Es un proceso iterativo: desde que el primer momento en el que tenemos algo "ponible"—cuanto antes, mejor—el cliente lo prueba y, tras mirarse en el espejo, nos ofrece valioso feedback.

 

 

No olvidemos que fue en el sector textil donde se dieron tanto los primeros albores de la automatización (el Telar de Jaquard, ejemplo temprano de "transformación digital", operaba con tarjetas perforadas), como las primeras reacciones a la amenaza del "desempleo tecnológico" (los luditas ingleses, y en España el conflicto de las selfactinas de 1854).

 

Los sentidos

Kent Beck acuñó el término "code smell", un aspecto del código fácilmente observable (bueno, "odorable") que merece una inspección más detenida porque puede indicar un problema en el código. El sentido del olfato fue elegido cuidadosamente para comunicar mejor la idea. 

Cabe preguntarse si podríamos usar más metáforas sensoriales en la programación. Por ejemplo, el término "encapsulamiento" me parece sumamente insulso. Preferiría hablar de "opacidad" o "transparencia" según cuadrase. En vez del famoso "código limpio" podríamos hablar de "código diáfano". ¡Y no desdeñemos el tacto y el gusto! ¿Qué os sugiere la expresión "interfaz áspera" (o suave)? ¿Qué podría significar una "recursión amarga"?

Estas últimas expresiones son imaginarias claro, pero hay una metáfora basada en el gusto que sí se usa en la práctica: el azúcar sintáctico ("syntactic sugar"), que significa una parte de la sintaxis del lenguaje que no permite expresar nuevos conceptos, pero sí expresar conceptos ya existentes de manera más sucinta. Por ejemplo, en Javascript las clases son azúcar sintáctico sobre la herencia de prototipos. El JSX de React también es azúcar, porque existen alternativas más verbosas que no requieren preprocesador. Hay programadores opuestos al uso indiscriminado del azúcar sintáctico que vuelven la metáfora contra sí misma, diciendo que causa diabetes en los lenguajes.

 

En conclusión

 "There are only two hard things in Computer Science: cache invalidation and naming things."

— Phil Karlton

 

"Los límites de mi lenguaje son los límites de mi mundo."

— Ludwig Wittgenstein

 

"If you can't give me poetry, can't you give me poetical science?"

— Ada Lovelace

 

Como programadores, evaluamos cuidadosamente los medios técnicos con los que afrontamos las tareas que nos encomiendan. También deberíamos evaluar las metáforas conceptuales a través de las cuales entendemos nuestro trabajo.

¿Estamos usando las más adecuadas? ¿Somos arquitectos, fontaneros o sastres? ¿O, quizá, alguna otra cosa?