Боюсь, не совсем ответ, но несколько замечаний и больше вопросов.Мой первый ответ будет: используйте clojure.core/seque
.Производителю необходимо как-то сообщить конец последовательности, чтобы потребитель знал, когда остановиться, и я предполагаю, что количество произведенных элементов заранее неизвестно.Почему вы не можете использовать маркер EOS (если это то, что вы подразумеваете под отравлением очереди)?
Если я правильно понимаю вашу альтернативную реализацию seque
, она сломается, когда элементы будут удалены из очереди за пределами вашей функции, поскольку channel
и q
в этом случае будут не в шаге: канал будет содержать больше элементов #(.take q)
, чем элементов в q
, что приведет к его блокировке.Могут быть способы обеспечения того, чтобы channel
и q
всегда были в шаге, но это, вероятно, потребовало бы реализации вашего собственного класса Queue
, и это добавляет столько сложности, что я сомневаюсь, что оно того стоит.Кроме того, ваша реализация не делает различий между нормальным EOS и ненормальным завершением очереди из-за прерывания потока - в зависимости от того, что вы используете, вы можете узнать, что есть что.Лично мне не нравится использовать исключения таким способом - использовать исключения для исключительных ситуаций, а не для нормального управления потоком.