Come defalias lambda?


8

Ho questo nel mio .emacs:

(defalias 'λ 'lambda)

che funziona bene per cose semplici come (funcall (λ (x) x) 1).

Ma quando faccio qualcosa come (org-add-link-type "foo" (λ (s) (message s)))o (add-to-list 'auto-mode-alist '("foo" . (λ () (message "bar")))), non funziona e ottengo

org-open-at-point: funzione non valida: (λ (s) (messaggi))

e

Errore specifica modalità file: (funzione non valida (λ nil (messaggio "bar")))

rispettivamente.

Qualcuno sa cosa c'è che non va qui?


4
Non è una risposta alla domanda sul defalias, ma potresti voler dare un'occhiata prettify-symbols-mode, che, tra le altre cose, ti consentirà di visualizzarlo lambdacome λsenza realmente cambiare il testo sottostante.
Dan

Una semplice libreria che prettifies solo lambda (a λ): pretty-lambdada.el.
Estratto il

Se vuoi solo simboli carini, usa github.com/akatov/pretty-mode
grettke,

Risposte:


11

Con l'aiuto di lunaryorn su reddit , credo di essere stato in grado di capire perché stai osservando il comportamento "strano".

Il problema è che stai citando l'espressione

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

Che equivale al modulo

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

Ora quando emacs apre un file con estensione "pippo", fa qualcosa di simile al seguente

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

Nota la citazione aggiuntiva, prima , ovviamente questa non è una funzione valida e ottieni l'errore Invalid function: ... Ma allora perché ("foo" . (lambda () (message "bar")))funziona, questo è spiegato dall'osservazione del lunaryorn

Una "lista lambda", cioè una lista la cui macchina è lambda, è anche una funzione valida

Quindi '(lambda () (message "bar"))è una funzione valida, questa può essere verificata dal seguente codice

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

Quindi la soluzione sarebbe semplicemente non citare l'espressione usando invece quanto segue

(add-to-list 'auto-mode-alist (cons "foo" (λ () (bar))))

Grazie per la spiegazione approfondita! Ora funziona tutto bene :)
rtrn

3

Sembra che il problema non sia con defalias, ma piuttosto dove e come stai chiamando λ. funcallaccetta, come i suoi argomenti, una funzione e gli argomenti di quella funzione, quindi il tuo funcallesempio funziona bene.

Entrambi org-add-link-typee auto-mode-alist, tuttavia, prevedono simboli che contengono le funzioni pertinenti. Quindi, basandoti sui tuoi esempi, dovrebbe funzionare quanto segue:

(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))

Se stai cercando principalmente di λmostrarti nel tuo buffer, prova a provarlo prettify-symbols-mode, che verrà visualizzato lambdacome λsenza cambiare il testo del buffer.


La cosa strana è che tutto funziona bene quando lo uso lambdadirettamente.
rtrn,

@rtrn: ah, buon punto. Immagino sia perché la lambdamacro restituisce una lambdaforma speciale auto-quotata che l'alias non sta raccogliendo, ma qui potrebbe esserci più magia nera. Evoca @Malabarba.
Dan
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.