On Sunday, 4 November 2012 at 19:59:55 UTC, Mehrdad wrote:
The whole problem seems to me to be caused by one simple
problem in D:
value vs. reference semantics
If it was clear that the output of a range has value semantics,
then clearly, its copy would not be transient.
And if it was clear that the output has reference semantics,
then clearly, its copy could be modified internally.
So really, the problem is not with ranges.
It's with an inherent ambiguity in D -- can you assume arrays &
structs are values or no?
Not sure this is specific to D. Just because you pass something
by value doesn't mean somebody else can't modify what's
underneath.
C++ gets away with this with an obsessive ownership model. Copy
always trigger duplication of internals everytime anyting is ever
passed by value. In D, you have dup, to do it only when you
really need it.
-------
The problem IS with ranges: in C++, stream operations require an
output argument, defering to the caller to chose where the output
is written to, avoiding the problem. Ranges, just like iterators,
must return values.
Heck, D has it better than C++. If you want to use istream
iterators in C++ (say, to interface with an algorithm), you can't
chose char* as a re-useable output buffer. You HAVE to use
std:::string, always allocating.
In D, you at least have the choice of byLine and
byLine.map!"a.idup"().
Problem is the default choice is not the easiest to operate
with...