Given some basic guidelines I would gladly add a PriorityQueue implementation to Javaslang.
I could base my implementation on http://www.brics.dk/RS/96/37/BRICS-RS-96-37.pdf.
Hi Pap, this is a great idea. I'm returning home from vacation and have currently only my mobile phone at hand. My thoughts:
Tomorrow I'm able to provide you with some more detailed information.
This will be fun :)
@paplorinc We add the PriorityQueue as interface to the existing type hierarchy:

A (FIFO) _Queue_ is a special _Priority Queue_ ("... the priority of each inserted element is monotonically decreasing", see wikipedia). Please note that a _Stack_ is also a special _Priority Queue_ but in Javaslang the _Stack_ is not a collection but a marker interface with a bunch of Stack operations, so Stack will not implement Priority Queue.
Before talking about implementation details there is still a question (and I already have a suggested answer):
The first approach (using an explicit priority) is not intuitive because we may easily add one element with different priorities. The priority on the one hand is bound to an element but on the other hand it is not derived from that element. If the priority is independent of the element attributes, it can be seen as arbitrary/random from our viewpoint.
The second approach (using an ordering) goes well along with Java's standard collection. It implemented a mutable Priority Queue using an underlying Comparator. A Comparator provides us with more options, we are able to create a Priority Queue using a rank/priority function priority: T -> int that induces a Comparator compare: T x T -> int:
compare(elem1, elem2) := priority(elem2) - priority(elem1)
Using Heaps is just one variant to implement Priority Queues. Let's take the approach you suggested. I think it is nice because it is relatively easy. The performance characteristics are ok and we are able to exchange the implementation later because Priority Queue will be an interface and we do not expose the implementation details to the outside.
The interface looks like this:
public interface PriorityQueue<T> extends LinearSeq<T> {
Tuple2<T, ? extends PriorityQueue<T>> dequeue();
Option<Tuple2<T, ? extends PriorityQueue<T>>> dequeueOption();
PriorityQueue<T> enqueue(T element);
PriorityQueue<T> enqueue(T... elements);
PriorityQueue<T> enqueueAll(Iterable<? extends T> elements);
T peek();
Option<T> peekOption();
// -- Adjusted return types of LinearSeq methods
...
}
Note: The _adjusted return types_ mentioned above mean that methods inherited from LinearSeq that return LinearSeq need (in 99,99% of all cases) to be overridden with PriorityQueue as return type.
Accordingly we need to change class Queue:
// before
public class Queue<T> implements Kind1<Queue<?>, T>, LinearSeq<T>, Serializable {
...
}
// after
public class Queue<T> implements Kind1<Queue<?>, T>, PriorityQueue<T>, Serializable {
...
}
Above we see two disadvantages of letting Queue inherit PriorityQueue:
? extends PriorityQueue<T> because of Java's lack of (declaration site) variance. This is somewhat distracting API.PriorityQueue<T> cannot extend Kind1<PriorityQueue<?>, T> because it would be a conflict to Queue<T> implements Kind1<Queue<?>, T>. This is a minor issue because Kind* is only relevant for the javaslang-pure module.The second point can be ignored for now. The first point might be fixed by leaving PriorityQueue as standalone type that is not implemented by Queue.
@all Any opinions on that? I've experimented with Set and Map return types and think that it is ok to work with ? extends ... return types (no casts were needed).
I slept one night over the type-hierarchy topic. In the comment above I suggested the following:
Queue -> PriorityQueue -> LinearSeq -> Seq -> ...
where Queue is a class and PriorityQueue is an interface.
But Java has
PriorityQueue -> Queue -> ...
where Queue is an interface and PriorityQueue is a class.
At a first sight we might think that PriorityQueue -> Queue goes adhere with SortedSet -> Set. But that is not true because Set has no ordering opposed to SortedSet, so SortedSet is special in this manner.
Queue has a special ordering, so Queue -> PriorityQueue is the right way to do it. This goes well along with the fact that we do not have to change the current collection hierarchy existing collections.
Just wanted to clarify it a bit.
Awesome, will start working on it shortly :)
Great! I'm really looking forward to it :-) You can add your PR at an early stage and push your commits from time-to-time. I will guide you if there are any questions.
I've thought a little bit harder about the type hierarchy. The idea I sketched above is not the best solution. E.g. when having a method comparator() (similar to SortedSet.comparator()) our current Queue cannot implement it in a way that makes sense. There are also other examples where it makes no sense that Queue implements specific methods of PriorityQueue (like special map and flatMap methods that take a Comparator for the result type). So Queue cannot inherit PriorityQueue.
Just don't think too much about it, we start implementing the PriorityQueue as you suggested. It will directly inherit from LinearSeq for now.
Maybe we introduce later a common interface for Queue and PriorityQueue. The best name for that interface would be Queue. Our current class Queue needs then a different name but that is not possible because of backward compatibility. So we will introduce a 'hidden' (read: package private) interface (e.g. QueueLike) that may be renamed when releasing the next major Javaslang version (3.0). But that is not important for now. We concentrate on implementing the PriorityQueue.
@danieldietrich, could you please assign this to me?
I have translated most of the basic structure from the paper and the similarly cryptic Scalaz source -- I feel like a hacker who reverse engineered something that was not meant to be understood :p.
I will need to make it more Java-like, add some basic tests and will push a draft this week.
Once that's working, I will add the rest of the inherited methods. :)
@paplorinc That sounds great - looking forward to the review. I will assign you...
Update: Before I can assign you, you need to follow the invitation to the Javaslang team :)
Most helpful comment
Hi Pap, this is a great idea. I'm returning home from vacation and have currently only my mobile phone at hand. My thoughts:
Tomorrow I'm able to provide you with some more detailed information.
This will be fun :)