Was hindert ghc daran, Haskell in eine verkettete Programmiersprache wie kombinatorische Logik zu übersetzen und dann einfach die Stapelzuweisung für alles zu verwenden? Laut Wikipedia ist die Übersetzung von Lambda-Kalkül in kombinatorische Logik trivial, und auch verkettete Programmiersprachen können sich bei der Speicherzuweisung ausschließlich auf einen Stapel stützen. Ist es möglich, diese Übersetzung zu machen und so die Garbage Collection für Sprachen wie Haskell und ocaml zu eliminieren? Gibt es Nachteile dabei?
BEARBEITEN: hierher verschoben /programming/39440412/why-do-functional-programming-languages-require-garbage-collection
functional-programming
haskell
Nicholas Grasevski
quelle
quelle
Antworten:
Alle folgenden Kommentare basieren auf der Wahl einer Standardimplementierungsstrategie unter Verwendung von Closures zur Darstellung von Funktionswerten und einer Call-by-Value-Evaluierungsreihenfolge:
Für die reine Lambda-Rechnung ist keine Speicherbereinigung erforderlich. Dies liegt daran, dass es nicht möglich ist, Zyklen im Heap zu bilden: Jeder neu zugewiesene Wert kann nur Verweise auf zuvor zugewiesene Werte enthalten. Daher bildet der Speichergraph eine DAG. Die Referenzzählung ist also ausreichend, um den Speicher zu verwalten.
Die meisten Implementierungen verwenden aus zwei Gründen keine Referenzzählung.
ref
Typkonstruktor in ml) gelöst und so wahr Zyklen in dem Haufen gebildet werden.Durch linear getippte Sprachen kann die Referenzanzahl eliminiert werden (im Wesentlichen, weil die Anzahl 0-1 beträgt: Entweder hat der Wert eine einzige Referenz oder er ist tot und kann freigegeben werden).
Die Stapelzuordnung reicht jedoch immer noch nicht aus. Dies liegt daran, dass es möglich ist, Funktionswerte zu bilden, die sich auf freie Variablen beziehen (dh, wir müssen Funktionsabschlüsse implementieren). Wenn Sie Dinge auf dem Stapel zuordnen, können Live-Werte mit toten Werten verschachtelt werden, was zu einer falschen asymptotischen Wirkung führt Raumnutzung.
Sie können die richtige Asymptotik erzielen, indem Sie einen Stapel durch einen "Spaghetti-Stapel" ersetzen (dh den Stapel als verknüpfte Liste im Heap implementieren, sodass Sie bei Bedarf tote Rahmen ausschneiden können).
Wenn Sie eine echte Stapeldisziplin wünschen, können Sie Typsysteme verwenden, die auf "geordneter Logik" basieren (im Wesentlichen lineare Typen minus Austausch).
quelle