Bill Clementson's Blog

Bits and pieces (mostly Lisp-related) that I collect from the ether.

May 2004
Sun Mon Tue Wed Thu Fri Sat
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
Apr  Jun

Funcallable Macros

Thursday, May 27, 2004

Ever want to funcall or map using a macro? Although there are some good reasons for not doing this (see this thread for some of them), Lars Brinkhoff posted some code (actually 2 different versions) that shows how one could. Cute.

;;; Lisp apprentice's wet dream: funcallable macros.
;;; Probable newbie usage example: (funcallable-macro 'and)
;;;                                (reduce #`and '(t t t nil t t))
;;; Two implementations are provided: one trivial using eval, and one
;;; that memoizes compiled functions.
;;; #1 Trivial version using eval. (defun funcallable-macro (name) (lambda (&rest args) (eval (cons name args))))
;;; #2 Version that memoizes compiled functions. (defun funcallable-macro (name) (let ((table (make-hash-table :test #'eql))) (lambda (&rest args) (let ((n (length args))) (apply (or (gethash n table) (setf (gethash n table) (make-funcallable-macro-function name n))) args)))))
(defun make-funcallable-macro-function (name n) (let ((args nil)) (dotimes (i n) (push (gensym) args)) (compile nil `(lambda ,args (,name ,@args)))))
;;; Do this for either version that is used. (set-dispatch-macro-character ## #` (lambda (s c n) `(funcallable-macro ',(read s t nil t))))

emacs Copyright © 2004 by Bill Clementson