La programación alfabetizada es un paradigma de programación introducido en 1984 por Donald Knuth en el que se da un programa de computadora como explicación de cómo funciona en un lenguaje natural , como el inglés, intercalado (incrustado) con fragmentos de macros y código fuente tradicional , a partir del cual Se puede generar código fuente compilable . [1] El enfoque se utiliza en informática científica y en ciencia de datos de forma rutinaria con fines de investigación reproducible y acceso abierto . [2] Millones de programadores utilizan hoy en día herramientas de programación alfabetizadas. [3]
El paradigma de la programación alfabetizada, tal como lo concibió Donald Knuth, representa un alejamiento de escribir programas de computadora en la forma y el orden impuestos por el compilador y, en cambio, brinda a los programadores macros para desarrollar programas en el orden exigido por la lógica y el flujo de sus pensamientos. [4] Los programas alfabetizados se escriben como una exposición de lógica en un lenguaje más natural en el que se utilizan macros para ocultar abstracciones y código fuente tradicional , más parecido al texto de un ensayo .
Las herramientas de programación alfabetizada (LP) se utilizan para obtener dos representaciones de un archivo fuente: una comprensible para un compilador o intérprete, el código "enredado", y otra para ver como documentación formateada , que se dice "tejida" a partir de los alfabetizados. fuente. [5] Si bien la primera generación de herramientas de programación alfabetizadas eran específicas del lenguaje informático , las últimas son independientes del lenguaje y existen más allá de los lenguajes de programación individuales.
La programación alfabetizada fue introducida por primera vez en 1984 por Donald Knuth, cuyo objetivo era crear programas que fueran literatura adecuada para los seres humanos. Lo implementó en la Universidad de Stanford como parte de su investigación sobre algoritmos y tipografía digital . La implementación se denominó " WEB " ya que creía que era una de las pocas palabras de tres letras del inglés que aún no se había aplicado a la informática. [6] Sin embargo, se asemeja a la naturaleza complicada del software delicadamente ensamblado a partir de materiales simples. [1] La práctica de la programación alfabetizada ha experimentado un resurgimiento importante en la década de 2010 con el uso de cuadernos computacionales , especialmente en ciencia de datos .
La programación alfabetizada consiste en escribir la lógica del programa en un lenguaje humano con macros y fragmentos de código incluidos (separados por un marcado primitivo). Las macros en un archivo fuente alfabetizado son simplemente frases tipo título o explicativas en un lenguaje humano que describen abstracciones humanas creadas mientras se resuelve el problema de programación y ocultan fragmentos de código o macros de nivel inferior. Estas macros son similares a los algoritmos en pseudocódigo que se utilizan normalmente en la enseñanza de informática . Estas frases explicativas arbitrarias se convierten en nuevos operadores precisos, creados sobre la marcha por el programador, formando un metalenguaje sobre el lenguaje de programación subyacente.
Se utiliza un preprocesador para sustituir jerarquías arbitrarias, o más bien "redes" interconectadas de macros", [7] para producir el código fuente compilable con un comando ("tangle") y la documentación con otro ("weave"). El preprocesador también proporciona la capacidad de escribir el contenido de las macros y agregarle macros ya creadas en cualquier lugar del texto del archivo fuente del programa alfabetizado, eliminando así la necesidad de tener en cuenta las restricciones impuestas por los lenguajes de programación tradicionales. o interrumpir el flujo del pensamiento.
Según Knuth, [8] [9] la programación alfabetizada proporciona programas de mayor calidad, ya que obliga a los programadores a expresar explícitamente los pensamientos detrás del programa, haciendo más obvias las decisiones de diseño mal pensadas. Knuth también afirma que la programación alfabetizada proporciona un sistema de documentación de primer nivel, que no es un complemento, sino que se desarrolla de forma natural en el proceso de exposición de los pensamientos durante la creación de un programa. [10] La documentación resultante permite al autor reiniciar sus propios procesos de pensamiento en cualquier momento posterior y permite a otros programadores comprender la construcción del programa más fácilmente. Esto difiere de la documentación tradicional, en la que al programador se le presenta el código fuente que sigue un orden impuesto por el compilador y debe descifrar el proceso de pensamiento detrás del programa a partir del código y sus comentarios asociados. También se afirma que las capacidades de metalenguaje de la programación alfabetizada facilitan el pensamiento, brindando una mayor "visión panorámica" del código y aumentando la cantidad de conceptos que la mente puede retener y procesar con éxito. La aplicabilidad del concepto a la programación a gran escala, la de programas de nivel comercial, queda demostrada por una edición del código TeX como programa alfabetizado. [8]
Knuth también afirma que una programación alfabetizada puede facilitar la migración del software a múltiples entornos, e incluso cita la implementación de TeX como ejemplo. [11]
Muy a menudo se malinterpreta la programación alfabetizada [12] refiriéndose únicamente a documentación formateada producida a partir de un archivo común con código fuente y comentarios (lo que propiamente se llama generación de documentación ) o a comentarios voluminosos incluidos con el código. Esto es lo contrario de la programación alfabetizada: el código bien documentado o la documentación extraída del código sigue la estructura del código, con la documentación incorporada en el código; mientras que en la programación alfabetizada, el código está integrado en la documentación, y el código sigue la estructura de la documentación.
Esta idea errónea ha llevado a afirmar que las herramientas de extracción de comentarios, como los sistemas Perl Plain Old Documentation o Java Javadoc , son "herramientas de programación alfabetizadas". Sin embargo, debido a que estas herramientas no implementan la "red de conceptos abstractos" que se esconde detrás del sistema de macros de lenguaje natural, ni brindan la capacidad de cambiar el orden del código fuente de una secuencia impuesta por una máquina a una conveniente para la mente humana. , no pueden denominarse propiamente herramientas de programación alfabetizadas en el sentido que pretende Knuth. [12] [13]
La implementación de una programación alfabetizada consta de dos pasos:
El tejido y el enredo se realizan sobre la misma fuente para que sean consistentes entre sí.
Un ejemplo clásico de programación alfabetizada es la implementación alfabetizada del programa estándar de conteo de palabras de Unix wc
. Knuth presentó una versión CWEB de este ejemplo en el capítulo 12 de su libro Literate Programming . El mismo ejemplo fue reescrito posteriormente para la herramienta de programación no alfabetizada. [14] Este ejemplo proporciona una buena ilustración de los elementos básicos de la programación alfabetizada.
El siguiente fragmento del wc
programa alfabetizado [14] muestra cómo se utilizan frases descriptivas arbitrarias en un lenguaje natural en un programa alfabetizado para crear macros, que actúan como nuevos "operadores" en el lenguaje de programación alfabetizado y ocultan fragmentos de código u otras macros. . La notación de marcado consta de corchetes angulares dobles ( <<...>>
) que indican macros. El @
símbolo que, en un archivo no web, indica el comienzo de un fragmento de documentación. El <<*>>
símbolo representa la "raíz", el nodo superior desde el cual la herramienta de programación alfabetizada comenzará a expandir la red de macros. En realidad, escribir el código fuente ampliado se puede hacer desde cualquier sección o subsección (es decir, un fragmento de código designado como <<name of the chunk>>=
, con el signo igual), por lo que un archivo de programa alfabetizado puede contener varios archivos con código fuente de máquina.
El propósito de wc es contar líneas , palabras y / o caracteres en una lista de archivos . El número de líneas de un archivo es ........ / más explicaciones / A continuación presentamos una descripción general del archivo wc . c que está definido por el programa noweb wc . nw : <<*>>= << Archivos de encabezado a incluir >> << Definiciones >> << Variables globales >> << Funciones >> << El programa principal >> @ Debemos incluir las definiciones de E / S estándar , ya que queremos enviar salida formateada a stdout y stderr . << Archivos de encabezado a incluir >>= #include <stdio.h> @
El desentrañamiento de los fragmentos se puede realizar en cualquier lugar del archivo de texto del programa alfabetizado, no necesariamente en el orden en que están secuenciados en el fragmento adjunto, sino según lo exige la lógica reflejada en el texto explicativo que envuelve todo el programa.
Las macros no son lo mismo que los "nombres de sección" en la documentación estándar. Las macros de programación alfabetizadas ocultan el código real detrás de sí mismas y se pueden usar dentro de cualquier operador de lenguaje de máquina de bajo nivel, a menudo dentro de operadores lógicos como if
, while
o case
. Esto se puede ver en el siguiente wc
programa de alfabetización. [14]
El fragmento actual , que hace el recuento , fue en realidad uno de los más sencillos de escribir . Observamos cada carácter y cambiamos de estado en < nowiki / > si comienza o termina una palabra . << Escanear archivo >>= while ( 1 ) { << Llene el búfer si está vacío ; romper al final del archivo >> c = * ptr ++ ; if ( c > '' && c < 0177 ) { /* códigos ASCII visibles */ if ( ! in_word ) { word_count ++ ; en_palabra = 1 ; } continuar ; } if ( c == '\n' ) line_count ++ ; de lo contrario, si ( c ! = ' ' && c ! = '\t' ) continúa ; en_palabra = 0 ; /* c es nueva línea, espacio o tabulación */ } @
Las macros representan cualquier fragmento de código u otras macros, y son más generales que las "fragmentaciones" de arriba hacia abajo o de abajo hacia arriba, o que las subsecciones. Donald Knuth dijo que cuando se dio cuenta de esto, empezó a pensar en un programa como una red de varias partes. [1]
En un programa no alfabetizado, además del orden libre de su exposición, los fragmentos detrás de las macros, una vez introducidos con <<...>>=
, pueden crecer más adelante en cualquier lugar del archivo simplemente escribiendo <<name of the chunk>>=
y agregando más contenido, como lo ilustra el siguiente fragmento ( +
se agrega por el formateador del documento para facilitar la lectura y no está en el código). [14]
Los totales generales deben inicializarse a cero al comienzo del programa.Si hiciéramos que estas variables fueran locales a main, tendríamos que hacer esta inicializaciónexplícitamente; sin embargo, los globales de C se ponen a cero automáticamente. (O mejor dicho, "estáticamentepuesto a cero.'' (¿Entiendes?) <<Variables globales>>+=long tot_word_count, tot_line_count,
tot_char_count;/* total number of words, lines, chars */
@
La documentación para un programa de alfabetización se produce como parte de la redacción del programa. En lugar de comentarios proporcionados como notas laterales al código fuente, un programa alfabetizado contiene la explicación de los conceptos en cada nivel, con los conceptos de niveles inferiores remitidos a su lugar apropiado, lo que permite una mejor comunicación del pensamiento. Los fragmentos de los alfabetizados wc
anteriores muestran cómo se entrelazan una explicación del programa y su código fuente. Esta exposición de ideas crea el flujo de pensamiento que es como una obra literaria. Knuth escribió una "novela" que explica el código del juego de ficción interactivo Colossal Cave Adventure . [15]
El primer entorno de programación alfabetizado publicado fue WEB , introducido por Knuth en 1981 para su sistema de composición tipográfica TeX ; Utiliza Pascal como lenguaje de programación subyacente y TeX para la composición tipográfica de la documentación. El código fuente completo de TeX comentado se publicó en TeX de Knuth: The program , volumen B de sus 5 volúmenes Computers and Typesetting . Knuth ya en 1979 utilizaba de forma privada un sistema de programación competente llamado DOC. Se inspiró en las ideas de Pierre-Arnoul de Marneffe . [16] El CWEB gratuito , escrito por Knuth y Silvio Levy, está adaptado para C y C++ , se ejecuta en la mayoría de los sistemas operativos y puede producir documentación TeX y PDF .
Hay varias otras implementaciones del concepto de programación alfabetizada como se detalla a continuación. Muchos de los más nuevos no tienen macros y, por lo tanto, no cumplen con el principio de orden de la lógica humana, lo que los convierte quizás en herramientas "semialfabetizadas". Estos, sin embargo, permiten la ejecución celular de código, lo que los hace más parecidos a las herramientas de programación exploratoria .
Otras herramientas útiles incluyen:
.hs
y .lhs
; este último significa Haskell alfabetizado. Los scripts alfabetizados pueden ser texto fuente completo de LaTeX, al mismo tiempo se pueden compilar sin cambios, porque el intérprete solo compila el texto en un entorno de código, por ejemplo:
% aquí texto que describe la función: \begin { code } fact 0 = 1 fact ( n + 1 ) = ( n + 1 ) * fact n \end { code } aquí más texto
El código también se puede marcar en el estilo de Richard Bird, comenzando cada línea con un símbolo mayor que y un espacio, precediendo y terminando el fragmento de código con líneas en blanco.
El listings
paquete LaTeX proporciona un lstlisting
entorno que se puede utilizar para embellecer el código fuente. Se puede utilizar para definir un code
entorno a utilizar dentro de Haskell para imprimir los símbolos de la siguiente manera:
\newenvironment { código }{ \lstlistings [idioma=Haskell] }{ \endlstlistings }\begin { código } comp :: ( beta -> gamma ) -> ( alfa -> beta ) -> ( alfa -> gamma ) ( g ` comp ` f ) x = g ( f x ) \end { code }
que se puede configurar para producir:
Tenía la sensación de que de arriba hacia abajo y de abajo hacia arriba eran metodologías opuestas: una más adecuada para la exposición de programas y la otra más adecuada para la creación de programas. Pero después de adquirir experiencia con WEB, me he dado cuenta de que no hay necesidad de elegir de una vez por todas entre de arriba hacia abajo y de abajo hacia arriba, porque es mejor pensar en un programa como una red en lugar de un árbol. Existe una estructura jerárquica, pero lo más importante de un programa son sus relaciones estructurales. Una pieza compleja de software consta de partes simples y relaciones simples entre esas partes; La tarea del programador es establecer esas partes y esas relaciones, en el orden que sea mejor para la comprensión humana, no en un orden rígidamente determinado como de arriba hacia abajo o de abajo hacia arriba.
— Donald E. Knuth , Programación alfabetizada [1]
Las macros de WEB pueden tener como máximo un parámetro. Nuevamente, hice esto en aras de la simplicidad, porque noté que la mayoría de las aplicaciones de parámetros múltiples podrían, de hecho, reducirse al caso de un solo parámetro. Por ejemplo, supongamos que desea definir algo como [ejemplo elidido].... En otras palabras, el nombre de una macro puede ser útil un parámetro para otra macro.
— Donald E. Knuth , Programación alfabetizada [1]
Sin embargo, para mí, la programación alfabetizada es sin duda lo más importante que surgió del proyecto
TeX
. No sólo me ha permitido escribir y mantener programas de manera más rápida y confiable que nunca, y ha sido una de mis mayores fuentes de alegría desde la década de 1980, sino que en ocasiones ha sido indispensable. Algunos de mis programas principales, como el metasimulador MMIX, no podrían haberse escrito con ninguna otra metodología de la que haya oído hablar. La complejidad era simplemente demasiado abrumadora para que mi limitado cerebro pudiera manejarla; sin una programación alfabetizada, toda la empresa habría fracasado estrepitosamente. ... La programación alfabetizada es lo que se necesita para superar el nivel ordinario de logros.
Otra cosa sorprendente que aprendí mientras usaba WEB fue que los lenguajes de programación tradicionales me habían llevado a escribir programas inferiores, aunque no me había dado cuenta de lo que estaba haciendo. Mi idea original era que WEB sería simplemente una herramienta de documentación, pero en realidad descubrí que mis programas WEB eran mejores que los programas que había estado escribiendo en otros lenguajes.
— Donald E. Knuth , Programación alfabetizada [1]
Así, el lenguaje WEB permite a una persona expresar programas en un orden de "flujo de conciencia" . TANGLE es capaz de codificar todo en la disposición que exige un compilador PASCAL. Esta característica de WEB es quizás su mayor ventaja; hace que un programa escrito en WEB sea mucho más legible que el mismo programa escrito exclusivamente en PASCAL, incluso si este último programa está bien comentado. Y el hecho de que no hay necesidad de obsesionarse con la cuestión de arriba hacia abajo versus abajo hacia arriba, ya que un programador ahora puede ver un programa grande como una red, para ser explorado en un orden psicológicamente correcto, es quizás la lección más importante que he aprendido. He aprendido de mis experiencias recientes.
— Donald E. Knuth , Programación alfabetizada [1]
Elegí el nombre WEB en parte porque era una de las pocas palabras en inglés de tres letras que aún no se había aplicado a las computadoras. Pero a medida que pasó el tiempo, me sentí extremadamente satisfecho con el nombre, porque creo que una pieza compleja de software se considera mejor como una red que ha sido delicadamente construida a partir de materiales simples. Entendemos un sistema complicado entendiendo sus partes simples y entendiendo las relaciones simples entre esas partes y sus vecinas inmediatas. Si expresamos un programa como una red de ideas, podemos enfatizar sus propiedades estructurales de una manera natural y satisfactoria.
— Donald E. Knuth , Programación alfabetizada [1]