December 13, 2017
On 12/13/17 2:33 PM, Jonathan M Davis wrote:
> On Wednesday, December 13, 2017 11:33:35 Steven Schveighoffer via
> Digitalmars-d wrote:
>> I don't think there's a requirement for empty not to do any work, it
>> just has to return the same value each time.
> 
> IIRC, when this was discussed previously, it was decided that you really
> couldn't do work in empty. The problem is that under some circumstances at
> least, it's perfectly legitimate to skip calls to empty 

The discussion before was whether empty was required to be called before calling front. It's perfectly acceptable to do work in empty, as long as you return the same value in 2 subsequent calls to empty without changing the range between those calls.

The problem is, if you have work done in empty, that doesn't mean you don't have to do the equivalent work in front. Which is probably what Luís is after.

The best way I think to have ranges work is to only modify them in popFront/popBack, and the ctor.

-Steve
December 13, 2017
On Wed, Dec 13, 2017 at 03:33:51PM -0500, Steven Schveighoffer via Digitalmars-d wrote:
> On 12/13/17 2:33 PM, Jonathan M Davis wrote:
[...]
> The best way I think to have ranges work is to only modify them in popFront/popBack, and the ctor.
[...]

I don't see anything wrong with doing work in .empty or .front, as long as the overall result looks the same.  Sometimes, if .front is expensive to compute, you may want to defer the work until it's actually needed. For this, a caching implementation of .front might work best, though at the cost of slightly more complexity:

	struct MyRange {
		private WorkParams params;
		private Nullable!T frontValue;

		@property bool empty() { ... }
		@property T front() {
			if (frontValue.isNull)
			{
				frontValue = doExpensiveWork(params);
			}
			return frontValue;
		}
		void popFront() {
			params = setupNextItemParams();
		}
	}

The use of Nullable here is just for illustration, of course. In an actual implementation you can probably find cheaper ways of doing the same thing.


T

-- 
My program has no bugs! Only undocumented features...
December 13, 2017
On Wednesday, 13 December 2017 at 10:15:10 UTC, ag0aep6g wrote:
>
> `front` can't assume that `empty` has been called before. For a well-behaved range, `front` must work the same whether you've called `empty` or not (given that the range isn't actually empty).

That last point is what I meant: it cannot assume empty() being called BUT it can assume that it WOULD have returned false it it were. So there is no problem with the program crashing when calling front() of an empty range. Therefore, there is no need to manually do stuff like if(inited) because if the elements are not initialized, the range would obviously be empty. Assuming I understood the intention of that code correctly.
1 2
Next ›   Last »