sábado, 28 de febrero de 2009

Del desarrollo del lenguaje en la búsqueda de la perfección.

Si para algo me ha sevido este blog es a contrarrestar los efectos de la programación sobre la calidad de mi lenguaje cotidiano. Me he sentido muy identificado con este párrafo:

You have to pour your heart and your soul into accepting nothing but perfection from that damn regular expression, that damn CSS selector, that damn SQL case statement, that bloody mother f***ing a*****e of a *** **** son of a ******* ugly ***** ***** **** of a **** installation package, so the lucky ******* **** of an end user gets all the joy of a working system.

(Extracto de Low Frustration Tolerance: Curse and Blessing - secretGeek)

En efecto, si transcribiera todo lo que digo cuando programo sería algo muy parecido a ésto:

****** de ****** una san ******* y la ****** madre ****** que lo ******* por qué ****** si esta ***** *****… ¡Funciona! Tomá, ***** de la ****** madre que te ******.

viernes, 27 de febrero de 2009

Jueguitos de viernes: Super Stacker 2.

Siguiendo la línea Jelly Towers, Perfect Balance y Totem Destroyer 2, el siguiente sería Super Stacker 2, en el que también tenemos que apilar diferentes figuras geométricas sin que caigan hacia el fondo de la pantalla.

Tiene un buen toque de humor y música jazzera. Los primeros niveles son tal vez demasiado fáciles, pero finalmente aparecen los problemas.

ss2

La “respuesta” a “¿Cuál es el error?”, la ambigüedad, su resolución y, finalmente, la realidad.

question Estamos hablando del problema planteado en el post ¿Cuál es el error? Si no lo has leído (con sus comentarios) no vas a entender nada (es simple y cortito, no hay excusa).

Me encanta ese problema ya que es disparador de un montón de cuestiones relacionadas a la codificación entre las que encontraremos muchas zonas grises. Algunos (como yo) verán las suficientes para afirmar sin lugar a dudas que programar está a medio camino entre el arte y la técnica, y que para el ojo entrenado no es difícil encontrar cierta belleza (o por lo menos elegancia, una de sus formas) en algunos ejemplos.

Bueh, tal vez me emocioné un poco. De todas maneras lo anterior sirve para aclarar que lo que sigue es mi personalísima opinión y que si bien puede ser contraria a la de algunos de ustedes no pretende ni puede invalidarla en manera alguna ya que, como establecimos, son zonas grises.

La solución “estricta”.

Siendo riguroso con el enunciado del problema, creo que la respuesta más acertada es “No se puede saber”.

Parece que hay un error (y aunque eso parece claro, si leyeron los comentarios en la entrada del planteo verán que hasta eso puede objetarse) ya que la declaración dice que suma pero la implementación resta. No hay forma de decidir qué está mal sin un contexto.

Lo más que podemos decir es que el código es poco legible, que es confuso, ambigüo (para un ser humano) o traicionero. Lo que no podemos decir (sin contexto) con seguridad es que hay un error de esos que le interesan a la gente común, y mucho menos decir cuál es. El único error que podemos verificar es de estilo o prolijidad, y no podemos resolverlo.

De acuerdo al contexto el error podría ser nimio, de esos que uno corrije sin decir nada a nadie (sería obviamente de tipeo, el programador quiso poner “+” y le salió un “-”. Algunos de los muchos números del reporte –por ejemplo- salieron mal, pero eran tantos que era difícil darse cuenta. En las pruebas, para un analista que interprete esos números, será mucho más evidente que para un programador cansado o aburrido de hacer reportes)… o grosero, muy grosero. Que se entienda bien clarito: al programador que utilice eso para restar, repetida y consistentemente en cualquier porción de código, yo le deseo la muerte.

Mejor volvamos a nuestro problema, sin contexto. Uno de los principios de diseño de Guido Van Rossum (autor de Python, entre otras cosas) nos dice:

Cuando te enfrentes a la ambigüedad, rechaza la tentación de adivinar.

Es muy, muy difícil de seguir. Casi tanto como decir “No sé” o “No se puede saber”. La primera respuesta es dolorosa para un orgullo cultivado (y los programadores sí que cultivamos el nuestro) y la segunda requiere mucha confianza y conocimiento del tema que se trata.

Por otro lado las preguntas engañan. No es lo mismo preguntar “¿Cuál es el problema?” que “¿Hay un problema?”.

Vivimos en un mundo imperfecto y una computadora no entiende de imperfecciones. A los programadores nos toca ser el último eslabón entre lo ambigüo por naturaleza (el lenguaje, los negocios, el ser humano, la vida en general) y lo absoluto (una sucesión finita de operaciones), así que lidiamos con este problema -de enfrentarnos a la ambigüedad- todos los días.

