Beabsichtigte unendliche Rekursion, keine Rückkehrfunktionen

7

Unendliche Rekursion wird meistens nicht gewünscht, und wenn es passiert, verursacht es normalerweise einen Stapelüberlauf oder segfaults.

Aber aus Gründen der Theorie und der einfachen Neugier habe ich darüber nachgedacht, ob es möglich wäre, absichtlich eine echte unendliche Rekursion zu erzeugen.

Arbeiten in C ++ und C, wobei der Stack normalerweise für jeden Funktionsaufruf wächst und jede Funktion den Teil des Stacks zurückgibt, den sie bearbeitet hat.

Hier ist der Gedanke. Wäre es möglich, eine Funktion zu zwingen, ihren eigenen Stapelspeicherplatz zu löschen und dann eine andere Funktion aufzurufen, so dass die neue Funktion effektiv die erste Funktion ersetzt, ohne dass die erste Funktion zurückkehren und dann erneut über eine Schleife ausgelöst werden muss.

Ich denke nicht nur über einfache Schleifen als mögliche Verwendung dafür nach, wenn es welche geben würde. Loops machen normalerweise einen guten Job bei dem, was sie tun. Aber was wäre, wenn Sie es zum Senden von Signalen über ein Knoten-Netzwerk verwenden würden, die endlos in ihren eigenen Prozess-Threads weiterlaufen, bis sie eine bestimmte Bedingung erreichen. Es könnte ein Werkzeug sein, das für einige Probleme verwendet werden könnte.

Denken Sie daran, ich frage nicht wirklich, ob es praktisch ist, nur wenn es möglich ist. Für die Wissenschaft!

    
Zoomulator 19.10.2011, 10:53
quelle

3 Antworten

15
  

Wäre es möglich, eine Funktion zu zwingen, den eigenen Stack zu löschen?   Leerzeichen und dann eine andere Funktion aufrufen, damit die neue Funktion   ersetzt effektiv die erste Funktion

Dies wird für tail-call-optimization verwendet, also ja möglich und in der Praxis genutzt. In Sprachen wie C ++ ist dies ein nettes Feature, weil Algorithmen manchmal einfacher unter Verwendung von Rekursion ausgedrückt werden können, aber effizienter unter Verwendung einer Schleife implementiert werden können. Die Umwandlung kann in einigen Fällen automatisch vom Compiler durchgeführt werden.

    
Björn Pollex 19.10.2011 10:56
quelle
5

Es gibt eine Technik namens Trampolining, die verwendet wird, um Fortsetzungsstil ohne zu programmieren die Verwendung von Tail-Call-Optimierung. Wenn Sie eine Sprache ohne Unterstützung für TCO wie JavaScript und Forschungslösungen für CPS in dieser Sprache in Betracht ziehen, ist es wahrscheinlich, dass die Lösung Trampolining beinhaltet.

Im Wesentlichen gibt es beim Trampolining eine Funktion namens Trampolin, die iterativ Thunk-Return-Funktionen aufruft.

Ich weiß, dass du gesagt hast "ohne dass die erste Funktion zurückkehren und dann wieder über eine Schleife abfeuern muss" - das ist Trampolining - aber wenn man bedenkt, dass dies C ++ ist, ist das Verlassen von Bereichen, beispielsweise durch Rückkehr, von zentraler Bedeutung Design von C ++'s automatischer Ressourcenverwaltung über Destruktoren (siehe: RAII). Sie können auch die Funktionen setjmp() / longjmp() von C verwenden, um den Stapel zu löschen, aber dann müssen Sie sehr vorsichtig sein, um sicherzustellen, dass alle Ressourcen ordnungsgemäß freigegeben werden.

    
Daniel Trebbien 19.10.2011 11:20
quelle
2

Das erinnert mich an eine Optimierung, die in Assembler-Code vorgenommen werden kann. Sprich du hast das:

%Vor%

Sie können es ersetzen mit:

%Vor%

Dies führt dazu, dass ret am Ende von FuncA direkt zu FuncB springt, anstatt zurück zum Aufrufer und dann zu FuncB . In höheren Sprachen nicht wirklich möglich.

Es gibt auch folgendes:

%Vor%

kann geändert werden zu:

%Vor%     
Skizz 20.10.2011 11:04
quelle

Tags und Links