Использование элементов seq / coll в качестве аргументов call / recur - PullRequest
1 голос
/ 15 февраля 2012

Я столкнулся с такой ситуацией:

(fn produce [] '(val0 val1))

;...

(loop [
    arg0 false
    arg1 false
    arg2 false] 

    ;...

)

Есть ли какая-нибудь функция / макрос распаковки, чтобы вы могли вызвать

(recur (unpack (produce)) :arg2)

в контексте цикла? Я знаю, что я мог бы просто сделать что-то вроде

(recur (nth (produce) 0) (nth (produce) 1) :arg2)

но наверняка первое решение будет более элегантным?

Код IIRC Common Lisp может возвращать более одного значения, может ли Clojure тоже?

Ответы [ 2 ]

4 голосов
/ 15 февраля 2012

Может быть, деструктуризация в самих привязках loop поможет?

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

позволяет вам (recur (produce) arg2) в теле цикла, при этом последовательность из 2 элементов, возвращаемая produce, деструктурирована и связана с arg0 и arg1.

1 голос
/ 16 февраля 2012

В общем, деструктура работает хорошо и будет делать то, что вы хотите. Одна проблема с чем-то вроде

(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))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...