La programación alfabetizada es un paradigma de programación introducido en 1984 por Donald Knuth en el que se presenta un programa informático como una 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 la informática científica y en la ciencia de datos de forma rutinaria para fines de investigación reproducible y acceso abierto . [2] Millones de programadores utilizan herramientas de programación alfabetizada en la actualidad. [3]
El paradigma de programación alfabetizada, tal como lo concibió Donald Knuth, representa un alejamiento de la escritura de programas de computadora en la forma y el orden impuestos por el compilador, y en su lugar proporciona a los programadores macros para desarrollar programas en el orden demandado por la lógica y el flujo de sus pensamientos. [4] Los programas alfabetizados se escriben como una exposición de la 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 que está "tejida" a partir de la fuente alfabetizada. [5] Si bien la primera generación de herramientas de programación alfabetizada era específica del lenguaje de computadora , las posteriores 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, quien pretendía crear programas que fueran literatura adecuada para los seres humanos. La implementó en la Universidad de Stanford como parte de su investigación sobre algoritmos y tipografía digital . La implementación se llamó " 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 la ciencia de datos .
La programación literaria consiste en escribir la lógica del programa en un lenguaje humano con fragmentos de código y macros incluidos (separados por un marcado primitivo). Las macros en un archivo fuente literario son simplemente frases explicativas o similares a títulos en un lenguaje humano que describen abstracciones humanas creadas al resolver 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 la 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.
Un preprocesador se utiliza 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 de agregar 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 de interrumpir el flujo de 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 las ideas detrás del programa, haciendo que las decisiones de diseño mal pensadas sean más obvias. Knuth también afirma que la programación alfabetizada proporciona un sistema de documentación de primera clase, que no es un complemento, sino que crece naturalmente en el proceso de exposición de las propias ideas 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 que otros programadores comprendan la construcción del programa más fácilmente. Esto difiere de la documentación tradicional, en la que se presenta al programador un 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, proporcionando una "vista de pájaro" superior del código y aumentando el número de conceptos que la mente puede retener y procesar con éxito. La aplicabilidad del concepto a la programación a gran escala, la de los programas de nivel comercial, queda demostrada mediante una edición del código TeX como programa alfabetizado. [8]
Knuth también afirma que la programación alfabetizada puede conducir a una fácil portabilidad del software a múltiples entornos, e incluso cita la implementación de TeX como ejemplo. [11]
Muy a menudo se confunde la programación literaria [12] con la idea de que se refiere únicamente a la documentación formateada producida a partir de un archivo común con código fuente y comentarios (lo que se denomina propiamente generación de documentación ) o a voluminosos comentarios incluidos con el código. Esto es lo opuesto a la programación literaria: el código bien documentado o la documentación extraída del código sigue la estructura del código, con la documentación incrustada en el código; mientras que en la programación literaria, el código está incrustado 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 la documentación simple de Perl o los sistemas Javadoc de Java , son "herramientas de programación alfabetizada". 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 proporcionan la capacidad de cambiar el orden del código fuente de una secuencia impuesta por la máquina a una conveniente para la mente humana, no pueden ser llamadas apropiadamente herramientas de programación alfabetizada en el sentido que Knuth pretendía. [12] [13]
La implementación de una programación alfabetizada consta de dos pasos:
El tejido y el enredo se realizan en 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 alfabetizada noweb . [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 otros macros. La notación de marcado consta de corchetes angulares dobles ( <<...>>
) que indican macros. El @
símbolo que, en un archivo noweb, indica el comienzo de un fragmento de documentación. El <<*>>
símbolo representa la "raíz", el nodo superior desde el que la herramienta de programación alfabetizada comenzará a expandir la red de macros. En realidad, la escritura del código fuente expandido se puede realizar 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 . La cantidad de líneas en un archivo es ........ / más explicaciones / A continuación , se presenta 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ñar 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 que los contiene, sino como 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 literaria 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 literario. [14]
El fragmento actual , que realiza el recuento , fue en realidad uno de los más sencillos de escribir . Observamos cada carácter y cambiamos de estado si comienza o termina una palabra . << Escanear archivo >>= while ( 1 ) { << Rellenar el buffer si está vacío ; romper al final del archivo >> c = * ptr ++ ; if ( c > ' ' && c < 0177 ) { /* códigos ASCII visibles * / if ( ! in_word ) { word_count ++ ; in_word = 1 ; } continue ; } if ( c == '\n' ) line_count ++ ; else if ( c != ' ' && c != '\t' ) continue ; in_word = 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 la fragmentación de arriba hacia abajo o de abajo hacia arriba, o que la subdivisión. Donald Knuth dijo que cuando se dio cuenta de esto, comenzó a pensar en un programa como una red de varias partes. [1]
En un programa no alfabetizado en la web, además del orden libre de su exposición, los fragmentos detrás de las macros, una vez introducidos con <<...>>=
, se pueden hacer crecer más tarde en cualquier lugar del archivo simplemente escribiéndolos <<name of the chunk>>=
y agregándoles más contenido, como lo ilustra el siguiente fragmento ( +
lo agrega 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 la principal, tendríamos que hacer esta inicializaciónexplícitamente; sin embargo, las variables globales de C se ponen a cero automáticamente. (O más bien, ``estáticamentepuesto a cero.'' (¿Lo entiendes?) <<Variables globales>>+=long tot_word_count, tot_line_count,
recuento_de_caracteres totales;/* total number of words, lines, chars */
@
La documentación de un programa literario se produce como parte de la escritura del programa. En lugar de comentarios proporcionados como notas al margen del código fuente, un programa literario contiene la explicación de los conceptos en cada nivel, con los conceptos de nivel inferior postergados a su lugar apropiado, lo que permite una mejor comunicación del pensamiento. Los fragmentos del programa literario wc
anteriores muestran cómo se entrelazan una explicación del programa y su código fuente. Tal 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 alfabetizada 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: The program de Knuth , volumen B de su libro de 5 volúmenes Computers and Typesetting . Knuth había utilizado de forma privada un sistema de programación alfabetizada llamado DOC ya en 1979. Se inspiró en las ideas de Pierre-Arnoul de Marneffe . [16] El CWEB gratuito , escrito por Knuth y Silvio Levy, está adaptado para WEB para C y C++ , se ejecuta en la mayoría de los sistemas operativos y puede producir documentación TeX y PDF .
Existen otras implementaciones del concepto de programación alfabetizada, como se muestra a continuación. Muchas de las más nuevas no tienen macros y, por lo tanto, no cumplen con el principio de orden lógico humano, lo que las convierte en herramientas "semi-alfabetizadas". Sin embargo, estas permiten la ejecución celular de código, lo que las convierte más en herramientas de programación exploratoria .
Nombre | Idiomas soportados | Escrito en | Lenguaje de marcado | Macros y orden personalizado | Ejecución celular | Comentarios |
---|---|---|---|---|---|---|
WEB | Pascal | Pascal | Texas | Sí | No | El primer entorno de programación alfabetizada publicado. |
CWEB | C++ y C | do | Texas | Sí | No | ¿ WEB está adaptado para C y C++ ? |
AhoraWEB | Cualquier | C , AWK y Icono | LaTeX , TeX , HTML y troff | Sí | No | Es bien conocido por su simplicidad y permite formatear texto en HTML en lugar de pasar por el sistema TeX. |
Alfabetizado | Cualquier | D | Reducción | Sí | No | Admite ecuaciones TeX. Compatible con Vim (literate.vim). |
FunnelWeb | Cualquier | do | HTML y TeX | ¿Sí? | Tiene un marcado más complicado, pero tiene muchas más opciones flexibles. | |
NuWEB | Cualquier | C++ | Látex | Puede traducir una única fuente LP en cualquier cantidad de archivos de código. Lo hace en una única invocación; no tiene comandos weave y tangle independientes. No tiene la extensibilidad de noweb . | ||
pyWeb | Cualquier | Pitón | Texto reestructurado | Sí | Respeta la sangría, lo que lo hace utilizable para lenguajes como Python , aunque se puede utilizar para cualquier lenguaje de programación. | |
muchacha | Cualquier | Perl | HTML | Su objetivo es modernizarlo y escalarlo con "HTML plegable" y "vistas virtuales" del código. Utiliza el marcado "noweb" para los archivos fuente legibles. | ||
Codnar | Rubí | Es una herramienta de programación alfabetizada inversa disponible como Ruby Gem. En lugar de extraer el código fuente legible por máquina de las fuentes de documentación alfabetizada, la documentación alfabetizada se extrae de los archivos de código fuente legibles por máquina normales. | ||||
Modo org de Emacs | Cualquier | Emacs Lisp | Texto simple | Requiere Babel, [17] que permite incrustar bloques de código fuente de múltiples lenguajes de programación [18] dentro de un único documento de texto. Los bloques de código pueden compartir datos entre sí, mostrar imágenes en línea o analizarse para obtener código fuente puro utilizando la sintaxis de referencia noweb . [19] | ||
Script de café | Script de café | CoffeeScript , JavaScript | Reducción | CoffeeScript admite un modo "literario", que permite compilar programas a partir de un documento fuente escrito en Markdown con bloques de código sangrados. [20] | ||
Hojas de trabajo de arce | Arce (software) | XML | Las hojas de trabajo de Maple son un entorno de programación alfabetizado independiente de la plataforma que combina texto y gráficos con código en vivo para el cálculo simbólico. "Hojas de trabajo de Maple". MapleSoft.com . Consultado el 30 de mayo de 2020 . | |||
Cuadernos de Wolfram | Lenguaje Wolfram | Lenguaje Wolfram | Los cuadernos Wolfram son un método de programación alfabetizada independiente de la plataforma que combina texto y gráficos con código en vivo. [21] [22] | |||
Parques infantiles | Swift (lenguaje de programación) | Proporciona un entorno de programación interactivo que evalúa cada enunciado y muestra resultados en vivo a medida que se edita el código. Playgrounds también permite al usuario agregar lenguaje de marcado junto con el código que proporciona encabezados, formato en línea e imágenes. [23] | ||||
Jupyter Notebook , anteriormente IPython Notebook | Python y cualquiera con un kernel Jupyter | Especificación del formato JSON para ipynb | No | Sí | Trabaja en formato de cuadernos, que combinan encabezados, texto (incluido LaTeX), gráficos, etc. con el código escrito. | |
Complemento Jupytext para Jupyter | Muchos idiomas | Pitón | Markdown en comentarios | No | Sí | |
nbdev | Cuaderno Python y Jupyter | nbdev es una biblioteca que permite desarrollar una biblioteca de Python en Jupyter Notebooks, poniendo todo el código, pruebas y documentación en un solo lugar. | ||||
Julia (lenguaje de programación) | Pluto.jl es un entorno de cuaderno reactivo que permite realizar pedidos personalizados, pero no admite macros de tipo web. | Sí | Admite el modo de desarrollo iJulia que se inspiró en iPython. | |||
Agda (lenguaje de programación) | Admite una forma limitada de programación alfabetizada de forma inmediata. [24] | |||||
Lenguaje de programación Eve | Los programas son principalmente en prosa. [25] Eve combina variantes de Datalog y Markdown con un entorno de desarrollo gráfico en vivo. | |||||
Cuadernos R Markdown (o cuadernos R) | R , Python , Julia y SQL | PDF , Microsoft Word , LibreOffice y formatos de presentación o presentación de diapositivas, además de formatos interactivos como widgets HTML | No | Sí | [26] | |
Libro en cuarto | R , Python , Julia y Observable | PDF , Microsoft Word , LibreOffice y formatos de presentación o presentación de diapositivas, además de formatos interactivos como widgets HTML | No | Sí | [26] | |
Ondular | R | [27] [28] | ||||
Tejedor | R | LaTeX , PDF , LyX , HTML , Markdown , AsciiDoc y reStructuredText | [29] [30] | |||
Codigo trenzado | Pandoc , Rust , Julia , Python , R , Bash | Pitón | Reducción | No | Sí | |
Pweave | Pitón | No | ||||
Editor en vivo de MATLAB | MATLAB | Reducción | No | Sí | ||
En la web | C , C++ , Informe 6 , Informe 7 | C , CWEB | TeX , HTML | ¿Sí? | Se utiliza para escribir el lenguaje de programación Inform desde 2004. [31] | |
Mercurio | Pitón | Python , TypeScript | Especificación del formato JSON para ipynb | Mercury convierte Jupyter Notebook en documentos computacionales interactivos. Se pueden publicar como aplicaciones web , paneles, informes, API REST o diapositivas. El documento ejecutado se puede exportar como archivo HTML o PDF independiente . Los documentos se pueden programar para su ejecución automática. La presencia del documento y los widgets se controlan con el encabezado YAML en la primera celda del notebook. | ||
Observable | JavaScript | JavaScript , Tipografía | TeX ( KaTeX ), HTML | Almacenado en la nube con interfaz web. Los contenidos se pueden publicar como sitios web. Control de versiones; la plataforma define sus propias operaciones de control de versiones. Las celdas de código se pueden organizar desordenadas ; los cuadernos observables construirán el gráfico de ejecución (un DAG ) automáticamente. Una rica biblioteca estándar implementada con características modernas de JavaScript . Las celdas de diferentes cuadernos observables pueden hacer referencia entre sí. Las bibliotecas Npm se pueden importar sobre la marcha. | ||
Ganesha | JavaScript , Tipografía | JavaScript | Reducción | Permite que Node.js cargue módulos alfabetizados, representados por archivos Markdown que contienen código JavaScript o TypeScript intercalado con prosa con formato enriquecido. Admite la agrupación de módulos alfabetizados para navegadores cuando se utilizan los agrupadores de módulos de interfaz Rollup o Vite. | ||
JWEB | C , C++ , JavaScript , TypeScript | JavaScript | Reducción | Sí | No |
Otras herramientas útiles incluyen:
.hs
y .lhs
; la última significa Haskell alfabetizado. Los scripts alfabetizados pueden ser texto fuente LaTeX completo y, al mismo tiempo, pueden compilarse 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 al estilo de Richard Bird, iniciando cada línea con un símbolo mayor que y un espacio, precediendo y finalizando el fragmento de código con líneas en blanco.
El paquete LaTeX listings
proporciona un lstlisting
entorno que se puede utilizar para embellecer el código fuente. Se puede utilizar para definir un code
entorno que se 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 { código }
que se puede configurar para producir:
Tenía la sensación de que el método de arriba hacia abajo y el 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 la WEB, me he dado cuenta de que no hay necesidad de elegir de una vez por todas entre el método de arriba hacia abajo y el de abajo hacia arriba, porque es mejor pensar en un programa como una red en lugar de como un árbol. Existe una estructura jerárquica, pero lo más importante de un programa son sus relaciones estructurales. Un software complejo consta de partes simples y relaciones simples entre esas partes; la tarea del programador es enunciar esas partes y esas relaciones, en el orden que sea mejor para la comprensión humana, no en un orden determinado rígidamente como el de arriba hacia abajo o el de abajo hacia arriba.
— Donald E. Knuth , Programación literaria [1]
Las macros de WEB pueden tener como máximo un parámetro. Nuevamente, hice esto por simplicidad, porque noté que la mayoría de las aplicaciones de múltiples parámetros podrían, de hecho, reducirse al caso de un solo parámetro. Por ejemplo, supongamos que desea definir algo como [ejemplo omitido] ... En otras palabras, el nombre de una macro puede ser útil como parámetro de otra macro.
— Donald E. Knuth , Programación literaria [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 más rápido y de forma más fiable que nunca, y ha sido una de mis mayores fuentes de alegría desde los años 80, sino que en ocasiones ha sido indispensable. Algunos de mis programas más importantes, 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 la manejara; sin la programación alfabetizada, toda la empresa habría fracasado miserablemente. ... La programación alfabetizada es lo que necesitas para elevarte por encima del nivel ordinario de logros.
Otra cosa sorprendente que aprendí mientras usaba WEB fue que los lenguajes de programación tradicionales me habían hecho escribir programas de inferior calidad, aunque no me había dado cuenta de lo que estaba haciendo. Mi idea original era que WEB sería simplemente una herramienta para 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 literaria [1]
Así, el lenguaje WEB permite a una persona expresar programas en un orden de "flujo de conciencia" . TANGLE es capaz de mezclar todo en el orden 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 puramente en PASCAL, incluso si este último programa está bien comentado. Y el hecho de que no haya necesidad de obsesionarse con la cuestión de arriba hacia abajo o de abajo hacia arriba, ya que un programador puede ahora 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 de mis experiencias recientes.
— Donald E. Knuth , Programación literaria [1]
Elegí el nombre WEB en parte porque era una de las pocas palabras de tres letras en inglés que no se había aplicado antes a las computadoras. Pero con el tiempo, me sentí muy satisfecho con el nombre, porque creo que un programa complejo se considera mejor como una red que se ha construido delicadamente a partir de materiales simples. Entendemos un sistema complicado al comprender sus partes simples y al comprender las relaciones simples entre esas partes y sus vecinos inmediatos. 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 literaria [1]