在Paul Graham的ANSI Common Lisp中撰写示例 [英] Compose example in Paul Graham's ANSI Common Lisp
问题描述
任何人可以在Paul Graham的ANSI Common Lisp页面110中解释一个例子吗?
Can anybody explain an example in Paul Graham's ANSI Common Lisp page 110?
示例尝试解释使用& rest和lambda来创建函数式编程设施。其中一个是组成函数参数的函数。我找不到任何解释它是如何工作的。代码如下:
The example try to explain the use &rest and lambda to create functional programming facilities. One of them is a function to compose functional arguments. I cannot find anything explaining how it worked. The code is as follows:
(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)))))
用法是:
(mapcar (compose #'list #'round #'sqrt)
'(4 9 16 25))
输出为:
((2) (3) (4) (5))
魔法给我。任何评论将不胜感激。 compose
函数返回一个
Line 2 and 6 look especially like magic to me. Any comments will be appreciated.
推荐答案
//en.wikipedia.org/wiki/Closure_%28computer_science%29rel =nofollow> closure 从最后一次调用每个函数,将每个函数调用的结果传递给下一个函数。
The compose
function returns a closure that calls each of the functions from last to first, passing on the result of each function call to the next.
调用(compose#'list#'round#'sqrt)
产生的闭包首先计算平方根的参数,将结果四舍五入到最接近的整数,然后创建一个结果列表。使用say 3作为参数调用闭包等效于计算(list(round(sqrt 3)))
。
The closure resulting from calling (compose #'list #'round #'sqrt)
first calculates the square root of its argument, rounds the result to the nearest integer, then creates a list of the result. Calling the closure with say 3 as argument is equivalent to evaluating (list (round (sqrt 3)))
.
destructuring-bind 评估(reverse fns)
表达式以获取 compose
,并将结果列表的第一个项目绑定到 fn1 局部变量,将其余的结果列表绑定到 rest 局部变量。因此, fn1 持有 fns ,#'sqrt
的最后一个项目。
The destructuring-bind evaluates the (reverse fns)
expression to get the arguments of compose
in reverse order, and binds its first item of the resulting list to the fn1 local variable and the rest of the resulting list to the rest local variable. Hence fn1 holds the last item of fns, #'sqrt
.
减少每次调用 fns code>函数与累加结果。
:initial-value(apply fn1 args)
为 reduce
函数提供初始值,多个参数。不需要多个参数, compose
可以简化为:
The reduce calls each the fns
functions with the accumulated result. The :initial-value (apply fn1 args)
provides the initial value to the reduce
function and supports calling the closure with multiple arguments. Without the requirement of multiple arguments, compose
can be simplified to:
(defun compose (&rest fns)
#'(lambda (arg)
(reduce #'(lambda (v f) (funcall f v))
(reverse fns)
:initial-value arg)))
这篇关于在Paul Graham的ANSI Common Lisp中撰写示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!