Pytanie Jaki jest idiomatyczny sposób na umieszczenie PersistentQueue w ref?


Biorąc pod uwagę PersistentQueue w ref:

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

Jaki jest idiomatyczny sposób, aby otworzyć kolejkę i uzyskać wynik?

Moja najlepsza próba twojej krytyki:

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

alter zwraca wartość transakcji kolejki, która jest już pobita, więc nie możesz po prostu samodzielnie dokonać zmiany.


12
2018-02-03 19:52


pochodzenie


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


Odpowiedzi:


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

Jeśli jednak masz ochotę na sztuczkę, możesz spróbować hackowanie jeden po drugim: zawsze uważaj głowę PQ za śmieci (zawiera ona poprzednio popped item). Oznacza to, że możesz przepisać qpop:

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

Powoduje to dodanie specjalnych sprawdzeń dla pustki (w szczególności, gdy się ją przywołuje). 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 tutaj.


5
2018-02-04 12:37



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


Twoje ciało DYNYNC można uprościć za pomocą Common Lisp prog1 makro, choć wydaje się, że Core Clojure go nie ma. Istnieje prosta implementacja w grupie Googlewraz z dyskusją o tym, jak możesz uczynić z niej funkcję (zamiast makra) w Clojure.


1
2018-02-04 21:00



dzięki, dobra wskazówka. - Alex Miller