Según Pippenger [1996] Wenn man ein rein funktionales Lisp-System (mit strikter Auswertungssemantik, nicht faul) mit einem System vergleicht, das Daten verändern kann, wird ein für das unreine Lisp geschriebener Algorithmus, der in O( n ) kann in einen Algorithmus in reinem Lisp übersetzt werden, der in O( n Protokoll n ) Zeit (basierend auf Arbeiten von Ben-Amram und Galil [1992] über die Simulation von Arbeitsspeichern mit wahlfreiem Zugriff unter ausschließlicher Verwendung von Zeigern). Pippenger stellt auch fest, dass es Algorithmen gibt, für die dies das Beste ist, was man tun kann; es gibt Probleme, die O( n ) in dem unreinen System, die ( n Protokoll n ) im reinen System.
Es gibt einige Vorbehalte zu diesem Papier. Der wichtigste ist, dass es sich nicht mit faulen funktionalen Sprachen wie Haskell befasst. Bird, Jones und De Moor [1997] zeigen, dass das von Pippenger konstruierte Problem in einer faulen funktionalen Sprache in O( n ) Zeit, aber sie stellen nicht fest (und soweit ich weiß, hat das auch noch niemand getan), ob eine faule funktionale Sprache alle Probleme in der gleichen asymptotischen Laufzeit lösen kann wie eine Sprache mit Mutation oder nicht.
Das von Pippenger konstruierte Problem erfordert ( n Protokoll n ) wurde speziell zu diesem Zweck erstellt und ist nicht unbedingt repräsentativ für praktische, reale Probleme. Es gibt einige Einschränkungen für das Problem, die etwas unerwartet, aber notwendig sind, damit der Beweis funktioniert; insbesondere erfordert das Problem, dass die Ergebnisse online berechnet werden, ohne dass auf zukünftige Eingaben zugegriffen werden kann, und dass die Eingabe aus einer Folge von Atomen aus einer unbeschränkten Menge möglicher Atome besteht, anstatt aus einer Menge fester Größe. Außerdem werden in dem Papier nur Ergebnisse (untere Schranke) für einen unreinen Algorithmus mit linearer Laufzeit ermittelt; bei Problemen, die eine längere Laufzeit erfordern, ist es möglich, dass die zusätzlichen O(log n ) des linearen Problems kann möglicherweise durch zusätzliche Operationen, die für Algorithmen mit längeren Laufzeiten erforderlich sind, "absorbiert" werden. Diese Klarstellungen und offenen Fragen werden kurz erörtert durch Ben-Amram [1996] .
In der Praxis können viele Algorithmen in einer rein funktionalen Sprache genauso effizient implementiert werden wie in einer Sprache mit veränderbaren Datenstrukturen. Eine gute Referenz für Techniken zur effizienten Implementierung rein funktionaler Datenstrukturen finden Sie unter Chris Okasakis "Purely Functional Data Structures" [Okasaki 1998] (dies ist eine erweiterte Version seiner Dissertation (Okasaki 1996) ).
Jeder, der Algorithmen auf rein funktionalen Datenstrukturen implementieren muss, sollte Okasaki lesen. Man kann im schlimmsten Fall immer eine O(log n ) Verlangsamung pro Operation durch die Simulation von veränderbarem Speicher mit einem ausgeglichenen Binärbaum, aber in vielen Fällen kann man noch wesentlich besser vorgehen, und Okasaki beschreibt viele nützliche Techniken, von amortisierten Techniken bis hin zu Echtzeittechniken, die die amortisierte Arbeit inkrementell erledigen. Rein funktionale Datenstrukturen können etwas schwierig zu handhaben und zu analysieren sein, aber sie bieten viele Vorteile wie z.B. referenzielle Transparenz, die bei der Compiler-Optimierung, beim parallelen und verteilten Rechnen und bei der Implementierung von Funktionen wie Versionierung, Undo und Rollback hilfreich sind.
Beachten Sie auch, dass es hier nur um asymptotische Laufzeiten geht. Viele Techniken zur Implementierung rein funktionaler Datenstrukturen führen zu einer gewissen Verlangsamung um einen konstanten Faktor, was auf die zusätzliche Buchhaltung zurückzuführen ist, die für das Funktionieren dieser Strukturen erforderlich ist, sowie auf Implementierungsdetails der betreffenden Sprache. Die Vorteile rein funktionaler Datenstrukturen können diese Verlangsamungen um konstante Faktoren überwiegen, so dass Sie im Allgemeinen je nach Problemstellung Kompromisse eingehen müssen.
Referenzen
- Ben-Amram, Amir und Galil, Zvi 1992. "Über Zeiger und Adressen" Journal of the ACM, 39(3), S. 617-648, Juli 1992
- Ben-Amram, Amir 1996. "Anmerkungen zu Pippingers Vergleich von reinem und unreinem Lisp" Unveröffentlichtes Manuskript, DIKU, Universität Kopenhagen, Dänemark
- Bird, Richard, Jones, Geraint, und De Moor, Oege 1997. "Mehr Eile, weniger Tempo: träge versus eifrige Bewertung" Zeitschrift für funktionale Programmierung 7, 5 pp. 541-547, September 1997
- Okasaki, Chris 1996. "Rein funktionale Datenstrukturen" Dissertation, Carnegie Mellon Universität
- Okasaki, Chris 1998. "Rein funktionale Datenstrukturen" Cambridge University Press, Cambridge, UK
- Pippenger, Nicholas 1996. "Reines versus unreines Lisp" ACM Symposium on Principles of Programming Languages, Seiten 104-109, Januar 1996