2014-10-30 3 views
8

Rich Hickey's Strange Loop transducers presentation сообщает, что в Clojure 1.6 реализованы две реализации map, одна для последовательностей в clojure.core и одна для каналов в core.async.Может ли core.async реализовать свои функции в терминах последовательностей?

enter image description here

Теперь мы знаем, что в 1,7 раза у нас есть датчики, для которых функция foldr (reduce) возвращается из функций высшего порядка, как map и filter когда задана функция, но не коллекцию.

Что я пытаюсь сформулировать и терпеть неудачу, почему core.async функции не могут вернуть последовательность или быть Seq-like. У меня такое ощущение, что «интерфейсы» (протоколы) разные, но я не вижу, как это сделать.

Несомненно, если вы снимаете первый элемент с канала, вы можете представить это как взятие первого элемента из последовательности?

Мой вопрос: Может ли core.async реализовать свои функции в терминах последовательностей?

ответ

7

Да, в некотором смысле они могли быть. Если вы игнорируете идут блоки (на данный момент давайте делать это), то есть на самом деле ничего плохого в чем-то вроде следующего:

(defn chan-seq [ch] 
    (when-some [v (<!! c)] 
    (cons v (lazy-seq (chan-seq ch))))) 

Но обратите внимание, здесь <!! вызов. Это называется «take blocking»: внутри этой функции есть некоторые обещания и блокировки, которые заставят текущий исполняемый поток останавливаться, пока на канале не будет доступно значение. Так что это сработает нормально, если вы не возражаете, если нить Java не сидит там, ничего не делая.

Идея блоков go заключается в том, чтобы сделать логические процессы намного дешевле; для этого блок go переписывает тело блока в последовательность обратных вызовов, которые прикреплены к каналу, так что внутренний вызов <! внутри блока go превращается в нечто вроде этого (take! c k), где k является обратным вызовом к остальная часть блока go.

Теперь, если у нас были настоящие продолжения или если JVM поддерживал легкие потоки, то да, мы могли бы объединить блоки-блоки и блокировки. Но в настоящее время это связано либо с перестройкой глубокого байткода (например, с проектом Pulsar/Quasar), либо с некоторой нестандартной функцией JVM. Обе эти опции были исключены при создании core.async в пользу гораздо более простого для реализации (и, надеюсь, гораздо проще рассуждать) локального преобразования блока.

 Смежные вопросы

  • Нет связанных вопросов^_^