Paul Graham 的 On Lisp(以及 Ansi Common Lisp)中的 Compose 函数

Compose function in Paul Graham's On Lisp ( and also in Ansi Common Lisp)

在 Paul Graham 的书中,On Lisp,第 66 页,我们有这个函数:

(defun compose (&rest fns)
  (if fns
      (let ((fn1 (car (last fns)))
            (fns (butlast fns)))
        #'(lambda (&rest args)
            (reduce #'funcall fns
                    :from-end t
                    :initial-value (apply fn1 args))))
      #'identity))

[这个函数是这样写的,在Paul Graham的书中,Ansi Common Lisp, page 110] :

(defun compose (&rest fns)
  (destructuring-bind (fn1 . rest) (reverse fns)
     (lambda (&rest args)
       (reduce #'(lambda (v f) (funcall f v))
               rest
               :initial-value (apply fn1 args)))))

例如:

CL-USER> (funcall (compose #'1+ #'find-if) #'oddp '(2 3 4))
4

我知道已经有人问过有关此功能的问题,并且有很多答案 已经提供: (compose) in Common Lisp
Compose example in Paul Graham's ANSI Common Lisp

但是总有一点我不太清楚。 我知道:

fn1 <# <FUNCTION FIND-IF>
fns <(# <FUNCTION 1+>)>  
args <(#<FUNCTION ODDP> (2 3 4))> 

但是,我不明白指令是如何工作的:

(apply fn1 args)

我认为通过单独测试,将fn1替换为#'find-if,将args替换为(#'oddp (2 3 4)):

(apply #'find-if #'oddp '(2 3 4))  
or
(apply #'find-if (#'oddp (2 3 4)))  

它会起作用,但它不起作用:

CL-USER> (apply #'find-if #'oddp '(2 3 4))
; Evaluation aborted on #<UNKNOWN-KEYWORD-ARGUMENT {10036BBD03}>.

CL-USER> (apply #'find-if (#'oddp (2 3 4)))
; Evaluation aborted on #<SB-INT:COMPILED-PROGRAM-ERROR {1003DE6413}>.

CL-USER> (apply #'find-if '(#'oddp (2 3 4)))
; Evaluation aborted on #<TYPE-ERROR expected-type: (OR FUNCTION SYMBOL) datum: #'ODDP>.

有人可以向我解释一下这条指令是如何工作的吗? 提前感谢您的宽容和回复。

假设您要创建一个包含三项的列表:一个函数对象和两个数字。使用

(list #'+ 1 2)

不要使用:

(#'+ 1 2)     ; that's not valid Common Lisp code. The
              ;  first element of a Lisp form can't be a function object.
              ;  It's violating the basic evaluation rules
              ;  of Common Lisp.

'(#'+ 1 2)    ; This does not evaluate the list. Quoting makes it
              ;  a constant literal list. The elements of the list
              ;  won't be evaluated.
              ; Thus the first item is not a function object,
              ; but the list (function +)

定义:

Lisp 形式:要评估的有效代码