zu www.bildungsgueter.de zur Inhaltsübersicht des Kapitels

LISP - Implementierungshinweise

Effiziente Implementierung schlichter Aufrufe und endrekursiver Funktionen


Begriffsbestimmungen

Ein schlichter Aufruf ist ein Aufruf in Ergebnisposition.

Ein rekursiver Aufruf, der schlicht ist, heißt endrekursiv (engl.: tail recursive). Auch die Bezeichnung restrekursiv ist üblich.

Beispiele für schlichte Aufrufe

(setq odd*
      '(lambda (x)
               (cond ((zerop x) nil)
                     (t (even* (sub1 x)))
)      )       )

(setq even*
      '(lambda (x)
               (cond ((zerop x))
                     (t (odd* (sub1 x)))
)      )       )

In diesem Beispiel liegt verschränkte Rekursion vor. Der Aufruf von even* in der Funktion odd* ist ein schlichter Aufruf. In gleicher Weise ist auch der Aufruf von odd* in der Funktion even* ein schlichter Aufruf.

Beispiel einer endrekursiven Definition:

(setq last*
     '(lambda (x)
              (cond ((null (cdr x)) x)
                    (t (last* (cdr x)))
)     )       )

In dieser Funktion wird ein rekursiver Aufruf von last* als schlichter Aufruf verwendet.

(setq sum
      '(lambda (i0 in fn)
          ((label compute-sum
                  (lambda (s i)
                          (cond ((greaterp i in) s)
                                (t (compute-sum (plus s (fn i)) (add1 i)))
           )      )       )
           0 i0
)      )  )

Die lokal vereinbarte Funktion compute-sum enthält einen endrekursiven Aufruf.


Hier müssen die Argumentwerte des rekursiven Aufrufs noch in der vom Lambda-Ausdruck erzeugten Umgebung ausgewertet werden. Der rekursive Aufruf selbst kann dann die nicht mehr benötigten Bindings aufgeben, bevor er neue Bindings erzeugt.


Ein allgemeinerer Fall verschränkter Rekursion:

(setq p1
      '(lambda (x y )  % soll z verwenden
               (cond ((zerop x) nil)
                     (t (p2 (sub1 x)))
)      )       )

(setq p2  % soll  y verwenden
      '(lambda (x z)
               (cond ((zerop x))
                     (t (p1 (sub1 x)))
)      )       )

Es ist im Augenblick nicht klar, wie hier das Anwachsen des Lisp-Kellers vermieden werden kann.

...


zur Inhaltsübersicht des Kapitels