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



在Paul Graham的书《论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,第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(在Common Lisp中
在Paul Graham中编写示例';s ANSI通用Lisp

但总有一件事我不清楚。我知道:

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

然而,我不理解指令是如何工作的:

(apply fn1 args)

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

(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表单:要评估的有效代码

最新更新