fnlet

funcallを省略するためのマクロ。
実際には使わなそうだけど、一応残しておく。

(defmacro fnlet (letargs &body body)
  `(macrolet 
    ,(mapcar 
      (lambda (letarg)
        (destructuring-bind (fn-name fn)
                            (if (listp letarg)
                                letarg
                              `(,letarg ,letarg))
          `(,fn-name (&rest args)
             `(funcall ,',fn ,@args))))
      letargs)
    ,@body))

;;;;;;;;;;;;
;;;; 使用例
;; WikipediaのStandard MLの項目に載っていた数値微分の定義
(defun d (delta fn x)
  (fnlet (fn)       ; (fn ...) == (funcall fn ...)
    (/ (- (fn (+ x delta))
          (fn (- x delta)))
       (* 2 delta))))

(defun my-mapcar (fn list)
  (fnlet ((! fn))   ; (! ...) == (funcall fn ...)
    (if (endp list)
        '()
      (cons (!(car list)) (my-mapcar fn (cdr list))))))