Imagine un lenguaje de programación funcional cuyos únicos tipos de datos son escalares numéricos y anidaciones arbitrarias de matrices. El lenguaje carece de cualquier medio de iteración ilimitada, por lo que no se permite lo siguiente:
- bucles explícitos (de todos modos, sin mucho uso sin efectos secundarios)
- recursividad
- funciones arbitrarias de primera clase (sin combinador y)
Sin embargo, el lenguaje tiene:
- funciones de nivel superior
- Ángulo léxico dejar enlaces
- flujo de control de ramificación
- funciones escalares comunes de matemática y lógica
- algún constructor de matriz simple como fill (n, x) que crea una matriz de n elementos con valores idénticos x
- lo más importante: un conjunto restringido de operadores de orden superior que realizan iteraciones estructuradas paralelas (como mapear, reducir, escanear, todos los pares).
Para ser más específico sobre los operadores paralelos de datos:
- y = mapa (f, x) => y [i] = f [i]
- y = reducir (f, a, x) => y = f (a, f (y [p [0]], f (y [p [1]], ...))) para alguna permutación p
- y = exploración (f, a, x) => y [i] = reducir (f, a, y [0 ... i-1])
- y = todos los pares (f, x, y) => y [i, j] = f (x [i], y [j])
También podríamos tener otros operadores, pero para calificar deberían tener un tiempo de ejecución polinómico, ser implementables bajo algún modelo razonable de cómputo paralelo de datos y usar como máximo espacio polinómico.
Obviamente, hay algunas construcciones que no se pueden expresar en este lenguaje, como:
while f(x) > tol:
x <- update(x)
¿Qué podemos expresar en este sistema? ¿Estamos limitados solo a problemas de búsqueda en FP? ¿Podemos capturar todos los algoritmos de tiempo polinomiales? Además, ¿hay algún conjunto mínimo de operadores para esta clase?