output ranges: by ref or by value?

Philippe Sigaud philippe.sigaud at gmail.com
Thu Dec 31 23:02:53 PST 2009


On Thu, Dec 31, 2009 at 16:47, Michel Fortin <michel.fortin at michelf.com>wrote:

> On 2009-12-31 09:58:06 -0500, Andrei Alexandrescu <
> SeeWebsiteForEmail at erdani.org> said:
>
>  The question of this post is the following: should output ranges be passed
>> by value or by reference? ArrayAppender uses an extra indirection to work
>> properly when passed by value. But if we want to model built-in arrays'
>> operator ~=, we'd need to request that all output ranges be passed by
>> reference.
>>
>
> I think modeling built-in arrays is the way to go as it makes less things
> to learn. In fact, it makes it easier to learn ranges because you can begin
> by learning arrays, then transpose this knowledge to ranges which are more
> abstract and harder to grasp.
>

I agree. And arrays may well be the most used range anyway.

Beside, an extra indirection is wasteful when you don't need it. It's easier
> to add a new layer of indirection when you need one than the reverse, so the
> primitive shouldn't require any indirection.


So (squint through sleep-deprived eyes:) that makes it by ref, right?



>  // pseudo-method
>> void put(R, E)(ref R tgt, E e) {
>>    tgt.front = e;
>>    tgt.popFront();
>> }
>>
>
A few random comments, sorry if they are not entirely coherent:

- this new put needs hasAssignableElements!R, right? What's in this case the
difference between isOutputRange!R and hasAssignableElements!R?

- should all higher-order ranges expose a put method if possible? (stride
comes to mind, but also take or filter).

- does that play nice with the new auto ref / ref template parameter from
2.038? It seems to me that this new feature will go hand in hand with this,
but I may be mistaken.

- your shim method will be used like this:

put(r,e);

whereas for an output range you use:

r.put(e);

and you cannot freely go from one form to the other, except for arrays,
which are output ranges anyway [*]. Does that mean that you must disseminate
static if ByRef/Assignable/Output/Whatever checks everywhere, to use either
put(r,e) or r.put(e)?

- what if R is a range of ranges (ie: if E is itself a range). Should put by
invoked recursively? What if its a chunked range?

- something I wanted to ask for a long time: does put really write to the
range as written in the docs or to the underlying container for which the
output range is but a 'writable' view? The container/range separation does
not exist for arrays, but is important for other cases.


  Philippe

[*] except if this transformation rule is implemented now?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20100101/c3902c57/attachment.html>


More information about the Digitalmars-d mailing list