Philippe Sigaud wrote:

    Andrei Alexandrescu wrote:

     > I'm trying to find justifications for keeping assumeSorted and
    friends
     > within Phobos. Background: assumeSorted(r) where r is some range
    returns
     > a value that wraps r and clarifies to the caller that it can assume r
     > has been sorted.

     > advantageous for sorted ranges. Question is: what are those? What
    kind
     > of cool primitives could a sorted range define?
     >
     > Here are a few I can think of:
     >
     > find -> uses binary search if random-access, or at least early
    stopping
     > otherwise.
     >
     > minElement -> r.front
     >
     > maxElement -> r.back
     >
     > topN -> essentially does nothing
     >
     > median -> r[r.length / 2]


It's not exactly what you're asking for, but my first thought was: "propagation". When you have a sorted range, it's rich, it's something you worked for to get. You don't want to waste it. So higher-order ranges and some other functions should take care to propagate the information.

* slicing a sorted range should produce a sorted range. so your wrapper range opIndex must be modified to account for this.

Cool, makes sense.

* ditto for .save()

Yah.

* Take(sortedRange, 5) should indicate it's also sorted.

Fortunately take already returns the type of the slice if the range supports slice, so that's in place already.

* The same for retro(sorted), but with a predicate being Not!pred (or something akin to this anyway)

Whoa, interesting.

* filter ! predicate (sortedRange) is also sorted
* stride
etc, etc.

Yah... that is all cool. My only reservations are that with what we have right now this looks like a lot of manual special casing. By the way, chain() with ranges sorted with the same predicate is also sorted...

Then, such an effort would be much better motivated if sorted ranges had some really interesting properties. Aside from those discussed - there's not a lot of them!

     > Such functions could have free counterparts in std.algorithm. The
    free
     > functions check whether the range already implements the fast
    functions
     > and uses them transparently if present. So then we have e.g. find()
     > which works in linear time for most ranges, but logarithmic time on
     > random-access sorted ranges.
     >



* Warning, daydreaming ahead *

As a side note, I'm playing with a Graph struct. And (generic) trees are just graphs, statically speaking. I can encode trees as graphs. The only difference is at runtime: no loop, one ancestor per node, etc. So, it's a bit like the standard range/sorted range problem: in general, being sorted is a runtime property. Being able to define this at the type level is quite interesting and that's what your assumeSorted does.


But, in general, it would be nice to have a way to add flags/properties as side-cars to an input type.
something like:

struct WithProperty(Original, alias property)
{
     Original _original;
/+ insert here some alias this-like magic to make WithProperty melt into an Original and expose _original most of the time +/ /+ expose property (SortedBy!pred, ConvergesTo!someValue, etc) with an alias.
}

Of course, it should be recursive: calling WithProperty on a WithProperty!(SomeType, OtherProperties) should add the new property to a CT-list, maybe a type-tuple. And there should be a way to disable some properties. As I said before, filter ! pred (some sorted range) is sorted, so it should indicate it. But map ! fun (sorted range) is _not_ sorted in general, and should 'off' this particular property.

What you're doing is defining 'interfaces', a sort of CT duck-typing, and your constraints templates check for the presence or absence of those new functions. I now realize much of what I longed for could be encoded in this way.

* Convergence to a certain value => expose a .limit() primitive.
* every value in the range occupy a certain 'range', smaller than what allows ElementType!Range (constraining values between 0.0 and 1.0 for a double-producing range, for example) => expose minValue/maxValue methods.

OK, it's past midnight around here, tomorrow my daughters will want to jump in the Mediterranean for hours, again. I'll shut up and go to bed.

Sounds like fun - of both the hacking and family kind. Keep those ideas coming, this is very interesting and something terse and usable could come out of it.


Andrei

Reply via email to