Подтвердить что ты не робот

Каков идиоматический способ вывести PersistentQueue в ref?

С учетом PersistentQueue в ref:

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

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