9

I have this in my .emacs:

(defalias 'λ 'lambda)

which works fine for simple things like (funcall (λ (x) x) 1).

But when I do something like (org-add-link-type "foo" (λ (s) (message s))) or (add-to-list 'auto-mode-alist '("foo" . (λ () (message "bar")))), it doesn't work and I get

org-open-at-point: Invalid function: (λ (s) (message s))

and

File mode specification error: (invalid-function (λ nil (message "bar")))

respectively.

Does anybody know what's wrong here?

3
  • 4
    Not an answer to the question about the defalias, but you might want to check out prettify-symbols-mode, which, among other things, will allow you to display lambda as λ without actually changing the underlying text.
    – Dan
    Dec 15, 2014 at 12:13
  • A simple library that prettifies only lambda (to λ): pretty-lambdada.el.
    – Drew
    Dec 15, 2014 at 15:48
  • If you just want pretty symbols then use github.com/akatov/pretty-mode
    – grettke
    Dec 16, 2014 at 4:25

2 Answers 2

12

With some help from lunaryorn on reddit, I guess I have been able to understand why you are observing the "wierd" behaviour.

The problem is that you are quoting the expression

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

Which is equivalent to the form

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

Now when emacs opens a file with extension "foo", it does something like the following

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

Notice the extra quote, before , this obviously is not valid function and you get the error Invalid function: ... But then why does ("foo" . (lambda () (message "bar"))) work, this is explained by lunaryorn's observation

A “lambda list”, i.e. a list whose car is lambda, is a valid function, too

So '(lambda () (message "bar")) is a valid function, this can be verified by the following code

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

So the solution would be to simply not quote the expression use the following instead

(add-to-list 'auto-mode-alist (cons "foo" (λ () (bar))))
1
  • Thanks for the thorough explanation! Everything's working fine now :)
    – rtrn
    Dec 15, 2014 at 18:01
3

It looks like the problem is not with the defalias, but rather where and how you're calling λ. funcall takes, as its arguments, a function and that function's arguments, so your funcall example works just fine.

Both org-add-link-type and the auto-mode-alist, however, expect symbols that contain the relevant functions. Hence, building off of your examples, the following should work:

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

If you're mostly looking to have λ show up in your buffer, consider trying out prettify-symbols-mode, which will display lambda as λ without changing th buffer's text.

2
  • The weird thing is that everything works fine when I use lambda directly.
    – rtrn
    Dec 15, 2014 at 12:57
  • @rtrn: ah, good point. I'm guessing it's because the lambda macro returns a self-quoted lambda special form which the alias isn't picking up, but there might be more black magic here. Summon @Malabarba.
    – Dan
    Dec 15, 2014 at 13:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.