Un ego desmedido como el nuestro no digiere fácilmente que (si bien podemos hacer cualquier cosa) no somos dueños de la verdad absoluta (no todo lo que hagamos estará bien -¡aunque funcione!-) y que -peor todavía- existe la verdad absoluta y tiene dueño: el cliente. Utilizando estrictamente las palabras, los programadores somos dueños de la implementación, pero no de la solución. Decidimos cómo pero no qué.

El cliente (o quien lo represente ante nosotros, los programadores) puede equivocarse en muchas cosas, pero cuando hay que resolver una ambigüedad tiene no sólo la última, sino la única palabra. En el trabajo de todos los días no podemos decidir si “una operación revertida aparece en el informe o no”. ¿Por qué no? Porque estaríamos inventando y tal vez invirtiendo tiempo en hacer bien algo que nunca debería haberse hecho.

Recuerden siempre: las preguntas engañan. Siguiendo el ejemplo de la operación revertida, es probable que hayamos arribado a esa opción binaria más por nuestra naturaleza de programadores que por la realidad de la situación. ¿El cliente pensó en esta situación? No. Entonces, ¿cómo podemos saber que la solución es una u otra, y no una tercera, o ninguna, o las dos?

¿Cómo saber si hay que sumar o restar? No lo sabemos. No sabemos qué es lo que hay que hacer si no nos lo comunican, tenemos que preguntar. La frase de Guido nos está diciendo “más fácil inventar parece, pero evita la tentación, porque buscar una respuesta debes” (¿o ése era Yoda?). Ésa es, en principio, nuestra responsabilidad: resolver la ambigüedad preguntando, no inventando.

Es también, entonces, un tema de responsabilidades (“Un gran poder conlleva una gran responsabilidad”): ¿tenemos ese poder para decidir? ¿queremos esa responsabilidad? Recordemos, otra vez, que estaríamos tomando una decisión sin conocer todos los detalles: no conocemos el negocio, al cliente final, ni la situación comercial… tal vez ni siquiera el sistema completo.

Pero, ya lo dijimos, vivimos en un mundo imperfecto. Muchas veces (en todo proyecto real esta situación es más que frecuente) el cliente no está disponible (si estuviese disponible él tiene la respuesta, aunque ésta sea “hacé lo que te parezca” o tire una moneda o cambie con el tiempo) o no entiende la pregunta. ¿Entonces?

La frase nos dice “evita la tentación”, no nos dice “no adivines”. Hay veces que tenemos que adivinar. Presionados por un sinfín de circunstancias, para bien o para mal, hay veces que hay que adivinar y seguir adelante, rellenar los huecos en las especificaciones apelando al sentido común o, en última instancia (es lo que yo lo recomiendo) hacer lo que sea más fácil para nosotros, así por lo menos el tiempo perdido será menor.

Pero tenemos que ser conscientes de que lo estamos haciendo. Y de que está bien si lo hacemos sólo si hemos agotado otras instancias (o no tenemos tiempo de hacerlo) y no nos queda otra, y no para patear un problema debajo de la alfombra.

La razón última por la que un proyecto no puede llevarse a cabo sin la cooperación y compromiso real de los programadores que en él participan (por lo menos de buena parte de ellos) es que (como una computadora no entiende de ambigüedades) estas pequeñas decisiones…

  • que nos vemos obligados a tomar sin información completa
  • o con la poca que logremos recabar investigando hasta donde dé nuestra conciencia,
  • basándonos en nuestra experiencia, sentido común, pálpito y buena suerte,
  • sabiendo que en el mejor de los casos evitaremos un problema y nadie se dará cuenta ni agradecerá nada,
  • y que en el peor de los casos… (mejor no hablar de ello)

…tienen gran impacto (para bien o para mal) en el resultado. Tanto que son determinantes, tal vez no del éxito (que dependerá también de muchos otros factores), pero seguro que del fracaso de un proyecto (que con una buena cantidad de decisiones equivocadas o con apenas un par en los lugares precisos puede darse por muerto).

La mejor manera de sabotear un proyecto es hacer exactamente lo que te piden, sin chistar.

jueves, 26 de febrero de 2009

El control total y sus consecuencias.

Juan Carrión (Jano 2.0) tiene una increíble capacidad para generar imágenes y frases impactantes, de esas que no puedo dejar de referenciar.

Éste es un pequeño extracto de Panópticos: Diez años y un día:

Las consecuencias del control total son terribles, ya que “los maltratados” tienden a vengarse de las empresas que los maltratan, convirtiéndose en auténticos terroristas. Sin duda, cada empresa tiene tantos empleados terroristas como se merece.

