milibopp / acacia

A spatial partitioning and tree library in Rust.
Mozilla Public License 2.0
83 stars 8 forks source link

Queries as iterators #13

Closed milibopp closed 9 years ago

milibopp commented 9 years ago

Having the Node abstraction it should be possible to design the query methods in a slightly different way:

trait DataQuery<D> {
    fn query_data<'a>(&'a self, recurse: |&Self| -> bool) -> SomeIterator<&'a D>;
}

This is nicer as the current interface, as it allows the user to chain this with iterator adaptors instead of using a mutable state captured from the environment.

However, the implementation is certainly somewhat trickier. For instance, it is a bit awkward to generalize over SomeIterator<_> without higher-kinded types (which Rust 1.0 will not include). This is also mentioned under limitations in the associated types RFC rust-lang/rfcs#195. A workaround could look like this:

trait QueryableOwned<A> {
    type I: Iterator<A>;
    fn query_owned(self) -> I;
}

trait DataQuery<D> {
    fn query_data<'a>(&'a self, recurse: |&Self| -> bool) -> <&'a Self>::I
        where &'a Self: QueryableOwned<&'a D>
    {
        QueryableOwned::query_owned(self)
    }
}

Now one would have to implement QueryableOwned<&'a D> for &'a T, so that T can implement DataQuery<D>. This is a bit complicated, so I am not sure whether it is worth the effort.

On the other hand it may be possible that DataQuery<D> can be implemented generically for all T: AssociatedData<D> + Node<..>. In this case it would almost be reduced to an implementation detail.

milibopp commented 9 years ago

Note, that this could be done similarly to how collections like Vec now interface with the for-loop.