Re: Formal request to remove put(OutRange, RangeOfElements)

2012-07-23 Thread monarch_dodra
Maybe I should put this request elsewhere? I'm not sure if there 
is a place where I should put this?


I know this is not a very exciting issue, but I think it is a 
very important to resolve, preferably sooner than later.


Maybe I'll try to help kick start this by listing all the modules 
that would need to be changed?


Re: Formal request to remove put(OutRange, RangeOfElements)

2012-07-23 Thread Christophe Travert
monarch_dodra , dans le message (digitalmars.D:173005), a écrit :
 Maybe I should put this request elsewhere? I'm not sure if there 
 is a place where I should put this?
 
 I know this is not a very exciting issue, but I think it is a 
 very important to resolve, preferably sooner than later.
 
 Maybe I'll try to help kick start this by listing all the modules 
 that would need to be changed?

You can fill a bug report.

assert(isOutputRange!typeof(r), typeof(e)  !output.r);
output.put(e);

failing on the second line is worthy of attention.
And it makes fill fail IIRC.

-- 
Christophe


Re: Formal request to remove put(OutRange, RangeOfElements)

2012-07-23 Thread Jonathan M Davis
On Monday, July 23, 2012 17:33:07 monarch_dodra wrote:
 Maybe I should put this request elsewhere? I'm not sure if there
 is a place where I should put this?
 
 I know this is not a very exciting issue, but I think it is a
 very important to resolve, preferably sooner than later.
 
 Maybe I'll try to help kick start this by listing all the modules
 that would need to be changed?

If you've found a bug, then report it bugzilla. If you have an issue that 
needs discussion, then this is the right place. It's just that you don't 
always get people responding, especially if it's a complicated topic (and the 
fact that it's summer right now probably doesn't help due to an increased 
number of people on vacation). Personally, I intend to read through this and 
respond, but it's the sort of thing that obviously needs to be read through 
and thought through carefully before discussing, and I haven't had the chance 
to do that yet.

- Jonathan M Davis


Formal request to remove put(OutRange, RangeOfElements)

2012-07-18 Thread monarch_dodra
I'm really very sorry that this is such a long post, but I'd like 
to make request for a serious change to Phobos, so I think it 
should be as complete as possible.


Thank you to those who have the patience to read it and consider 
it.



**
Abstract:

  This is a formal request for the deprecation of the the support 
for accepting ranges of elements for the function put ie 
(put(OutRange, RangeOfElements)).


  As convenient as this functionality may be is, it undermines 
the very definition of what constitutes an output range, and 
creates some fundamental problems when trying to deal with them.


  put(Range, RangeOfElements) doesn't actually bring anything to 
the table that would be missed.


**
Explanation:

  The problem is not put in and out of itself, but rather that 
it is the fundamental definition of what constitutes an output 
range. In particular, because you cannot extract elements from 
output ranges, and because an output range can potentially 
support multiple types, you cannot write:
  ElementType!OutputRange = this will yield void on a 'true' 
output range. Rather, you have to individually query if the range 
is an output for specific types:

  isOutputRange!(OutputRange, SomeElement)

  The catch is that the definition of isOutputRange is just 
does put(range, element) compile. This means that 
essentially, as soon as a range is an output for elements, it 
becomes an output for ranges of elements, for ranges of ranges of 
elements, for ranges of ranges of ranges of elements, for ...


For example: int[] is an outputRange of int (obviously), but it 
is also defined as an output range of int[], int[2], and 
int[][]...

This is clearly not right.

**
Problems put creates for template restrictions:

  At it simplest, it prevents any algorithm from properly working 
with outputRanges. This is the definition of copy:


Range2 copy(Range1, Range2)(Range1 source, Range2 target)
  if (isInputRange!Range1  isOutputRange!(Range2, 
ElementType!Range1))


See the trap? This is perfectly legal code:
  int a[][][][];
  int b[];
  copy(a, b);

  Look bad? it gets worse. Imagine the function fill. It works 
the same as copy, but it can also take an element as an 
argument. One would be tempted to write this pair of signatures:


void fill(Range1, Range2)(Range1 target, Element filler)
  if(isOutputRange(Range1, Element))

void fill(Range1, Range2)(Range1 target, Range2  filler)
  if(isInputRange!Range2  isOutputRange(Range1, 
ElementType!Range2))


You can try to write this, but if you do, the code will never 
work. ANYTHING that matches the range fill, will also match the 
element based fill, since the target range supports put from a 
range... For example:

int[2] a = [1, 2];
int[] b = new int[](8);
fill(b, a); //ambiguous call...
//Are you copying a range or an element?
//Answer: Who know! Honestly: if b is an output range of a, WHICH 
IS THE RIGHT CALL?


  The only way to really avoid this problem (as is currently done 
in algorithm.d) is to add: is(typeof(range.front = filler)), 
but this defeats the very requirement of outputRange (outputRange 
does not have front), and bumps the algorithm's requirements up 
to inputRange.


  Long story short, it is not currently possible to write 
templates that reliably support an outputRange restriction.


**
Problems put creates for implementation:

  The big problem about put is that it makes outputRanges _lie_ 
about what they support. Here is an example at its simplest:


alias int[] A; alias int[] B;
A a = new int[](2);
B b = new int[](1);
assert(isOutputRange!(typeof(a), typeof(b)));
if(!b.empty)
  b.put(a);

  In this code:
*b is an output range of A.
*b is not empty.
*putting an A inside b creates a empty range exception !?

  While this example might look cute, it is also unacceptable 
behavior. if b is a non-empty range that supports elements A, 
then it _HAS_ to be able to support a put. In this case, b 
clearly does not support elements of type A.


  I'm sure you can imagine the kinds of problems this can caue 
for a template developer.


**
Why we don't need put(Range):

  Quite simply: because we have the higher order function. The 
convenience put(Range) is nothing more than a glorified 
algorithm. Instead of using put, the user should make a call to 
copy. copy is designed specifically for copying an input range 
into an output range. Why duplicate this functionality into put? 
Calling copy is much more honest and accurate about what is 
actually happening.


**
Problems regarding removing put(Range):

  In theory, the only problem this would create is breaking code 
which can be legitimately replaced by “copy” without any 
change.


  It *could* also break 

Re: Formal request to remove put(OutRange, RangeOfElements)

2012-07-18 Thread Christophe Travert
That sounds reasonable and justified. Let's wait to know if people 
maintaining legacy code will not strongly oppose to this.