Stellen Sie sich eine funktionale Programmiersprache vor, deren einzige Datentypen numerische Skalare und beliebige Verschachtelungen von Arrays sind. Der Sprache fehlen alle Mittel zur unbegrenzten Iteration, daher sind die folgenden nicht zulässig:
- explizite Schleifen (ohne Nebenwirkungen sowieso nicht viel zu gebrauchen)
- Rekursion
- beliebige erstklassige Funktionen (kein y-Kombinator)
Die Sprache hat jedoch:
- Funktionen der obersten Ebene
- lexikalisch angelegt lassen Bindungen
- Verzweigungssteuerungsfluss
- gemeinsame skalare mathematische und logische Funktionen
- Ein einfacher Array-Konstruktor wie fill (n, x), der ein n-Element-Array mit identischen Werten x erstellt
- Am wichtigsten ist: eine eingeschränkte Gruppe von Operatoren höherer Ordnung, die eine parallel strukturierte Iteration durchführen (z. B. Map, Reduce, Scan, All-Pair).
Genauer gesagt zu den Datenparalleloperatoren:
- y = Karte (f, x) => y [i] = f [i]
- y = reduziere (f, a, x) => y = f (a, f (y [p [0]], f (y [p [1]], ...))) für eine Permutation p
- y = Scan (f, a, x) => y [i] = reduzieren (f, a, y [0 ... i-1])
- y = alle Paare (f, x, y) => y [i, j] = f (x [i], y [j])
Wir könnten auch andere Operatoren haben, aber um sie zu qualifizieren, sollten sie eine Polynomlaufzeit haben, unter einem vernünftigen Modell der datenparallelen Berechnung implementierbar sein und höchstens Polynomraum verwenden.
Es gibt offensichtlich einige Konstrukte, die in dieser Sprache nicht ausgedrückt werden können, wie zum Beispiel:
while f(x) > tol:
x <- update(x)
Was können wir in diesem System ausdrücken? Beschränken wir uns nur auf Suchprobleme in FP? Können wir alle polynomiellen Zeitalgorithmen erfassen? Gibt es auch eine minimale Anzahl von Operatoren für diese Klasse?