¿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í?


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

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.


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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.