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