(a) to provide some hopefully constructive feedback on p2ql, and
(b) because there were two aspects of the p2ql we had to work out for ourselves and if they're documented, we couldn't find them. :) I'm writing to confirm our understanding so that we can update the p2ql wiki page with these bits if that is necessary.
We liked p2ql because it separates the concerns of querying for IUs from what you do with the IUs after you've queried for them really cleanly. It also feels like a natural compliment to our existing API--by adding abstraction that makes common querying use cases simple.
We couldn't find anywhere in either the bug report nor on the Wiki that described how external Java objects are bound into p2ql. Here's my current understanding:
p2ql is a dynamically typed language in Smalltalk's tradition: It just has receivers and messages, but no data types per se.
p2ql is a strictly functional language. No assignments, but higher-order functions all over the place. Syntax reminds strongly of Scala. :-D
$0, $1, ..., $n refer to the Java objects passed in as query parameters.
An unqualified variable or function call refers to the IQueryable's collection.
e.g.: select(iu | ....) is the same as saying rootQueryable.select(iu | ...) if Java had proper higher-order functions.
If a message's receiver is an Iterable or an IQueryable, the message must be a higher-order function that iterates across the elements.
ie: if $0 is an ArrayList of IVersionedId, $0.exists(vi | vi.id == 'com.some.bundle') will iterate over $0's elements and return true iff "com.some.bundle" is the ID of an element inside the list.
Otherwise, dot notation calls getters on the receiver. e.g.: if $0 is an IVersionedId, $0.id is the same as writing param0.getId() in Java.