Makro "cl-flet", das keine rekursiven Funktionen zulässt

7

Ich bin an das veraltete Elisp-Makro gewöhnt fletund wurde aufgefordert, zu zu wechseln cl-flet. Doch auf diese Änderung gestoppt einige meiner elisp Programme machen Arbeit und ich erkennen , der Grund , dass, im Gegensatz zu flet, cl-fletnicht für rekursive Funktionen erlaubt. Beispiel: Definieren Sie die folgende Funktion

(defun show-problem-in-action (x)
  (cl-flet (
    (factorial (n)
      (if (= n 0)
        1
        (* n (factorial (- n 1))) )))
  (factorial x) ))

man bekommt keinen Fehler durch Aufrufen

(show-problem-in-action 0)

Ausgabe: 1

weil sich die Funktion "cl-flet-defined" factorialnicht selbst aufruft, wenn "x = 0". jedoch

(show-problem-in-action 5)

erzeugt den Fehler void-function factorial.

Auf der anderen Seite cl-fletdurch das veraltete Makro ersetzen flet, wie unten

(defun no-problem-with-deprecated-macro (x)
  (flet (
    (factorial (n)
      (if (= n 0)
        1
        (* n (factorial (- n 1))) )))
  (factorial x) ))

ermöglicht rekursiven Aufruf:

(no-problem-with-deprecated-macro 5)

Ausgabe: 120

Wenn cl-fletes nicht funktioniert, was wäre meine beste Alternative, um es zu ersetzen fletund trotzdem Funktionen rekursiv aufrufen zu können?

Ruy
quelle
4
Übrigens ist der entscheidende Unterschied zwischen fletund cl-fletnicht die mangelnde Unterstützung für die Rekursion, sondern die Tatsache, dass Funktionsdefinitionen fletmit dynamischem Gültigkeitsbereich bereitgestellt werden, während Funktionsdefinitionen cl-fletmit lexikalischem Gültigkeitsbereich bereitgestellt werden. Dynamisches Scoping bietet Unterstützung für die Rekursion, da es sich intern auf eine Indirektion stützt.
Stefan

Antworten:

4

Verwenden Sie cl-labelsanstelle von cl-flet. Erklärungen finden Sie im emacs-Handbuch

siehe-falz
quelle
Oder in C-h f cl-fletder Tat, die sagt "Wie, cl-labelsaber die Definitionen sind nicht rekursiv."
Phils
Danke für die Antwort. Wäre es nicht schön, wenn die Warnung, die ich erhalten habe ('flet' ist ein veraltetes Makro (ab 24.3); benutze entweder 'cl-flet' oder 'cl-letf'), auch 'cl-label' erwähnt?
Ruy
I aufgefallen (die harte Weise) , dass ein anderer Unterschied zwischen fletund cl-labelsdass die Funktionen mit dieser Syntax definiert ist , muß über den #‘quotation bezeichnet werden, wie es zu den üblichen Single-Quote gegenüber .
Ruy
Trotz der Tatsache, dass meine Frage bisher drei Stimmen erhalten hat, ist es mir ein bisschen peinlich, weil sie direkt aus der Dokumentenkette von beantwortet werden kann cl-labels, wie @phils hervorhebt. Ich werde es gerne löschen, falls jemand denkt, dass es unnötigen Speicherplatz in diesem Forum verbraucht.
Ruy
@ Ruy: überhaupt kein Problem. Zum einen habe ich aus diesem Austausch etwas gelernt, und ich bezweifle, dass ich der einzige sein werde.
Dan