Standardmethode zum Ausbrechen der Rekursion im Schema

8

Ich schreibe mein erstes Programm in einem Schema. Ich komme ziemlich tief in Rekursion, weil ich im Grunde ein Programm für einen einfachen Roboter interpretiere, der verschachtelte Prozeduranrufe haben kann.

Wenn ich eine Verletzung finde, muss ich das Programm nicht mehr interpretieren und den letzten gültigen Zustand zurückgeben.

Ich habe es gelöst, indem ich eine globale Variable (define illegalMoveFlag 0) deklariert habe und sie dann über set! gesetzt habe.

Es funktioniert gut, aber ich denke, mein Tutor wird es nicht mögen (weil es keine funktionale Herangehensweise ist, denke ich)

Andere Vorgehensweise, über die ich nachgedacht habe, ist das Hinzufügen eines Fehlerparameters zu jeder Funktion, die ich rekursiv im Programm aufruft. Ich mag es nicht, weil es meinen Code viel weniger lesbar machen würde, aber ich denke, es ist mehr "funktional".

Gibt es vielleicht eine dritte Möglichkeit, an die ich nicht gedacht habe? Und kann mein Ansatz in diesem Paradigma gerechtfertigt werden, oder ist es im Grunde ein Code-Geruch?

    
Honza Brabec 22.02.2013, 22:25
quelle

5 Antworten

5

Da dies Ihr erstes Scheme-Programm war, müssen Sie wahrscheinlich nur einen bedingten Ausdruck, cond , einführen, um weitere Rekursionen zu vermeiden, wenn Sie das Ende erreichen. Zum Beispiel:

%Vor%

Wenn Sie jedoch ein traditionelles return benötigen, um wie longjmp in C zurückzukehren, müssen Sie eine Escape-Fortsetzung speichern und verwenden. Dies kann so gemacht werden:

%Vor%

Wenn let/ec nicht in Ihrer Scheme-Implementierung definiert ist, dann setzen Sie Ihr Programm mit:

%Vor%

UPDATE:

Beachten Sie, dass cond eine => Variante hat:

%Vor%

Wenn der Aufruf erfolgreich ist, lautet die erste Klausel genommen und das Ergebnis ist an a gebunden. Wenn der Anruf fehlschlägt, Dann wird die Else-Klausel verwendet.

    
soegaard 23.02.2013, 10:04
quelle
5

Der übliche Weg, die Rekursion zu stoppen, ist, die Rekursion zu stoppen. d.h., rufen Sie die rekursive Funktion nicht länger auf. : -)

Wenn das zu schwierig ist, besteht die andere Möglichkeit, aus etwas herauszubrechen darin, eine Fortsetzung auf der obersten Ebene zu erfassen (bevor Sie rekursiv beginnen), und dann die Fortsetzung aufzurufen, wenn Sie "flüchten" müssen. Dein Lehrer mag diesen Ansatz jedoch nicht mögen. ; -)

    
Chris Jester-Young 22.02.2013 22:37
quelle
2

Vielleicht möchten Sie die integrierte Prozedur error verwenden, etwa so:

%Vor%

Dies wird eine Ausnahme auslösen und die Interpretation des Programms beenden (obwohl ich vermute, dass dies nicht das ist, was Sie suchen).

Sie können auch zusätzliche Argumente wie folgt angeben:

%Vor%     
Liffon 22.02.2013 22:37
quelle
1

Sie können eine Rekursion (oder einen anderen Prozess) mit einer Fortsetzung beenden. Ohne weitere Einzelheiten zu kennen, empfehle ich Ihnen, sich die Dokumentation Ihres Interpreters anzusehen.

    
Óscar López 22.02.2013 22:38
quelle
1

Machen Sie illegalMoveFlag einen Parameter in der Funktion anstelle einer globalen Variable

Ich gebe Ihnen ein einfaches Beispiel mit Fakultäten

zB: 0! = 1 n! = n * (n - 1)! wenn n (1 ... unendlich)

ist

nennt dies eine rekursive Fakultät

%Vor%

Eine Alternative wäre, einen Parameter für die Funktion zu verwenden, um die Rekursion zu beenden Lässt es iterativ factorial

heißen %Vor%

total muss bei 1 beginnen, also sollten wir eine andere Funktion machen, um es netter zu machen

%Vor%

Sie können etwas ähnliches mit illegalMoveFlag tun, um zu vermeiden, dass Sie eine globale Variable haben Soweit das Verwenden von Set vermeiden! Geht, wir werden wahrscheinlich mehr Informationen benötigen.

In einigen Fällen ist es immer noch ziemlich schwer zu vermeiden, es zu benutzen. Das Schema ist vollständig abgeschlossen ohne die Verwendung von Set! wenn es jedoch um den Zugriff auf eine externe Informationsquelle wie eine Datenbank oder ein Roboter-Set geht! kann die einzige praktische Lösung werden ...

    
sav 24.02.2013 10:54
quelle

Tags und Links