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?


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


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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.