range behaviour

H. S. Teoh via Digitalmars-d digitalmars-d at puremagic.com
Tue May 13 10:40:55 PDT 2014


On Tue, May 13, 2014 at 01:29:32PM -0400, Steven Schveighoffer via Digitalmars-d wrote:
[...]
> I don't agree there was a consensus. I think empty should not have to
> be called if it's already logically known that the range is not empty.

I only partially agree with this, up to the point where .empty has been
checked previously, such as:

	void f1() {
		void f2(R)(R r) if (isInputRange!R) {
			doSomething(r.front);
		}

		auto r = makeMeARange();
		if (!r.empty)
			f2(r);
		...
	}

Even in this case, I'd put an in-contract on f2 that verifies that the
range is indeed non-empty:

	...
		void f2(R)(R r)
			if (isInputRange!R)
		in { assert(!r.empty); }
		body {
			doSomething(r.front);
		}

[...]
> In any case, I think generic code for an unknown range type in an
> unknown condition should have to call empty, since it cannot logically
> prove that it's not.
[...]

In my mind, *all* range-based code is generic. If you need to depend on
something about your range beyond what the range API guarantees, then
you should be using the concrete type rather than a template argument,
which means that your code is no longer range-based code -- it's
operating on a concrete type. (Of course, if the concrete type
implements the range API, then there's nothing wrong with using range
API methods, but one shouldn't be under the illusion that one is writing
range-based code. It is type-dependent code that just happens to have
range-based methods. If the code will break if the range is substituted
by a different range that doesn't have the same guarantees (outside of
what the range API specifies), then it's not range-based code.)


T

-- 
Many open minds should be closed for repairs. -- K5 user


More information about the Digitalmars-d mailing list