Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 不工作时使用take的匿名函数?_Clojure_Anonymous Function - Fatal编程技术网

Clojure 不工作时使用take的匿名函数?

Clojure 不工作时使用take的匿名函数?,clojure,anonymous-function,Clojure,Anonymous Function,一个简单的例子可以说明我的问题: First I define a simple variable: (def a '(["one" 1] ["two" 2] ["nine" 9])) ;; CASE 1: (This works correctly) (take-while #(< (second %) 5) a) Returns: (["one" 1] ["two" 2]) ;; CASE 2: (This does not seem to work correctly) ;; T

一个简单的例子可以说明我的问题:

First I define a simple variable:
(def a '(["one" 1] ["two" 2] ["nine" 9]))

;; CASE 1: (This works correctly)
(take-while #(< (second %) 5) a)
Returns: (["one" 1] ["two" 2])

;; CASE 2: (This does not seem to work correctly)
;; The only difference is the '>' instead of '<'
(take-while #(> (second %) 5) a)
Returns: ()
首先我定义一个简单变量:
(定义a’([“一”1][“二”2][“九”9]))
;; 案例1:(这是正确的)
(花点时间#(<(秒)5)a)
返回:([“一”1][“二”2])
;; 案例2:(这似乎无法正常工作)

;; 唯一的区别是“>”而不是“”
的参数顺序很重要,请尝试

(take-while #(> 5 (second %)) a)
;=> (["one" 1] ["two" 2])

(drop-while #(> 5 (second %)) a)
;=> (["nine" 9])

的参数顺序很重要,请尝试

(take-while #(> 5 (second %)) a)
;=> (["one" 1] ["two" 2])

(drop-while #(> 5 (second %)) a)
;=> (["nine" 9])

在第一次失败测试后停止时执行。因为第一个元素没有通过测试(不超过五个),所以它永远不会到达最后一个。如果您想要所有通过测试的元素,而不管它们在序列中出现在何处,请改用
过滤器。

在第一次失败测试后停止时执行。因为第一个元素没有通过测试(不超过五个),所以它永远不会到达最后一个。如果您想要所有通过测试的元素,无论它们在序列中出现在何处,请改用
过滤器

100%正确——事实上,我查看了(source take while),我可以看到尾部有一个(when…)构造,这意味着当pred为false时,递归停止。有趣的。。。我认为Clojure不支持尾部递归,那么为什么在递归编码时使用take呢?嗯…take while不是递归编码的。。。只是看起来是这样。如果仔细观察,您将看到
take的整个主体,而
被包装在
lazy seq
lazy seq
是一个用于构造惰性序列的宏。基本上,
lazy seq
的主体被延迟,直到需要它的值。因此,它在机器级别上不是真正的递归,但通过宏的惰性计算允许以递归的方式对其进行描述。@jbm:AFAIK
(lazy-seq(foo))
被扩展为类似于
(clojure.lang.LazySeq.(fn[](foo))
。由于主体存储为一个函数,当LazySeq被强制执行而不是立即执行时调用该函数,因此看起来不像真正的递归。我遗漏了什么吗?@jbm,您所指的本地清除与控制堆栈大小无关。相反,它只是意味着在执行函数的最后一次函数调用之前,调用函数的局部变量(至少是clojure中未捕获的局部变量)将被清除(即,清除)。这可防止在加工尾部时保留结构的头部等。但是,它允许释放堆内存,而不是堆栈内存。无论如何,
lazy seq
绝对是懒惰的。这就是为什么它被称为
lazy seq
。而
take-while
是通过
lazy-seq
@jbm实现的,是的,本地清除与堆栈有关。但它与堆栈大小无关。这就是我要说的——清除局部变量不会改变堆栈的大小,它只是在进行最后一次函数调用之前清除局部变量,以避免保留对堆上未使用对象的引用。如果您对此还有其他问题,我建议您打开一个新的问题,在这里可以自由讨论..100%正确--事实上,一旦我查看(source take while),我可以看到尾部有一个(when…)构造,这意味着当pred为false时,递归停止。有趣的。。。我认为Clojure不支持尾部递归,那么为什么在递归编码时使用take呢?嗯…take while不是递归编码的。。。只是看起来是这样。如果仔细观察,您将看到
take的整个主体,而
被包装在
lazy seq
lazy seq
是一个用于构造惰性序列的宏。基本上,
lazy seq
的主体被延迟,直到需要它的值。因此,它在机器级别上不是真正的递归,但通过宏的惰性计算允许以递归的方式对其进行描述。@jbm:AFAIK
(lazy-seq(foo))
被扩展为类似于
(clojure.lang.LazySeq.(fn[](foo))
。由于主体存储为一个函数,当LazySeq被强制执行而不是立即执行时调用该函数,因此看起来不像真正的递归。我遗漏了什么吗?@jbm,您所指的本地清除与控制堆栈大小无关。相反,它只是意味着在执行函数的最后一次函数调用之前,调用函数的局部变量(至少是clojure中未捕获的局部变量)将被清除(即,清除)。这可防止在加工尾部时保留结构的头部等。但是,它允许释放堆内存,而不是堆栈内存。无论如何,
lazy seq
绝对是懒惰的。这就是为什么它被称为
lazy seq
。而
take-while
是通过
lazy-seq
@jbm实现的,是的,本地清除与堆栈有关。但它与堆栈大小无关。这就是我要说的——清除局部变量不会改变堆栈的大小,它只是在进行最后一次函数调用之前清除局部变量,以避免保留对堆上未使用对象的引用。如果你对此还有其他问题,我建议你提出一个新问题,可以自由讨论。。