[Inhalt]...["Strictness" in Haskell]...[Literaturverzeichnis]
Code-Beispiel in Haskell [Quelldatei]
>> sort :: [Integer]->[Integer]
An zwei Stellen spart die nicht-strikte Auswertung in Einzelfällen Laufzeit ein,
weil die Anzahl der auszuwertenden Teilausdrücke reduziert wird. In Kapitel 2 "Nicht-strikte Auswertung"
wurde darauf hingewiesen, dass alle namentlichen Vorkommen eines ausgewerteten Ausdrucks durch seinen Wert ersetzt werden.
Damit reduziert sich bei doppelten Elementen oder wiederholten Vergleichstests im zu sortierenden Feld die Menge der auszuwertenden
Ausdrücke. Das gleiche gilt für den rekursiven Aufruf der "
Während also die Komplexität des "Insertion-Sort"-Algorithmus in imperativen oder objektorientierten Programmiersprachen
als quadratisch zur Anzahl der sortierenden Elemente bekannt ist, hängt sie bei einer nicht-strikten, funktionalen Sprache
wie "Haskell" vor allem auch von der Ausprägung des Feldes ab.
Der erste stellt einen Fall dar, der auch in der "Haskell Mailing List" mehrfach Thema war. Beim Einlesen
von Dateien generieren Parser häufig Hilfsstrukturen, in denen die Inhalte der Dateien gepackt werden.
Aus diesen Strukturen werden schließlich die relevanten Daten extrahiert. Wenn in diesem
Fall die von einem Parser erzeugten Strukturen nicht strikt ausgewertet werden, kann beim Einlesen vieler
großer Strukturen der Speicherbedarf erheblich ansteigen.
Der zweite Aspekt besteht darin, dass für die Verwaltung nicht strikter Ausdrücke zusätzlicher Speicher
benötigt wird, um die Zuordnung von namentlichen Definitionen zu Ausdrücken zu realisieren, und eine
Veranschlagung der auszuwertenden und nicht auszuwertenden Teilausdrücke vorzunehmen, sowie Informationen.
[Inhalt]...["Strictness" in Haskell]...[Literaturverzeichnis]
5.1 "Handling"
In einer nicht-strikten, funktionalen Sprache ist die Reihenfolge der
Auswertung von Ausdrücken nicht relevant. Somit muss sich auch der Entwickler/Programmierer
hierüber keine Gedanken machen. Des weiteren kann er sich darauf verlassen, dass
alle (im Zweifel rechenintensiven) Operationen nur dann berechnet werden, wenn
ihr Ergebnis für die Weiterverarbeitung benötigt wird. Dadurch wird in vielen Fällen ein
problemnaher Entwurf begünstigt, der strukturelle Aspekte der Implementation
kaum berücksichtigen muss.
Es besteht beispielsweise die Möglichkeit, Verarbeitungs- oder Kontrollroutinen für Datenstrukturen
zu implementieren, die eventuell nicht terminieren. Aufgrund von Parametern oder Ausprägungen
der Daten kann die Auswertung dann gesteuert werden.
5.2 Komplexität
Die Komplexität eines Algorithmus oder einer Funktion bezeichnet die
Wachstumsrate von Resourcen wie zum Beispiel der Laufzeit gegenüber der Menge der zu
verabeitenden Daten. Im Falle von "Lazy evaluation" wird immer die geringste
Anzahl an benötigten Werten von Ausdrücken berechnet. Daraus lässt sich schließen,
dass in speziellen Problemfällen die Komplexität von Algorithmen in einer
nicht strikten Sprache reduziert werden kann. Als Fallbeispiel soll an dieser
Stelle der einfache "Insertion-Sort"-Algorithmus zum Sortieren von Feldern
dienen.
>> insert :: Integer->[Integer]->[Integer]
>> insert a [] = [a]
>> insert a (x:xs) | a<x = [a]++(x:xs)
>> | otherwise = [x]++(insert a xs)
>> sort [] = []
>> sort (x:xs) = (insert x (sort xs))
insert
"-Methode. Wiederholte Einfügeoperationen werden
nur einmal ausgewertet.5.3 Speicherbedarf
Durch Reduktion der Auswertungen werden Operationen gespart, und damit Laufzeit und Speicher. Zwei Aspekte müssen bei der Programmierung
mit nicht-strikter Auswertung jedoch bedacht werden, so dass sich dieser Vorteil nicht umkehrt.