2011-02-03 18 views
12

dado un PersistentQueue en una ref:¿Cuál es la forma idiomática de mostrar un PersistentQueue en una referencia?

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

Cuál es la forma idiomática para hacer estallar la cola y obtener el resultado?

Mi mejor intento para su crítica:

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

vuelve alterar el valor de transacción de la cola de la que se extrae ya, así que no se puede simplemente hacer el altar por sí mismo.

+0

Idiomatic para agregar a la cola sería: (dosync (alter pq conj new-item)) –

Respuesta

5

No puedo pensar en algo más idiomático que no sea abstraer el cuerpo de su dosync.

Sin embargo, si te encuentras en un truco, puedes probar el truco off-by-one: siempre considera el encabezado del PQ como basura (contiene el ítem previamente reventado). De ello se desprende que se puede reescribir qpop:

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

que incurre la adición de controles especiales para el vacío (en particular cuando conj). También significa mantener una referencia al elemento por más tiempo de lo que debería (sin embargo, si observas la implícita de PQ, verás que por sí misma puede mantener las referencias a los elementos reventados durante demasiado tiempo, por lo que la vida ya es turbia).

Utilicé este truco here.

+0

Eres un tipo asustadizo cgrand. [Lo decía como un cumplido. :)] –

1

Su cuerpo dosync podría simplificarse utilizando la macro prog1 de Common Lisp, aunque el núcleo Clojure parece carecer de ella. Existe una implementación directa on the Google group, junto con algunas discusiones sobre cómo puede hacer que funcione (en lugar de una macro) en Clojure.

+0

gracias, buen consejo. –

Cuestiones relacionadas