views:

747

answers:

2

I'd like to wrap java's PriorityQueue class in clojure for use in another part of my program. What I'm trying to figure out is if there is any way to do this in a lispy manner and make the priority queue immutable. Are there any good ways to do this, or am I just going to be better off using the PriorityQueue as a mutable data structure?

+6  A: 

I don't think there is a simple way to wrap a mutable data structure as an immutable one. Immutable data structures become efficient when the new version can share data with the old version in clever ways, and I can't really see how this can be done without access to the internals of PriorityQueue.

If you really want a persistent priority queue this thread might be interesting. Those seems to have linear-time inserts though, so if that is an issue maybe you have to look for another implementation.

Edit: On second thought, a simple implementation of a persistent priority queue is just to store the (prio, value)-pairs in a sorted set. Something like this:

(defn make-pqueue []
  (sorted-set))

(defn pqueue-add [pq x prio]
  (conj pq [prio x]))

(defn pqueue-peek [pq]
  (first pq))

(defn pqueue-pop [pq]
  (let [top (first pq)]
    (disj pq top)))

Of course, the code above is pretty limited (no multiple entries, for instance) but it illustrates the idea.

CAdaker
How does the sorted-set know to sort by prio in the (prio, value) pair?
Jason Baker
Clojure compares vectors lexicographically, so it will first sort by priority, and second by value.
CAdaker
Actually, looking at the source, only vectors of equal length are compared lexicographically. But that's not a problem in this case.
CAdaker
+5  A: 

You can't automagically make mutable class immutable. One can always call java class directly and mutate it.

To force immutability you can either implement it in clojure, or extend java class and throw exceptions in all mutable method implementations.

Dev er dev