Anonymous function macro in elisp

Clojure has anonymous functions with the reader macro #(

(#(print %2 %1) "there" "hi")
#+END_SRCa

Emacs Lisp doesn't have reader macros, but we can take direction from Hylang, a
lisp dialect similar to Clojure inter-oping with Python.

It implements the anonymous functions as the aptly named ~xi~ macro, where the
lambda has arguments determined by presence of ~x1 ... xi~ .

#+BEGIN_SRC lisp
((xi print x2 x1) "there" "hi")

We can implement the xi macro in Emacs Lisp roughly as:

(require 'dash)
(require 's)

(defmacro xi (&rest FORMS)
  `(lambda ,(--filter (s-contains? (symbol-name it)
                                   (prin1-to-string FORMS))
                      '(x1 x2 x3 x4 x5))
     ,FORMS))

This enables:

(funcall (xi print (concat x2 x1)) "there" "hi")
;; expands to
(funcall (lambda (x1 x2) (print (concat x2 x1))) "there" "hi")

This implementation could be improved - the above example works with (xi x3 x1), it doesn't actually validate that the xi are contiguous. It also doesn't cover all numbers of arguments, though over 5 arguments would be questionable anyway. Lastly it does not distinguish xis as part of say strings.

This macro is especially useful for lambdas without arguments, like adding hooks and keybindings.

(add-hook 'eshell-exit-hook (lambda () (setq esh-prompt-num 0)))
;; Becomes
(add-hook 'eshell-exit-hook (xi setq esh-prompt-num 0))
comments powered by Disqus