July 09, 2012
On Monday, 9 July 2012 at 14:48:05 UTC, Andrei Alexandrescu wrote:
> I think it's about the notion of "input range" that is confusing, a better name would be "single-pass range". One should be perfectly capable of assigning to elements of an input range. A built-in slice is an input range.
>
> Andrei

Aren't output ranges single-pass too?
July 09, 2012
On 7/9/12 10:52 AM, Mehrdad wrote:
> On Monday, 9 July 2012 at 14:48:05 UTC, Andrei Alexandrescu wrote:
>> I think it's about the notion of "input range" that is confusing, a
>> better name would be "single-pass range". One should be perfectly
>> capable of assigning to elements of an input range. A built-in slice
>> is an input range.
>>
>> Andrei
>
> Aren't output ranges single-pass too?

They don't have much of a notion of "pass" because the only primitive of output ranges is "put".

Andrei
July 09, 2012
On Monday, 9 July 2012 at 15:16:52 UTC, Andrei Alexandrescu wrote:
> On 7/9/12 10:52 AM, Mehrdad wrote:
>> On Monday, 9 July 2012 at 14:48:05 UTC, Andrei Alexandrescu wrote:
>>> I think it's about the notion of "input range" that is confusing, a
>>> better name would be "single-pass range". One should be perfectly
>>> capable of assigning to elements of an input range. A built-in slice
>>> is an input range.
>>>
>>> Andrei
>>
>> Aren't output ranges single-pass too?
>
> They don't have much of a notion of "pass" because the only primitive of output ranges is "put".
>
> Andrei

Sorry? I don't know what you mean, but "single-pass" makes perfect sense to me for output ranges. Think: CD burning.



Anyway, what I'm saying is that if your code _only_ depends on the _input_ capabilities of a range, then it /cannot/ and _does not_ need the 'ref' capability.

You only need 'ref' for two reasons, so far as I can see:

- Writing
- Optimization

The latter point is moot here, and the former is _clearly_ not something an "input range" should have, because it's a notion of output...
July 09, 2012
On Monday, 9 July 2012 at 15:34:35 UTC, Mehrdad wrote:
> The latter point is moot here, and the former is _clearly_ not something an "input range" should have, because it's a notion of output...

Er, let me rephrase that:

The former is _clearly_ not a property of "input ranges".

If something is both an input range and an output range, then sure, it can have that capability. But being able to write to something is _orthogonal_ to whether you can read from it.
July 09, 2012
On Monday, 9 July 2012 at 15:34:35 UTC, Mehrdad wrote:
> Think: CD burning.

A good comparison:

Single-pass output ranges: an output range that writes to a CD, DVD, etc.
Multi-pass output ranges: an output range that writes to a tape, hard disk, etc.
July 09, 2012
On 7/9/12 11:35 AM, Mehrdad wrote:
> If something is both an input range and an output range, then sure, it
> can have that capability. But being able to write to something is
> _orthogonal_ to whether you can read from it.

That is the case right now. The point is, with your design you need to add something extra to allow writing to elements of a single-pass range. So your design does not simplify things as much as it might seem.

Andrei
July 09, 2012
On Monday, 9 July 2012 at 15:34:35 UTC, Mehrdad wrote:
> On Monday, 9 July 2012 at 15:16:52 UTC, Andrei Alexandrescu wrote:
>> the only primitive of output ranges is "put".
>>
>> Andrei
>
> Sorry? I don't know what you mean

template isOutputRange(R,E)

Returns true if R is an output range for elements of type E. An output range is defined functionally as a range that supports the operation

void put(R, E)(ref R r, E e);
July 09, 2012
On Monday, 9 July 2012 at 15:48:35 UTC, Andrei Alexandrescu wrote:
> On 7/9/12 11:35 AM, Mehrdad wrote:
>> If something is both an input range and an output range, then sure, it
>> can have that capability. But being able to write to something is
>> _orthogonal_ to whether you can read from it.
>
> That is the case right now. The point is, with your design you need to add something extra to allow writing to elements of a single-pass range. So your design does not simplify things as much as it might seem.
>
> Andrei

> With your design you need to add something extra to allow writing to elements of a single-pass range.

If that's the case, I'd hate to tell you this, but _unless_ you're planning on removing the notion of input/output ranges (and perhaps adding single-pass/multi-pass), you're doing it wrong. :-)

That capability is simply /not needed/ when your /only/ contract is that something is an input range.

Asking an input range, "hey, can I write to you?" is just... insulting!
That's like asking an electrical engineer if he can plumb.

Sure, it might come in handy if he can, but it's just plain silly to ask himi that. If you need someone who can do both, then ask for someone who's an EE _and_ a plumber.

On the other hand, the concepts of single-pass and multi-pass are most certainly NOT orthogonal, for obvious reasons. So it DOES make sense to ask an output range, "hey, can I write to you multiple times?"

So if you're expecting to be able to say

	void foo(R)(ref R range) if (isInputRange!R)
	{
		static if (hasLValueElements!R)  // or whatever it was
			range.front = (ElementType!R).init;
	}

then you're mixing up two completely unrelated/orthogonal concepts, which is silly.

What you SHOULD be saying instead is:

	void foo(R)(ref R range) if (isInputRange!R)
	{
		static if (isOutput!R)  // or whatever it was
			range.put((ElementType!R).init);
	}

July 09, 2012
> With your design you need to add something extra to allow writing to elements of a single-pass range.

If that's the case, I'd hate to tell you this, but _unless_
you're planning on removing the notion of input/output ranges
(and perhaps adding single-pass/multi-pass), you're doing it
wrong. :-)

That capability is simply /not needed/ when your /only/ contract
is that something is an input range.

Asking an input range, "hey, can I write to you?" is just...
insulting!
That's like asking an electrical engineer if he can plumb.

Sure, it might come in handy if he can, but it's just plain silly
to ask himi that. If you need someone who can do both, then ask
for someone who's an EE _and_ a plumber.

On the other hand, the concepts of single-pass and multi-pass are
most certainly NOT orthogonal, for obvious reasons. So it DOES
make sense to ask an output range, "hey, can I write to you
multiple times?"

So if you're expecting to be able to say

	void foo(R)(ref R range) if (isInputRange!R)
	{
		static if (hasLValueElements!R)  // or whatever it was
			range.front = (ElementType!R).init;
	}

then you're mixing up two completely unrelated/orthogonal
concepts, which is silly.

What you SHOULD be saying instead is:

	void foo(R)(ref R range) if (isInputRange!R)
	{
		static if (isOutputRange!R)  // or whatever it was
			range.put((ElementType!R).init);
	}

July 09, 2012
On 07/09/2012 06:05 PM, Mehrdad wrote:
>> With your design you need to add something extra to allow writing to
>> elements of a single-pass range.
>
> If that's the case, I'd hate to tell you this, but _unless_
> you're planning on removing the notion of input/output ranges
> (and perhaps adding single-pass/multi-pass), you're doing it
> wrong. :-)
>
> That capability is simply /not needed/ when your /only/ contract
> is that something is an input range.
>
> Asking an input range, "hey, can I write to you?" is just...
> insulting!
> That's like asking an electrical engineer if he can plumb.
>

Consider the possibility that this electrical engineer might be a plumber as well.