I guess everyone who has spent any time with Emacs Lisp, knows that the language is full of oddities and quirks. That’s often a source of frustration for people coming from other languages, but it’s part of Emacs’s charm. Even after 15 years with Emacs and working on numerous Emacs packages, I still find things that manage to surprise me in Emacs Lisp. Consider the following:

(functionp (lambda (x) "I don't do much")) ;; => t
(functionp '(1 2 3)) ;; => nil

(listp (lambda (x) "I don't do much")) ;; => t
(listp '(1 2 3)) ;; => t

Turns out lambdas are both functions and lists! Weird, right?

I learned this yesterday, when someone reported a bug in Projectile triggered by the following code:

(if (listp marker)
    (and (projectile-verify-files marker) project-type)
  (and (funcall marker) project-type))

marker could be both a function or a list and this if covers both cases. It works fine if marker is something defined with defun, but blows up for lambdas, as listp returns t for them. The solution to the bug was pretty simple:

(if (functionp marker)
    (and (funcall marker) project-type)
  (and (projectile-verify-files marker) project-type))

I guess that’s the lesson from today’s post - if something can be both a lambda and list, you definitely want to have the functionp check first.

That’s all I have for you today. Keep hacking!

P.S. Feel free to share your favourite weird things about Emacs Lisp in the comments!