Otras personas han aplicado DAG a los datos, pero creo que es al menos tan aplicable (si no más) al código. Mahbubur R. Aaman menciona esto, así que realmente es más una adición a su respuesta que una respuesta completa por sí sola.
Se me ocurre que cualquier programa informático imperativo que esté libre de bucles infinitos (gracias @AndresF.) Es un Gráfico Acíclico Dirigido (DAG). Lo que significa que las posibles rutas de ejecución del código son dirigidas (primero esto, luego aquello) y acíclicas (sin formar bucles infinitos). Son un gráfico porque la ruta a través de cualquier código significativo rara vez es tan simple como una lista o un árbol.
Trabajé en XSLT por unos 4 años. Tuve un momento terrible tratando de explicar por qué no era un buen lenguaje de programación de propósito general, pero DAG es la razón. Específicamente, XSLT es un lenguaje basado en datos. Define funciones (sí, en el sentido de la programación funcional) pero no necesariamente llama a estas funciones desde su código. Por el contrario, XSLT establece una combinación de selección e iteración a través de los nodos de un documento XML de entrada. Esto permite que la estructura de los datos de entrada determine qué funciones se llaman y en qué orden.
Esto fue muy interesante y genial hasta que su programa encontró una condición de datos que no probó a las 2:30 a.m. y tuvo que despertarse y arreglarlo. Cuando deja que los datos definan el DAG, la definición del DAG se convierte en todas las condiciones de entrada posibles, que para cualquier aplicación comercial no trivial son más que incalculables; Son inimaginables.
Al principio, pensé que la programación funcional puede no ser un DAG porque el orden de ejecución a veces no es claro, ni siquiera pensado por el programador. Pero un programa funcional sí define dependencias. De hecho, la naturaleza declarativa de la programación funcional podría considerarse como la definición de solo dependencias (a ^ 2 = b ^ 2 + c ^ 2) sin especificar el orden de ejecución (no importa si 'b' o 'c' se cuadran primero , siempre que ambos estén al cuadrado antes de sumarlos).
Pero aunque la programación funcional puede ser deliberadamente vaga sobre el orden de las operaciones a un nivel detallado, es exquisitamente clara sobre las dependencias. Estas son las características que lo hacen tan susceptible a la concurrencia. En cualquier caso, todavía hay un gráfico de rutas a través del código, y ese gráfico todavía está dirigido (las dependencias deben evaluarse antes de las tareas dependientes), por lo que creo que DAG también se aplica allí.
Buena pregunta: ¡gracias por publicar!