PROGRAMANDO DE ABAJO-HACIA ARRIBA
1993
(Este ensayo es la introducción a On Lisp. El texto en rojo explica el origen del nombre de Arc.)
Es un principio de programación largamente establecido que los elementos funcionales de un programa no deben ser demasiado grandes. Si algún componente de un programa crece más allá de la etapa en que es fácilmente comprensible, se convierte en una masa de complejidad que oculta los errores tan fácilmente como una gran ciudad oculta fugitivos. Este tipo de software será difícil de leer, difícil de probar y difícil de depurar.
De acuerdo con este principio, un programa grande debe ser dividido en partes, y cuanto más grande sea el programa, más debe dividirse. ¿Cómo se debe dividir un programa? El enfoque tradicional se llama diseño de arriba-hacia abajo: tú dices "el propósito del programa es hacer estas siete cosas, así que lo divido en siete subrutinas principales. La primera subrutina tiene que hacer estas cuatro cosas, por lo que a su vez va a tener cuatro subrutinas propias", y así sucesivamente. Este proceso continúa hasta que todo el programa tiene el nivel adecuado de granularidad —cada parte suficientemente grande como para hacer algo importante, pero lo suficientemente pequeña como para ser entendida como una sola unidad—.
Los programadores Lisp experimentados dividen sus programas de manera diferente. De la misma manera que en el diseño de arriba-hacia abajo, ellos siguen un principio que podría llamarse el diseño de abajo-hacia arriba, cambiando el lenguaje para adaptarse al problema. En Lisp no solo escribes tu programa hacia el lenguaje, también construyes el lenguaje hacia tu programa. Mientras escribes un programa puedes pensar: "Deseo que Lisp tenga tal y tal operador". Así que lo escribes. Luego te das cuenta de que usar el nuevo operador simplificaría el diseño de otra parte del programa, y así sucesivamente. El programa y el lenguaje evolucionan juntos. Al igual que la frontera entre dos estados en guerra, la frontera entre el lenguaje y el programa se dibuja y vuelve a dibujar, hasta que finalmente queda en reposo a lo largo de las montañas y los ríos; las fronteras naturales de tu problema. Al final tu programa lucirá como si el lenguaje ha sido diseñado para él. Y cuando programa y lenguaje se complementan, terminas con código que es claro, conciso y eficiente.
Es importante destacar que el diseño de abajo-hacia arriba no significa sólo escribir el mismo programa en un orden diferente. Cuando se trabaja de abajo-hacia arriba, por lo general se termina con un programa diferente. En lugar de un programa único, monolítico, obtendrás un lenguaje más grande, con más operadores abstractos y un programa más pequeño escrito en él. En lugar de un dintel, obtendrás un arco.
En el código típico, una vez que se extraen las partes que solo sirven para sumar, lo que queda es mucho más corto; mientras más alto construyas el lenguaje, menor la distancia que tendrás que recorrer de arriba hacia abajo del mismo. Esto trae varias ventajas:
- Al hacer que el lenguaje haga más del trabajo, el diseño de abajo-hacia arriba produce programas que son más pequeños y ágiles. Un programa más corto no tiene que ser dividido en tantos componentes, y menos componentes significa programas que son más fáciles de leer o modificar. Menos componentes también significa menos conexiones entre los componentes y, por lo tanto, menos probabilidad de errores ahí. De la misma manera en que los diseñadores industriales se esfuerzan por reducir el número de partes móviles en una máquina, los programadores Lisp experimentados utilizan el diseño de abajo-hacia arriba para reducir el tamaño y la complejidad de sus programas.
- El diseño de abajo-hacia arriba promueve la reutilización de código. Cuando escribes dos o más programas, muchas de las utilidades que escribiste para el primer programa también serán útiles en los siguientes. Una vez que hayas adquirido un sustrato importante de utilidades, la escritura de un nuevo programa puede tomar sólo una fracción del esfuerzo que se requeriría si tuvieras que empezar con Lisp puro.
- El diseño de abajo-hacia arriba hace los programas más fáciles de leer. Una instancia de este tipo de abstracción le pide al lector comprender un operador de uso general, una instancia de abstracción funcional le pide al lector comprender una subrutina especifica. [1]
- Debido a que te hace estar siempre a la búsqueda de patrones en el código, trabajar de abajo-hacia arriba ayuda a clarificar tus ideas sobre el diseño del programa. Si dos componentes distantes de un programa son similares en la forma, serás llevado a notar la similitud y tal vez a rediseñar el programa de una manera más simple.
El diseño de abajo-hacia arriba es posible hasta cierto punto en lenguajes distintos a Lisp. Cuando ves funciones de biblioteca, el diseño de abajo-hacia arriba está presente. Sin embargo, Lisp te da poderes mucho más amplios en esta area y aumentar el lenguaje desempeña un papel proporcionalmente más grande en el estilo Lisp— tanto es así que Lisp no es sólo un lenguaje diferente, sino una manera completamente diferente de programación.
Es cierto que este estilo de desarrollo se adapta mejor a programas que pueden ser escritos por grupos pequeños. Sin embargo, al mismo tiempo, amplía los límites de lo que puede ser realizado por un grupo pequeño. En The Mythical Man-Month [a], Frederick Brooks propuso que la productividad de un grupo de programadores no crece linealmente con su tamaño. A medida que el tamaño del grupo aumenta, la productividad de los programadores individuales baja. La experiencia de la programación Lisp sugiere una forma más alegre para formular esta ley: a medida que el tamaño del grupo disminuye, la productividad de los programadores individuales aumenta. Un grupo pequeño gana, relativamente hablando, simplemente porque es más pequeño. Cuando un grupo pequeño también se aprovecha de las técnicas que Lisp permite, este, simple y sencillamente gana.
Nuevo: Descarga Gratis On Lisp. [En Inglés, N. del T.]
[1] "Pero nadie puede leer el programa sin entender todas sus nuevas utilidades." Para ver por qué esas declaraciones están por lo general equivocadas, véase la sección 4.8.
*Traducido del original Programming Bottom-Up por Paul Graham. Traducción: Armando Alvarez con la asesoria técnica de Hanedi Salas.
Notas del Traductor
[a] El Mítico Hombre-Mes: Ensayos de ingeniería de Software (en inglés The Mythical Man-Month: Essays on Software Engineering) es un libro de administración de proyectos de software de Fred Brooks, cuyo tema central establece que "agregar recursos humanos a un proyecto retrasado lo hace demorarse aún más". Esta idea es conocida como la "Ley de Brooks".
Las observaciones de Brooks están basadas en sus experiencias en IBM mientras administraba el desarrollo de OS/360. Para acelerar el desarrollo, se trató infructuosamente de agregar más trabajadores al proyecto que ya estaba retrasado. También apostó que escribir un compilador en ALGOL requería "6 meses de mano de obra" adicional. La tendencia de los administradores de proyectos a repetir estos errores llevaron a Brooks a la conclusión de que su libro era "la biblia de la ingeniería de software" porque "todos la leen, pero nadie la practica". [Fuente: Wikipedia. Ver]