Каков идиоматический способ добавить PersistentQueue в ссылку? - PullRequest
12 голосов
/ 03 февраля 2011

Учитывая PersistentQueue в ссылке:

(def pq (ref clojure.lang.PersistentQueue/EMPTY))

Какой идиоматический способ выскочить в очередь и получить результат?

Моя лучшая попытка вашей критики:

(defn qpop [queue-ref]
    (dosync 
        (let [item (peek @queue-ref)]
          (alter queue-ref pop)
          item))

alter возвращает значение в очереди транзакции, которая уже извлечена, поэтому вы не можете просто выполнить alter самостоятельно.

Ответы [ 2 ]

5 голосов
/ 04 февраля 2011

Я не могу придумать что-то более идиоматическое, если не считать абстрагирование тела от вашего досинкинга.

Однако, если вас ждет трюк, вы можете попробовать взломать один за другим : всегда рассматривайте голову PQ как мусор (он содержит ранее извлеченный элемент). Отсюда следует, что вы можете переписать qpop:

(defn qpop [queue-ref]
  (peek (alter queue-ref pop))

Это предполагает добавление специальных проверок на пустоту (в частности, когда вы соединяетесь). Это также означает, что ссылка на элемент должна храниться дольше, чем следовало бы (однако, если вы посмотрите на значение PQ, вы увидите, что при этом он может слишком долго хранить ссылки на всплывающие элементы, так что живость уже мутная).

Я использовал этот хак здесь .

1 голос
/ 05 февраля 2011

Ваше тело dosync можно упростить с помощью макроса prog1 Common Lisp, хотя ядру Clojure, похоже, его не хватает. Существует простая реализация в группе Google , а также некоторые обсуждения того, как сделать ее функцией (вместо макроса) в Clojure.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...