On Thursday, 2 June 2016 at 14:31:15 UTC, ag0aep6g wrote:
A little terminology: "Slice" is not a synonym for "range". iota does not return a slice, it returns a range. "Slice" is being used as a synonym for "dynamic array" (Type[]), and in the context of the slicing operator (expression[] or expression[a .. b]).

Now, for the actual question - how to define a range that is non-empty by definition:

One of the range primitives is popFront. popFront removes one element from the range. popFront cannot change the type of the range. So you can't have a type that is a range, and is guaranteed not to be empty, and can be emptied by calling popFront.

But you can have a type that is a range, is guaranteed not to be empty, and *cannot* be emptied by calling popFront: an infinite range. That's a range that never gets empty no matter how often popFront is called.

The library recognizes infinite ranges when you define `empty` like this: `enum bool empty = false;`. There's std.range.primitives.isInfinite [1] to check for them.

I guess that's not really what you're looking for.

Yes, that's not. :)

I don't think you can otherwise statically check that a range isn't empty. You could probably make a wrapper that checks once on construction, but that's still a run-time check. And I don't see it being particularly useful, because popFront is an essential parts of ranges.

So this would mean, the contract I use now for run-time check is ok. And... well... maybe I can alias two different methods, one which returns an arbitrary range and one which returns a range, checked for emptiness in an out contract...
This already would save a lot of code duplication...

You've lost me there. I don't see how non-empty range and Algebraic connect.

What I mean is: if there would be a possibility to use algebraic types here (or maybe some kind of template...), then my types would be able (maybe! did not seen anything similar yet...) to choose the proper methods for themselves automatically: As long as my type has a length > 1 it is handled as a range, if the range has the length=1 it is handled as a single element and not as a range, if the range has the length=0 it is handled as an absent element.

Reply via email to