Tengo varias experiencias con “código malo”. Muchas veces trabajé solo, pero también en equipos escribí código que simplemente funcionaba, aunque no era óptimo. Cuando intentaba refactorizar código viejo junto con trabajo nuevo, a menudo me lo rechazaban; y aunque dejara como tickets las refactorizaciones o correcciones necesarias, normalmente quedaban relegadas en prioridad o se ignoraban.
Si estás solo, puedes priorizar el trabajo necesario, pero en un equipo las decisiones subóptimas pueden quedar para siempre o abandonarse hasta el momento de “se cayó el sistema”. Después, en el postmortem, si señalaba un ticket de meses atrás en el que pedía arreglar esa bomba, se tomaba como “culpar” o “ser agresivo”, y al final la solución parecía ser nunca escribir código subóptimo, lo que aumentaba la frustración y la ansiedad al programar.
En 2017 también me contactaron para arreglar código que había escrito en 2003/2004, y ese código seguía en producción. Volver a ver el código roto y las concesiones que hice, y darme cuenta de que el responsable era yo, fue una experiencia bastante humillante; después de eso cambió mucho mi perspectiva sobre el código mantenible y la documentación.
Depende del equipo y de la empresa. He pasado por muchos equipos donde se alentaba a los desarrolladores a dedicar tiempo al mantenimiento y la refactorización del código, a veces incluso se los obligaba a hacer solo eso; donde el trabajo centrado en ingeniería tenía prioridad sobre requisitos aleatorios de producto, y donde también se ajustaban los plazos para terminar bien las cosas.
Tuve estas experiencias en grandes empresas del S&P 500, compañías de entre 100 millones y 1.000 millones de dólares, y startups; era algo común. En esos casos había ingenieros de software y managers experimentados, capaces de hacer compromisos razonables y atender también las necesidades del negocio, y era frecuente que los ingenieros interactuaran directamente con los clientes.
La clave es el equilibrio, y ese equilibrio normalmente lo generan personas capaces de juzgar de forma equilibrada. Si solo se busca la “perfección”, se termina en refactorizaciones interminables y lanzamientos que nunca llegan; si se ignora la deuda técnica o la calidad basura, con el tiempo el negocio puede venirse abajo. Dónde ubicarse depende del producto, la industria, los clientes y el negocio.
O mueres como héroe, o vives lo suficiente para ver tu nombre en un git blame de hace 10 años.
“Funciona, pero no es óptimo” suele ser un compromiso aceptable cuando falta tiempo y hay mucho por hacer. Esloganes de MBA como “lo perfecto es enemigo de lo bueno” también sirven para justificarlo cuando falta algo.
Que en 2017 te hayan llamado para arreglar código escrito en 2003/2004 también significa que todos somos viajeros en el tiempo. Soy generoso con mi yo del pasado y ligeramente grosero con mi yo del futuro.
Mi yo del pasado era joven e ingenuo, pero productivo, y superó muchas montañas. Me tomó dos días entender el código, pero al final era bastante ingenioso; quizá si mi yo actual lo olvidó todo fue por mala memoria.
Mi yo del futuro corregirá todos los errores. Creo que será más viejo y sabio, que convertirá XXX y TBD en código inteligente, y que tendrá tiempo infinito para implementar las buenas ideas y volver a implementar las ideas más o menos. Tal vez, con mejores comentarios, los tres podamos ser uno.
Creo que esta actitud justiciera de ser “esa persona” es dañina. Que un desarrollador senior pueda hablar de sus errores y de las cosas que le salieron mal es muy liberador y saludable.
No solo es una oportunidad de aprendizaje, sino que también muestra una cultura abierta y ayuda a combatir el síndrome del impostor. La actitud perfeccionista hace lo contrario: se reduce a “esfuérzate más y no cometas errores”, no deja nada que aprender y solo exige más esfuerzo individual.
Al menos dos veces sospeché que “esa persona” no habría reconocido un error grande, lo habría evitado incluso a costa de perder a un buen cliente, y habría hablado mal a sus espaldas.
Una vez asumí un pequeño error de un junior que puso una versión de software incorrecta en un informe; habría bastado con decirle al cliente “hubo un error y aquí está el informe corregido”, pero mi jefe solo pensaba: “¿podemos ocultar esto y mantener la imagen de que somos perfectos?”. Esa misma persona usaba los errores de otros como oportunidad para exigir descuentos, compensaciones o entregas gratis.
Creo que la mayoría simplemente hace su trabajo y mejora. En nuestra gestión de configuración hay bastantes cosas que escribí y que funcionalmente andan bien, pero después de manejar las herramientas durante uno o dos años empecé a considerarlas de bastante mala calidad por varias razones.
Aun así está bien. Si surge una razón para cambiarlas, las ordenaremos; hasta entonces quedan como ejemplos de malas prácticas y de mejores enfoques posibles.
Si no encuentras nada que criticarte a ti mismo, significa que no estás mejorando. Compartir esa autocrítica permite que otros aprendan de mis errores y entiendan que está bien aprender de los propios.
En las revisiones de código escucho a menudo cosas como “¿por qué simplemente no evitas cometer ese error?” o “¿por qué simplemente no lo haces así?”.
Últimamente respondo: “Probablemente sea porque tu IQ es más alto que el mío. Como mi IQ es bajo, tengo que hacer cosas más tontas y simples”. A veces eso hace que la otra persona se dé cuenta de lo poco reflexiva y despectiva que fue, como un pequeño rarito, y se ponga roja.
Les tengo un poco de alergia a las preguntas que empiezan con “¿por qué simplemente no…?”. Apenas oigo esas tres palabras, normalmente ya puedo anticipar la sugerencia que viene después; no porque sea enormemente compleja, sino porque suele ser la solución obvia que se te ocurre primero y que ya fue considerada o probada con cuidado.
La pregunta en sí no es mala, pero la premisa de “mi idea es facilísima” y “tú no pensaste en esta idea obvia y fácil” puede sentirse molesta o insultante. En cambio, cuando yo le pregunto a alguien, trato de evitar el “por qué simplemente” y prefiero algo como “¿puedo entender que no hiciste X por algún motivo?”, o quizá es mejor simplemente preguntar el motivo con amabilidad.
Si la pregunta surge por falta de contexto, puedo evitarla explicando, antes de describir lo que hice, por qué no funcionaron los enfoques más obvios o cuáles eran los requisitos difíciles y las entradas problemáticas. Si el código ya está commiteado, el objetivo es reducir comentarios tardíos en el commit o en el merge request. A veces también sirve no refutar, explicar directamente que probé ese método pero por qué no funcionó, y preguntar sinceramente si tienen otra idea.
Si de verdad es una sugerencia que no había considerado y parece que puede resolver el problema, digo que es una buena idea y pido ayuda para implementarla. En ese momento existe la tentación de confrontar la premisa o el tono de la otra persona, pero intento simplemente aceptarlo y sentir un poco de vergüenza por un rato.
Es un caso muy bien aplicado de grug brain: https://grugbrain.dev/
“Si grug tiene que elegir entre pelear uno a uno contra complejidad o tiranosaurio, grug elige tiranosaurio. Al menos grug puede ver al tiranosaurio”.
Si no es broma, la primera pregunta no ayuda y es casi una maldad. Cualquiera comete errores de vez en cuando.
La segunda pregunta normalmente puede ser un feedback válido. Las habilidades y los conocimientos de las personas no siempre se superponen. Algo absurdamente complicado para A puede no serlo para B, y viceversa; y eso no necesariamente significa que alguien sea más inteligente. A puede no saber SQL y B puede no saber pandas
Si suponemos que el stack tecnológico ya incluye tanto SQL como pandas, a veces tiene sentido mover cierto código de SQL a pandas, o al revés. A algunas personas les resulta más fácil el estilo orientado a objetos; a otras, el estilo funcional. No siempre es obvio qué tiene más sentido, así que la pregunta puede ser una buena pregunta. Si la propuesta es mala, se explica por qué es mala; si es buena, se evalúa si vale la pena hacerla ahora. Si está en un punto intermedio o no hay tiempo, se reconoce y se sigue adelante
Otra alternativa es simplemente estar claramente de acuerdo. Se puede responder “Sí, fue una tontería, ¿no?” o “Sí, quizá no debimos hacerlo así”, o “Lo voy a pensar”
Entonces a la otra persona le cuesta avergonzarme o hacerme sentir culpable por haber hecho algo subóptimo. Creo que a menudo el objetivo de este tipo de comentarios es establecer superioridad mediante la vergüenza. Es elegir no participar en el juego, y por lo general esa es la jugada ganadora
Si lo dijeron por ignorancia, no hace falta tomarlo como un ataque y hacer que la otra persona pague avergonzándola
No encuentro el blog o artículo que vi hace tiempo, pero el mensaje era: “no asumas incompetencia solo porque viste algo subóptimo en el código”. La persona que escribió ese código pudo haber tenido una fecha límite apretada, otras prioridades u otros factores que le impidieron hacer de inmediato “lo correcto”
Aunque el código haya sido perfecto cuando se escribió, el crecimiento de la base de código y los cambios de requisitos pueden volverlo malo
Por ejemplo, si hay que guardar 10 elementos, un archivo simple puede ser una opción práctica, pero si pasan a ser 10.000, quizá haga falta una base de datos. Pero si desde el inicio se hubiera usado una base de datos para 10 elementos, alguien se habría quejado de sobreingeniería
Con 2 clases, un if/else basta; con 20, quizá haga falta el patrón Factory, y si se hubiera hecho desde el principio habría parecido astronauta de arquitectura. Si intentas predecir ese crecimiento y te equivocas, terminas creando código complejo. Los proyectos que se desarrollan continuamente crecen de manera sistemática más allá de sí mismos
También está la cerca de Chesterton. Algo tonto en el código pudo haber sido realmente importante antes. Peor aún, puede seguir siendo importante para algún caso límite poco común, pero quizá todavía no has visto por qué
Recibí varias veces comentarios maliciosos sobre publicaciones de blog, aquí y en reddit. En esos casos uso el método de agregar al artículo un enlace al comentario malicioso, sin juzgarlo, para ponerlo bajo la luz. Normalmente no pasa nada, pero a veces ayuda a encauzar la discusión hacia un rumbo más saludable
Yo también he recibido bastantes. Quizá algunos me los merecía, pero probablemente la mayoría no. Algunos tenían algo de razón, pero no ayudaban o eran directamente dañinos para la comunidad. Decir algo correcto de la forma incorrecta sigue siendo decir algo incorrecto
Enlazar comentarios maliciosos sin juzgarlos no es una mala idea. No siempre es posible si el comentario fue marcado como muerto, pero en cualquier caso no respondo del mismo modo. Podría hacerlo, pero aprendí que la gasolina no es un extintor eficaz
Si me equivoco, intento reconocerlo de inmediato en el mismo lugar donde ocurrió el error. Me disgustan especialmente las disculpas privadas después de un ataque público
Hay una línea. Siento que hago un trabajo bastante bueno, llevo unos 40 años haciéndolo y he aprendido mucho en ese tiempo. También trabajé en entornos exigentes que no aceptan trabajo de baja calidad, así que hacer un trabajo decente se volvió un hábito
En general evito juzgar públicamente a otras personas. No ayuda, y tampoco siempre tengo razón. Pero puede ser distinto si trabajo con esa persona o uso lo que hace. Me han atacado con dureza por no aceptar basura, pero no actúo como Linus Torvalds. Cuando es posible, digo de forma respetuosa que ese trabajo no es aceptable para mí
Aun así, siempre se puede mejorar y aprender cosas nuevas, y a veces uno aprende de lugares totalmente inesperados. Estar abierto a ese aprendizaje es, en el fondo, una buena política. Me vuelvo correcto equivocándome y aprendiendo. “El buen juicio viene de la experiencia, y la experiencia viene del mal juicio”
Uno de mis podcasts favoritos, well there's your problem en YouTube, casi siempre fija comentarios que se quejan del podcast. En general son quejas del tipo “no me gusta este podcast, así que debería convertirse en otro podcast”, y el comentario fijado suele estar cerca de la interpretación más tonta posible de ese episodio
No sé si sirve para reducir esos comentarios, pero sí tiene el sentido de ponerle un gorro de tonto metafórico a la persona que participa en el discurso de esa manera
Estoy de acuerdo en que algunos ingenieros tienen mala actitud. Cualquiera puede escribir mal código, y también hay algo de verdad en la lógica de que todo código es malo y es deuda
Este artículo es interesante para leerlo junto con “No more pink mustache”. En ese texto se describe a Lyft como “rota a una escala increíble”, y la causa de la calidad suele ser la organización, no la persona sentada en la silla :-)
[1] https://rachelbythebay.com/w/2020/02/29/poof/
Leí este artículo en 2018 y me alegra que haya vuelto a aparecer. Fue uno de los textos que me hizo plantearme preguntas. Si no podemos eliminar el absolutismo o el extremismo, me hace pensar qué filtro podemos construir al encontrarnos con este tipo de conversaciones o personas. Tengo mi propio modelo, pero me da curiosidad qué estrategias usan los demás
Este tipo de personas intentan ocupar un territorio emocional que no les pertenece. Por lo general ya calcularon de antemano que “pueden hacerlo”, lo que significa que ven a la otra parte como débil
Hay tres opciones. Rendirse, ceder ese territorio y seguir con la vida; cuanto menos sueño pierdas por la injusticia, mejor. Enfrentarlos de frente; ellos están preparados para pelear, pero como su postura es inherentemente irracional, cuanto menos te arrastren a su espacio mental, más “ganas”. O venir desde arriba: llevar a su espacio prueba social de que están equivocados. En el caso del artículo original, serían programadores productivos que respetan el trabajo de los demás y no se dedican a buscarle cinco pies al gato
Cuando alguien aconseja “podría haber sido mejor hacerlo así”, eso no siempre es un ataque contra mí ni un insulto a mi capacidad
La persona que da el consejo podría ser un idiota torpe en sus relaciones interpersonales, o simplemente un completo idiota. Está bien que una parte del mundo no esté de acuerdo conmigo. Que la gente exprese opiniones contrarias o no esté de acuerdo no significa que me esté amenazando.
Es un texto raro. Suena como un tuit, tiene poco contenido y el título no refleja el cuerpo, así que parece clickbait.
No estoy en contra de la idea principal, pero también está la otra cara. También hace falta la capacidad de aceptar feedback.
La mayoría de las personas puede aceptar y aplicar feedback. Solo que algunas personas dan feedback de forma pésima y luego creen que la otra persona no sabe aceptarlo.
Estas personas piensan que su forma preferida de dar feedback es la mejor y que todos deberían sentir lo mismo; si no, consideran que la otra persona debe cambiar. Por supuesto, están equivocadas. Pero si les dices esto, ellas mismas demuestran por qué dije “la mayoría” en la primera oración.
1 comentarios
Opiniones de Hacker News
Si estás solo, puedes priorizar el trabajo necesario, pero en un equipo las decisiones subóptimas pueden quedar para siempre o abandonarse hasta el momento de “se cayó el sistema”. Después, en el postmortem, si señalaba un ticket de meses atrás en el que pedía arreglar esa bomba, se tomaba como “culpar” o “ser agresivo”, y al final la solución parecía ser nunca escribir código subóptimo, lo que aumentaba la frustración y la ansiedad al programar.
En 2017 también me contactaron para arreglar código que había escrito en 2003/2004, y ese código seguía en producción. Volver a ver el código roto y las concesiones que hice, y darme cuenta de que el responsable era yo, fue una experiencia bastante humillante; después de eso cambió mucho mi perspectiva sobre el código mantenible y la documentación.
Tuve estas experiencias en grandes empresas del S&P 500, compañías de entre 100 millones y 1.000 millones de dólares, y startups; era algo común. En esos casos había ingenieros de software y managers experimentados, capaces de hacer compromisos razonables y atender también las necesidades del negocio, y era frecuente que los ingenieros interactuaran directamente con los clientes.
La clave es el equilibrio, y ese equilibrio normalmente lo generan personas capaces de juzgar de forma equilibrada. Si solo se busca la “perfección”, se termina en refactorizaciones interminables y lanzamientos que nunca llegan; si se ignora la deuda técnica o la calidad basura, con el tiempo el negocio puede venirse abajo. Dónde ubicarse depende del producto, la industria, los clientes y el negocio.
Mi yo del pasado era joven e ingenuo, pero productivo, y superó muchas montañas. Me tomó dos días entender el código, pero al final era bastante ingenioso; quizá si mi yo actual lo olvidó todo fue por mala memoria.
Mi yo del futuro corregirá todos los errores. Creo que será más viejo y sabio, que convertirá XXX y TBD en código inteligente, y que tendrá tiempo infinito para implementar las buenas ideas y volver a implementar las ideas más o menos. Tal vez, con mejores comentarios, los tres podamos ser uno.
No solo es una oportunidad de aprendizaje, sino que también muestra una cultura abierta y ayuda a combatir el síndrome del impostor. La actitud perfeccionista hace lo contrario: se reduce a “esfuérzate más y no cometas errores”, no deja nada que aprender y solo exige más esfuerzo individual.
Una vez asumí un pequeño error de un junior que puso una versión de software incorrecta en un informe; habría bastado con decirle al cliente “hubo un error y aquí está el informe corregido”, pero mi jefe solo pensaba: “¿podemos ocultar esto y mantener la imagen de que somos perfectos?”. Esa misma persona usaba los errores de otros como oportunidad para exigir descuentos, compensaciones o entregas gratis.
Aun así está bien. Si surge una razón para cambiarlas, las ordenaremos; hasta entonces quedan como ejemplos de malas prácticas y de mejores enfoques posibles.
Últimamente respondo: “Probablemente sea porque tu IQ es más alto que el mío. Como mi IQ es bajo, tengo que hacer cosas más tontas y simples”. A veces eso hace que la otra persona se dé cuenta de lo poco reflexiva y despectiva que fue, como un pequeño rarito, y se ponga roja.
La pregunta en sí no es mala, pero la premisa de “mi idea es facilísima” y “tú no pensaste en esta idea obvia y fácil” puede sentirse molesta o insultante. En cambio, cuando yo le pregunto a alguien, trato de evitar el “por qué simplemente” y prefiero algo como “¿puedo entender que no hiciste X por algún motivo?”, o quizá es mejor simplemente preguntar el motivo con amabilidad.
Si la pregunta surge por falta de contexto, puedo evitarla explicando, antes de describir lo que hice, por qué no funcionaron los enfoques más obvios o cuáles eran los requisitos difíciles y las entradas problemáticas. Si el código ya está commiteado, el objetivo es reducir comentarios tardíos en el commit o en el merge request. A veces también sirve no refutar, explicar directamente que probé ese método pero por qué no funcionó, y preguntar sinceramente si tienen otra idea.
Si de verdad es una sugerencia que no había considerado y parece que puede resolver el problema, digo que es una buena idea y pido ayuda para implementarla. En ese momento existe la tentación de confrontar la premisa o el tono de la otra persona, pero intento simplemente aceptarlo y sentir un poco de vergüenza por un rato.
“Si grug tiene que elegir entre pelear uno a uno contra complejidad o tiranosaurio, grug elige tiranosaurio. Al menos grug puede ver al tiranosaurio”.
La segunda pregunta normalmente puede ser un feedback válido. Las habilidades y los conocimientos de las personas no siempre se superponen. Algo absurdamente complicado para A puede no serlo para B, y viceversa; y eso no necesariamente significa que alguien sea más inteligente. A puede no saber SQL y B puede no saber pandas
Si suponemos que el stack tecnológico ya incluye tanto SQL como pandas, a veces tiene sentido mover cierto código de SQL a pandas, o al revés. A algunas personas les resulta más fácil el estilo orientado a objetos; a otras, el estilo funcional. No siempre es obvio qué tiene más sentido, así que la pregunta puede ser una buena pregunta. Si la propuesta es mala, se explica por qué es mala; si es buena, se evalúa si vale la pena hacerla ahora. Si está en un punto intermedio o no hay tiempo, se reconoce y se sigue adelante
Entonces a la otra persona le cuesta avergonzarme o hacerme sentir culpable por haber hecho algo subóptimo. Creo que a menudo el objetivo de este tipo de comentarios es establecer superioridad mediante la vergüenza. Es elegir no participar en el juego, y por lo general esa es la jugada ganadora
Por ejemplo, si hay que guardar 10 elementos, un archivo simple puede ser una opción práctica, pero si pasan a ser 10.000, quizá haga falta una base de datos. Pero si desde el inicio se hubiera usado una base de datos para 10 elementos, alguien se habría quejado de sobreingeniería
Con 2 clases, un if/else basta; con 20, quizá haga falta el patrón Factory, y si se hubiera hecho desde el principio habría parecido astronauta de arquitectura. Si intentas predecir ese crecimiento y te equivocas, terminas creando código complejo. Los proyectos que se desarrollan continuamente crecen de manera sistemática más allá de sí mismos
Enlazar comentarios maliciosos sin juzgarlos no es una mala idea. No siempre es posible si el comentario fue marcado como muerto, pero en cualquier caso no respondo del mismo modo. Podría hacerlo, pero aprendí que la gasolina no es un extintor eficaz
Si me equivoco, intento reconocerlo de inmediato en el mismo lugar donde ocurrió el error. Me disgustan especialmente las disculpas privadas después de un ataque público
Hay una línea. Siento que hago un trabajo bastante bueno, llevo unos 40 años haciéndolo y he aprendido mucho en ese tiempo. También trabajé en entornos exigentes que no aceptan trabajo de baja calidad, así que hacer un trabajo decente se volvió un hábito
En general evito juzgar públicamente a otras personas. No ayuda, y tampoco siempre tengo razón. Pero puede ser distinto si trabajo con esa persona o uso lo que hace. Me han atacado con dureza por no aceptar basura, pero no actúo como Linus Torvalds. Cuando es posible, digo de forma respetuosa que ese trabajo no es aceptable para mí
Aun así, siempre se puede mejorar y aprender cosas nuevas, y a veces uno aprende de lugares totalmente inesperados. Estar abierto a ese aprendizaje es, en el fondo, una buena política. Me vuelvo correcto equivocándome y aprendiendo. “El buen juicio viene de la experiencia, y la experiencia viene del mal juicio”
No sé si sirve para reducir esos comentarios, pero sí tiene el sentido de ponerle un gorro de tonto metafórico a la persona que participa en el discurso de esa manera
Este artículo es interesante para leerlo junto con “No more pink mustache”. En ese texto se describe a Lyft como “rota a una escala increíble”, y la causa de la calidad suele ser la organización, no la persona sentada en la silla :-)
[1] https://rachelbythebay.com/w/2020/02/29/poof/
Hay tres opciones. Rendirse, ceder ese territorio y seguir con la vida; cuanto menos sueño pierdas por la injusticia, mejor. Enfrentarlos de frente; ellos están preparados para pelear, pero como su postura es inherentemente irracional, cuanto menos te arrastren a su espacio mental, más “ganas”. O venir desde arriba: llevar a su espacio prueba social de que están equivocados. En el caso del artículo original, serían programadores productivos que respetan el trabajo de los demás y no se dedican a buscarle cinco pies al gato
La persona que da el consejo podría ser un idiota torpe en sus relaciones interpersonales, o simplemente un completo idiota. Está bien que una parte del mundo no esté de acuerdo conmigo. Que la gente exprese opiniones contrarias o no esté de acuerdo no significa que me esté amenazando.
Estas personas piensan que su forma preferida de dar feedback es la mejor y que todos deberían sentir lo mismo; si no, consideran que la otra persona debe cambiar. Por supuesto, están equivocadas. Pero si les dices esto, ellas mismas demuestran por qué dije “la mayoría” en la primera oración.