Overhauling the notion of output range

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Mon Jul 12 12:18:17 PDT 2010


On 07/12/2010 01:47 PM, Steven Schveighoffer wrote:
> On Mon, 12 Jul 2010 13:49:50 -0400, Andrei Alexandrescu
> <SeeWebsiteForEmail at erdani.org> wrote:
>> Yes. The point is that with a delegate you must choose between
>> accepting E and E[]. Given the constraint, it's better for everyone to
>> accept E[] and let put() take care of the occasional E by doing the
>> wraparoo (&elem)[0..1].
>
> But given a delegate that takes a single element, there's no way to wrap
> it so it can be an output range. Yet such a delegate can easily be
> something that outputs something.

void delegate(int) perItem;
void ofCourseThereIsAWay(int[] items) {
     foreach (e; items) perItem(i);
}

> Indeed, a delegate that takes a string takes a single element, but
> because a string happens to be defined as a range of chars, it passes
> the test for output ranges.

Yah, that's a good point.

> I could loop on an array of strings of one character, and output that to
> a valid output range no problem. The only thing that solves this problem
> correctly is buffering.

I don't understand the point here.

> What if I have my own container types that are large chunks of data, but
> don't happen to define the input range primitives? Why should I be
> artificially prevented from using those as input to output ranges?

I don't understand this either.

> Really to me, you are saying, "I want your delegate to be efficient",
> but you defined something that is related to that in a small set of
> circumstances (when the arrays being passed in are large).

What I'm saying is, "If you know how to output one item you may as well 
output several, as I'm producing them in bulk".

> Here's a proposal for put/isOutputRange which would solve my problem and
> not have any for loops in it:
[snip]

I'm uncomfortable about allowing inefficiency by design if I can help 
it, but I guess the costs all depend on the costs of trafficking one item.

>>> I can tell you this for sure, because it's exactly what's in many
>>> dcollections classes.
>>>
>>> So what happens when you call put(r, e) for one of these output classes?
>>> Instead of just calling add(e), it calls (add((&e)[0..1])) which in turn
>>> goes through some needless loop, which then ends up calling add(e). I
>>> don't see why this is preferable.
>>
>> Ah, I see. There is a confusion. The array restriction is only for
>> delegates. For straight ranges, you should accept individual Es.
>
> Why the discrepency? A naive coder can define inefficient ranges just as
> well as he can define inefficient delegates.

That doesn't mean we shouldn't foster the mechanisms that reduce the 
chance of bad designs happening.


Andrei


More information about the Digitalmars-d mailing list