Wie Defalias Lambda?

8

Ich habe dies in meinen .emacs:

(defalias 'λ 'lambda)

das funktioniert gut für einfache Dinge wie (funcall (λ (x) x) 1).

Aber wenn ich so etwas wie (org-add-link-type "foo" (λ (s) (message s)))oder (add-to-list 'auto-mode-alist '("foo" . (λ () (message "bar"))))mache, funktioniert es nicht und ich bekomme

org-open-at-point: Ungültige Funktion: (λ (s) (Nachricht s))

und

Dateimodus-Spezifikationsfehler: (ungültige Funktion (λ nil (Meldung "bar")))

beziehungsweise.

Weiß jemand, was hier los ist?

rtrn
quelle
4
Keine Antwort auf die Frage zu defalias, aber Sie möchten vielleicht auschecken, was Ihnen prettify-symbols-modeunter anderem ermöglicht, anzuzeigen lambda, λohne den zugrunde liegenden Text tatsächlich zu ändern.
Dan
Eine einfache Bibliothek, die nur lambda (zu λ) verschönert : pretty-lambdada.el.
Drew
Wenn Sie nur hübsche Symbole wollen, dann verwenden Sie github.com/akatov/pretty-mode
grettke

Antworten:

11

Mit etwas Hilfe von lunaryorn auf reddit konnte ich wohl verstehen, warum Sie das "seltsame" Verhalten beobachten.

Das Problem ist, dass Sie den Ausdruck zitieren

'("foo" . (λ () (message "bar")))

Welches ist gleichbedeutend mit der Form

(cons "foo" '(λ () (message "bar")))

Wenn emacs jetzt eine Datei mit der Erweiterung "foo" öffnet, geschieht Folgendes

(funcall '(λ () (message "bar")))

Beachten Sie das zusätzliche Zitat, bevor dies offensichtlich keine gültige Funktion ist und Sie den Fehler erhalten. Invalid function: ... Aber warum funktioniert das ("foo" . (lambda () (message "bar")))? Dies wird durch die Beobachtung von lunaryorn erklärt

Eine „Lambda-Liste“, dh eine Liste, deren Auto Lambda ist, ist ebenfalls eine gültige Funktion

Ist dies '(lambda () (message "bar"))also eine gültige Funktion, kann dies durch den folgenden Code überprüft werden

(functionp (lambda () "hello"))  => t
(functionp (λ () "hello"))       => t
(functionp '(lambda () "hello")) => t
(functionp '(λ () "hello"))      => nil

Die Lösung wäre also, den Ausdruck einfach nicht zu zitieren und stattdessen Folgendes zu verwenden

(add-to-list 'auto-mode-alist (cons "foo" (λ () (bar))))
Iqbal Ansari
quelle
Danke für die gründliche Erklärung! Jetzt funktioniert alles gut :)
15.
3

Es sieht so aus, als ob das Problem nicht beim liegt defalias, sondern wo und wie Sie anrufen λ. funcallNimmt als Argumente eine Funktion und die Argumente dieser Funktion, sodass Ihr funcallBeispiel einwandfrei funktioniert.

Beide org-add-link-typeund die auto-mode-alisterwarten jedoch Symbole, die die relevanten Funktionen enthalten. Ausgehend von Ihren Beispielen sollte daher Folgendes funktionieren:

(defun a-silly-fnx (s)
  (message s))
(defalias #'my-link-alias #'a-silly-fnx)
(org-add-link-type "foo" #'my-link-alias)

(defun a-tester-fnx ()
  (message "Testing!")
  (sit-for 2))
(defalias #'my-alist-alias #'a-tester-fnx)
(add-to-list 'auto-mode-alist '("foo" . my-alist-alias))

Wenn Sie hauptsächlich λin Ihrem Puffer prettify-symbols-modeangezeigt werden möchten, sollten Sie es ausprobieren. Dies wird angezeigt lambda, λohne den Text des Puffers zu ändern.

Dan
quelle
Das Seltsame ist, dass alles gut funktioniert, wenn ich lambdadirekt benutze .
15.
@rtrn: ah, guter Punkt. Ich vermute, das liegt daran, dass das lambdaMakro eine selbst zitierte lambdaSonderform zurückgibt, die der Alias ​​nicht aufnimmt, aber hier könnte es mehr schwarze Magie geben. Beschwöre @Malabarba.
Dan