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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.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 为什么这个函数返回nil?_Clojure - Fatal编程技术网

Clojure 为什么这个函数返回nil?

Clojure 为什么这个函数返回nil?,clojure,Clojure,我正在学习Clojure和函数式编程,为了练习,我正在研究4clojure问题 这个函数(我知道不是最好的方法)正在工作。 (反向交织)但是,函数正在重新调整nil (defn reverse_interleave [coll ss] (let [xx (dec ss)] (loop [coll (reverse coll) s xx _ss ss ret `()] (if (nil? (first coll)) (do (println :ret ret) ret)

我正在学习Clojure和函数式编程,为了练习,我正在研究4clojure问题

这个函数(我知道不是最好的方法)正在工作。 (反向交织)但是,函数正在重新调整nil

(defn reverse_interleave
  [coll ss]
  (let [xx (dec ss)]
    (loop [coll (reverse coll) s xx _ss ss ret `()]
      (if (nil? (first coll)) (do (println :ret ret) ret))
      (when-let [x (first coll)]
                        (recur 
                          (rest coll)
                          (if (zero? s) xx (dec s))
                          (if (or (= 1 _ss) (zero? _ss)) 0 (dec _ss))
                          (if (zero? _ss)
                            (map-indexed #(if (= % s) (cons x %2) %2) ret)
                            (cons (list x) ret))
                            ))
      )) ret)


(reverse_interleave (range 9) 3)

问题是。。。为什么?

这里必须记住,Clojure并不像大多数命令式语言那样真正执行语句。使用
do
可以计算多个表达式的副作用,然后返回最后一个表达式的值,并且像
let
fn
这样的几个结构包含隐式
do
。但除了最后一个表达式之外,任何表达式都不可能停止求值并说“我们完成了”,除非它抛出异常。因此,整个生产线

(if (nil? (first coll)) (do (println :ret ret) ret))
只能从它的副作用中看出。它将作为
ret
中的值或
nil
中的值进行计算,然后将其丢弃

然后我们在let时打开一个
。因为它是
when
的变体,如果满足条件,它将返回其主体的值,如果不满足条件,它将返回
nil
。正文是一条指令,用于
循环
到循环的开头,因此此循环只能在值
nil
中终止
自然的解决方法似乎是将
if
表单的最后一个paren移到
when let
之后,这样整个表单就是else案例的值。您的代码本身也无法为我编译,因为它在创建它的循环之外使用了名称
ret
,但随着它的消失,它似乎按照预期工作:

(defn reverse_interleave
  [coll ss]
  (let [xx (dec ss)]
    (loop [coll (reverse coll) s xx _ss ss ret `()]
      (if (nil? (first coll)) 
        (do (println :ret ret) ret)
        (when-let [x (first coll)]
          (recur 
           (rest coll)
           (if (zero? s) xx (dec s))
           (if (or (= 1 _ss) (zero? _ss)) 0 (dec _ss))
           (if (zero? _ss)
             (map-indexed #(if (= % s) (cons x %2) %2) ret)
             (cons (list x) ret))))))))

(reverse_interleave (range 9) 3)
;;returns ((0 3 6) (1 4 7) (2 5 8))

您在循环中定义了一个变量
ret
,但它不存在于循环之外。函数中的最后一个
ret
在循环之外,因此它不是同一个变量。当你评估你的代码时,你甚至会得到一个编译器的例外。klebervirgilio,你能稍微改进一下你的问题标题吗?仅仅是标题?