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?

rtrn
  • 93
  • 4
  • 4
    Not an answer to the question about the `defalias`, but you might want to check out [`prettify-symbols-mode`](http://ergoemacs.org/emacs/emacs_pretty_lambda.html), which, among other things, will allow you to display `lambda` as `λ` without actually changing the underlying text. – Dan Dec 15 '14 at 12:13
  • A simple library that prettifies *only* `lambda` (to `λ`): [`pretty-lambdada.el`](http://www.emacswiki.org/emacs-en/download/pretty-lambdada.el). – Drew Dec 15 '14 at 15:48
  • If you just want pretty symbols then use https://github.com/akatov/pretty-mode – grettke Dec 16 '14 at 04:25

2 Answers2

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))))
Iqbal Ansari
  • 7,468
  • 1
  • 28
  • 31
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.

Dan
  • 32,584
  • 6
  • 98
  • 168
  • The weird thing is that everything works fine when I use `lambda` directly. – rtrn Dec 15 '14 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 '14 at 13:09