2011-02-03 13 views
12

Biorąc pod uwagę PersistentQueue w Ref:Jaki jest idiomatyczny sposób na wyrzucenie PersistentQueue w ref?

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

Jaki jest idiomatyczne sposób pop kolejkę i uzyskać wynik?

Moja najlepsza próba dla krytyki:

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

Alter zwraca wartość w transakcję z kolejki, która jest już pojawiło, więc nie można po prostu zrobić alter sama.

+0

Idiomatyczny do dodania do kolejki będzie: (dosync (alter pq conj new-item)) –

Odpowiedz

5

Nie mogę wymyślić czegoś bardziej idiomatycznego, niż pozbawienie ciała twojego odmieńca.

Jednak jeśli jesteś w drodze, możesz wypróbować jeden raz hack: zawsze uważaj głowę PQ jako śmiecie (zawiera poprzednio popped item). Wynika z tego, że można przerobić qpop:

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

to ponosi dodając specjalne kontrole na pustkę (w szczególności, gdy Conj). Oznacza to również utrzymywanie odniesienia do przedmiotu na dłużej, niż powinno (jednak jeśli spojrzysz na implikację PQ, zobaczysz, że przez to może zbyt długo utrzymywać odniesienia do popped items, więc życie jest już mętne).

Użyłem tego hacka here.

+0

Jesteś przerażającym kolesiem. [Mam na myśli to jako komplement. :)] –

1

Twój organizm dozymetru może zostać uproszczony za pomocą makra Common Lisp prog1, chociaż wydaje się, że Core Clojure go nie ma. Istnieje prosta implementacja on the Google group wraz z dyskusją na temat tego, w jaki sposób można ją wykonać (zamiast makra) w Clojure.

+0

dzięki, dobra wskazówka. –

Powiązane problemy