Frankenstein, el líder de proyecto (XII).

ATENCIÓN: ¡No sigas si no has leído la onceava parte! Y si no has leído nada empieza por el principio.


[Resumen: Frankenstein encomienda al líder técnico que complete la codificación del módulo, resolviendo las incongruencias y pequeños errores de las especificaciones. El líder accede por primera vez al código de la criatura, descubriendo con horror que es inmenso y completamente ilegible, y por tanto inmodificable. “¿Pero quién carajo es el monstruo que le enseñó a programar a este tipo?”, exclama. Él no lo sabe, pero ese monstruo no es otro que Frankenstein.]

El líder sostenía su cabeza con las manos, los codos apoyados en el borde del escritorio, la silla alejada de éste, la vista perdida entre los detalles de la alfombra.

Algo en el sonido del grito que acababa de liberar –un timbre de genuino horror, una nota que denotaba algo más que un grave problema, algo más que un incidente laboral… una nota que transmitía desesperación, furia, impotencia… locura- había actuado sobre el resto de los ocupantes de la oficina. Todos –todos menos la criatura, que continuaba tipiando impasible- habían interrumpido sus tareas y miraban fijamente en dirección al líder, inmóviles, esperando alguna reacción.

No la hubo. Un programador se acercó tímidamente y observó la pantalla. Detrás de él se aglutinaron los demás. Inclinándose por sobre el cuerpo del líder, el programador corrió un poco el teclado y giró el monitor.

Se enderezó, luego de unos instantes. Cruzó el brazo izquierdo sobre el pecho. En la mano izquierda apoyó el codo derecho, y la mejilla en su mano derecha. Así permaneció, con la boca abierta, mientras los demás repetían aquello que parecía un extraño ritual.

El silencio era absoluto. Algunos se miraban entre sí, otros al piso. Otros volvieron a sus lugares, reconcentrados, incrédulos, intentando asimilar lo que habían visto.

No era la visión de aquel código lo que los horrorizaba, sino el asomarse a la naturaleza de su autor e imaginar su origen.

Un programador ve en el código de otro su lógica, su forma de pensar, el camino que recorre su cerebro en busca de una solución, sus problemas, sus dudas, sus errores. ¿Qué revelaba de la criatura aquel ejemplo abominable?

Una ausencia, un vacío. No una lógica ajena, extravagante, complicada o simplemente equivocada (como estaban acostumbrados a ver de vez en cuando), sino una carencia, un vacío absoluto. Carencia de lógica, de comprensión, de razonamiento.

- Es… siniestro –dijo uno de ellos, rompiendo el silencio.

- ¿Qué es siniestro?

- Cuando lo cotidiano se vuelve extraño.

- Es… como… es como… un compilador de documentación funcional.

Alguno esbozó una sonrisa triste. Era solamente eso, al fin y al cabo. Un autómata de carne y hueso, una máquina de traducción simple, lisa y llana del lenguaje al código, un paso más, mecánico, transparente e inútil entre el analista y el software.

Pero parecía humano. Era esa similitud lo que lo volvía siniestro y -en principio- atemorizante.

El líder sollozaba. Y tal vez algún programador contuvo una lágrima. No por el fracaso del módulo o del proyecto, sino a causa de la profunda tristeza que inspiraba su autor, tan humano en apariencia.

Luego del rechazo, del temor y del horror ante la visión del vacío, éste sólo inspiraba una tristeza absoluta.

Un programador –el mismo que había roto el silencio- se acercó a la criatura y apoyó una mano en su hombro, pero ésta continuaba trabajando, ajena a todo y todos a su alrededor.

- ¿Qué está haciendo? –preguntó alguien desde el otro extremo de la oficina.

- Nada, sólo sigue escribiendo.

…continuará. Actualización: capítulo XIII.

miércoles, 25 de febrero de 2009

Frases: personas y planificación.

Una muy buena frase de Clay Shirky, citada en Buenas y malas prácticas en la transición hacia la “Empresa 2.0″, de El Caparazón:

Los sistemas con buenos participantes producen mejores resultados que los que fueron bien planificados.

¿Cuál es el error?

Una bobada para pensar un rato, de esas que me gusta tirar en las primeras clases: ¿qué está mal en este código, y por qué?

public decimal Suma(decimal a, decimal b)
{
 return a-b;
}

Obviamente el "por qué" es lo más importante de la respuesta. No consulten ninguna fuente (pierde la gracia), sólo sigan su instinto y, si quieren, dejen un comentario (sin mirar antes los de los demás).

Actualización: el tema se resuelve (en parte) en La “respuesta” a “¿Cuál es el error?”, la ambigüedad, su resolución y, finalmente, la realidad.