¿Cómo defalias lambda?

8

Tengo esto en mis .emacs:

(defalias 'λ 'lambda)

que funciona bien para cosas simples como (funcall (λ (x) x) 1).

Pero cuando hago algo como (org-add-link-type "foo" (λ (s) (message s)))o (add-to-list 'auto-mode-alist '("foo" . (λ () (message "bar")))), no funciona y me sale

org-open-at-point: Función no válida: (λ (s) (mensaje s))

y

Error de especificación del modo de archivo: (función no válida (λ nil (mensaje "bar")))

respectivamente.

¿Alguien sabe lo que está mal aquí?

rtrn
fuente
44
No es una respuesta a la pregunta sobre el defalias, pero es posible que desee consultar prettify-symbols-mode, que, entre otras cosas, le permitirá mostrar lambdacomo λsin cambiar realmente el texto subyacente.
Dan
Un simple biblioteca que prettifies única lambda (a λ): pretty-lambdada.el.
Dibujó
Si solo quieres símbolos bonitos, usa github.com/akatov/pretty-mode
grettke

Respuestas:

11

Con algo de ayuda de lunaryorn en reddit , creo que he podido entender por qué estás observando el comportamiento "extraño".

El problema es que estás citando la expresión

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

Que es equivalente a la forma

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

Ahora, cuando emacs abre un archivo con la extensión "foo", hace algo como lo siguiente

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

Observe la cita adicional, antes , obviamente esta función no es válida y obtiene el error Invalid function: ... Pero entonces, ¿por qué ("foo" . (lambda () (message "bar")))funciona? Esto se explica por la observación de lunaryorn

Una "lista lambda", es decir, una lista cuyo automóvil es lambda, también es una función válida

Por '(lambda () (message "bar"))lo tanto, es una función válida, esto se puede verificar con el siguiente código

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

Entonces, la solución sería simplemente no citar la expresión, use lo siguiente

(add-to-list 'auto-mode-alist (cons "foo" (λ () (bar))))
Iqbal Ansari
fuente
Gracias por la explicación detallada! Trabajar muy bien de todo lo que ahora :)
RTRN
3

Parece que el problema no es con el defalias, sino más bien dónde y cómo estás llamando λ. funcalltoma, como sus argumentos, una función y los argumentos de esa función, por lo que su funcallejemplo funciona bien.

Ambos org-add-link-typey auto-mode-alist, sin embargo, esperan símbolos que contienen las funciones relevantes. Por lo tanto, a partir de sus ejemplos, lo siguiente debería funcionar:

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

Si usted está buscando sobre todo para tener λmostrará en su memoria intermedia, considere la posibilidad de probar prettify-symbols-mode, que mostrará lambdacomo λsin cambiar el texto del búfer XX.

Dan
fuente
Lo extraño es que todo funciona bien cuando lo uso lambdadirectamente.
rtrn
@rtrn: ah, buen punto. Supongo que es porque la lambdamacro devuelve una lambdaforma especial auto-citada que el alias no está captando, pero puede haber más magia negra aquí. Invocar a @Malabarba.
Dan