Wie mache ich in ELisp benannte Argumente?

8

Ich nahm an, dass Emacs Lisp und Common Lisp so eng mit der Syntax verwandt waren, dass ich einfach dem Beispielcode folgen konnte, den ich auf RosettaCode , aber es stellt sich heraus, dass ich falsch lag.

Der betreffende Code sieht so aus:

%Vor%

Und nach RosettaCode sollte es Folgendes tun:

%Vor%

Nun, hier ist das Ding; Wenn ich versuche, diese Funktion in meinem ELisp-Interpreter auszuführen, erhalte ich den folgenden Fehler:

%Vor%

Ich bin nicht routiniert genug zu lispern, um zu wissen, was das bedeuten soll, und keine Menge von Googeln hat mich einer Antwort näher gebracht.

Was ist der richtige Weg, dies in Emacs Lisp zu tun?

    
Electric Coffee 29.09.2014, 14:58
quelle

3 Antworten

12

Da Emacs Lisp Schlüsselwortargumente nicht direkt unterstützt, müssen Sie diese emulieren, entweder mit cl-defun wie in der anderen Antwort, oder indem Sie die Argumente als plist analysieren:

%Vor%

&rest args weist Emacs an, alle Funktionsargumente in eine einzige Liste zu schreiben. plist-get extrahiert einen Wert aus einer Eigenschaftsliste, dh eine Liste des Formats (key1 value1 key2 value2 …) . Effektiv ist ein Plist eine abgeflachte Alist.

Gemeinsam können Sie print-name wie in Ihrer Frage aufrufen:

%Vor%     
lunaryorn 29.09.2014 16:01
quelle
12

Elisps defun unterstützt nicht &key (unterstützt jedoch &optional und &rest ). Es gibt ein Makro, mit dem Sie Funktionen mit &key definieren können. In Emacs 24.3 und später können Sie cl-lib anfordern und cl-defun verwenden:

%Vor%

In früheren Emacs-Versionen ist dieselbe Funktionalität in der cl -Bibliothek unter dem Namen defun* :

enthalten %Vor%

Die cl-lib -Bibliothek wird vor cl bevorzugt, da der Namespace sauber gehalten wird, indem allen Symbolen cl- vorangestellt wird; Wenn Sie jedoch Kompatibilität mit früheren Emacs-Versionen benötigen, bevorzugen Sie möglicherweise cl und defun* .

Die Funktion im Beispiel enthält auch einen Aufruf der Funktion values . Diese Funktion ist spezifisch für Common Lisp, ist aber als cl-values in cl-lib und values in cl verfügbar.

Die Alternativen funktionieren jedoch nicht genau so wie ihr Common-Lisp-Pendant. Common Lisp hat das Konzept mehrerer Rückgabewerte. Zum Beispiel würde der Aufruf von (values 1 2 3) drei Werte zurückgeben - und der Aufruf von (values) wie oben würde Nullwerte zurückgeben. Die Emacs-Lisp-Funktionen emulieren mehrere Rückgabewerte anhand von Listen und definieren auch multiple-value-bind neu, damit sie übereinstimmen. Dies bedeutet, dass der Aufruf (cl-values) nur nil (die leere Liste) zurückgibt.

In einer solchen Emacs-Lisp-Funktion würden Sie den Rückgabewert entweder explizit als nil angeben oder Sie lassen ihn ganz weggelassen, wobei der Rückgabewert des letzten Formulars als Rückgabewert der Funktion seit dem Aufrufer verbleibt Es wird nicht erwartet, dass der Rückgabewert verwendet wird.

    
legoscia 29.09.2014 15:32
quelle
2

Leider elisp unterstützt nicht benannte Argumente per se . Sie können diese Funktion jedoch emulieren, indem Sie eine alist an eine Funktion übergeben, prüfen Sie dies für eine Anleitung zu alists . .

Im Kern bedeutet dies, dass Sie eine kartenähnliche -Datenstruktur in die Funktion übergeben. Daher müssen Sie sowohl das Wrapping (Zusammenstellung von Argumenten in alist ) als auch das Entpacken berücksichtigen (Zerlegung in Variablen / Überprüfung von erforderlichen / optionalen Werten) selbst.

Das Erstellen der Eingabestruktur ist einfach, einfach die Zellen des Variablensymbols und seinen Wert zusammensetzen:

%Vor%

Das Lesen ist noch einfacher: Verwenden Sie einfach assoc , um den entsprechenden Wert zu erhalten:

%Vor%

Daher könnte print-name folgendermaßen aussehen:

%Vor%     
elemakil 29.09.2014 15:21
quelle

Tags und Links