Clojure 使用seq/coll的元素作为调用/递归参数

Clojure 使用seq/coll的元素作为调用/递归参数,clojure,Clojure,我遇到这种情况: (fn produce [] '(val0 val1)) ;... (loop [ arg0 false arg1 false arg2 false] ;... ) 是否有某种解包函数/宏可以调用 (recur (unpack (produce)) :arg2) 在循环上下文中?我知道我可以做一些类似的事情 (recur (nth (produce) 0) (nth (produce) 1) :arg2) (loop [[arg0

我遇到这种情况:

(fn produce [] '(val0 val1))

;...

(loop [
    arg0 false
    arg1 false
    arg2 false] 

    ;...

)
是否有某种解包函数/宏可以调用

(recur (unpack (produce)) :arg2)
在循环上下文中?我知道我可以做一些类似的事情

(recur (nth (produce) 0) (nth (produce) 1) :arg2)
(loop [[arg0 arg1] (get-my-arg-list)] ...
但前一种解决方案肯定会更优雅


IIRC Common Lisp代码可以返回多个值,Clojure也可以吗?

也许在
循环中解构绑定本身会有所帮助

(loop [ [arg0 arg1] [false false] arg2 false] ...

允许您在循环体中使用
(重现(生成)arg2)
,将
product
返回的2元素序列解构并绑定到
arg0
arg1

循环中解构绑定本身是否有帮助

(loop [ [arg0 arg1] [false false] arg2 false] ...

允许您在循环体中使用
(重现(生成)arg2)
,将
product
返回的2元素序列解构并绑定到
arg0
arg1

一般来说,解构效果很好,可以实现您想要的功能。这样做的唯一问题是

(recur (nth (produce) 0) (nth (produce) 1) :arg2)
(loop [[arg0 arg1] (get-my-arg-list)] ...
当您调用
recur
时,必须将所有内容打包到一个列表中。因此,递归调用看起来像

(recur [new-arg0 new-arg1])
如果这是一个交易破坏者,您还可以定义一个匿名函数与
recur
一起使用,然后在第一次调用参数列表时使用
apply
解压参数列表,尽管这种技术总体上相当难看。例:

(apply (fn [arg0 arg1]
         ...
         (recur new-arg0 new-arg1))
       (get-my-arg-list))

一般来说,解构工作得很好,可以做你想做的事情。这样做的唯一问题是

(recur (nth (produce) 0) (nth (produce) 1) :arg2)
(loop [[arg0 arg1] (get-my-arg-list)] ...
当您调用
recur
时,必须将所有内容打包到一个列表中。因此,递归调用看起来像

(recur [new-arg0 new-arg1])
如果这是一个交易破坏者,您还可以定义一个匿名函数与
recur
一起使用,然后在第一次调用参数列表时使用
apply
解压参数列表,尽管这种技术总体上相当难看。例:

(apply (fn [arg0 arg1]
         ...
         (recur new-arg0 new-arg1))
       (get-my-arg-list))

我认为在Clojure中返回多个值的惯用方法是将它们包装在
向量中。但是没有与CL的
形式等价的东西,它允许调用方决定处理一个返回值或多个返回值。我认为在Clojure中返回多个值的惯用方法可能是将它们包装在
向量
中。但是没有与CL的
values
表单等价的东西,它允许调用者决定处理一个返回值或多个返回值。也许我遗漏了什么,但是
recur
似乎调用fn而不是循环…?确切地说。效果是一样的(您仍然可以得到尾部递归),但是因为您有一个完全成熟的函数对象,所以可以使用apply。这种技术总体上可能是一种净负面(循环通常要漂亮得多),但如果您想避免在列表中包装参数或自己解包初始列表,这将允许您这样做。也许我遗漏了一些东西,但是
recur
似乎调用fn而不是循环…?没错。效果是一样的(您仍然可以得到尾部递归),但是因为您有一个完全成熟的函数对象,所以可以使用apply。这种技术总体上可能是一种净负面(循环通常更漂亮),但如果您希望避免在列表中包装参数或自己解包初始列表,这将允许您这样做。