Boost logo

Boost :

Subject: Re: [boost] Formal Review: Boost.RangeEx
From: Rogier van Dalen (rogiervd_at_[hidden])
Date: 2009-03-02 11:35:08


Dear Dave,

Do I correctly understand your opinion can be summarised as "for linear
structures operator| is clearest; for complicated trees, function
syntax; and combinations, a combination"?

On Mon, 2009-03-02 at 10:01 -0500, David Abrahams wrote:
> on Fri Feb 27 2009, Rogier van Dalen <rogiervd-AT-gmail.com> wrote:
>
> > To me, RangeEx provides functions that take a range and return a range.
> > How is it not most natural to make these functions look like
> > functions?
>
> Every bit of runtime functionality is most naturally-expressed as a
> function call, according to some people. Those people end up writing
> code with lots and lots of parentheses, and they cite this uniformity as
> a source of expressiveness. Personally, I don't get it. If there's a
> more evocative syntax, we should consider using it.

You give a convincing argument. But is this different from ranges than
for any expression? Taking the n-th power of a complicated expression is
        pow((... complicated expression ...), n)
but might be more clearly expressed as
        (... complicated expression ...) #pow# n
Shouldn't this go into a more general library? Shouldn't RangeEx by
default offer the well-known syntax of function calls? (Even though I
agree that also providing operator| is sensible, and not very hard at
all.)

> What we're doing with RangeEx (in general) only expresses a degenerate
> tree structure (i.e. a linear structure):

Is that true? I've used RangeEx-like facilities (that I wrote) mostly
for more complicated trees, such as set operations.

> > What is wrong with saying "uniqued(rng)"? Why is it vital that the name
> > has "make_ _range" to remind me that this returns a lazy range rather
> > than a range?
>
> I don't think "make_ _range" does anything to indicate laziness.

Sorry, I was trying (and clearly failed) to ask a Socratic question
(echoing Neil's "I like the make_XXX_range because I instantly recognise
that this creates a range adaptor"). We agree here.

> > Currently merge(), transform(), and the set algorithms use output
> > iterators as a substitute for return values. Rephrasing them as
> > functions would also get rid of output iterators, which would improve
> > their interface.
>
> While value semantics are wonderful, I have doubts that everything that
> operates on output iterators can be effectively reformulated to return a
> range without limiting expressiveness and efficiency.

Re efficiency, it would make sense to have
        copy (lazy_operation (rng), output_it)
forward to the standard library operation. Re expressiveness, I am not
sure what you mean. The output iterator versions of the operations I
mention can be mimicked with "copy".

I do know that I find that "merge()" returning ranges
        copy (merge (rng1, rng2) | transform (f), output_it);
gives expressiveness than the implementation of the same using the
standard library, which requires storing the intermediate values. To be
fair, I have never compared performance, but I don't think the lazy
range version is obviously slower.

But maybe by "everything" you mean all possible operations, not just
those currently in the standard library. In that case I'm sure you're
right, but I don't see how that would make it undesirable to eliminate
output iterators where possible, especially in a library that's bound to
be used a lot.

Cheers,
Rogier


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk