Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 27 additions & 10 deletions std/range/primitives.d
Original file line number Diff line number Diff line change
Expand Up @@ -123,16 +123,33 @@ r.popFront(); // can invoke popFront()
auto h = r.front; // can get the front of the range of non-void type
----

The semantics of an input range (not checkable during compilation) are
assumed to be the following ($(D r) is an object of type $(D R)):

$(UL $(LI $(D r.empty) returns $(D false) iff there is more data
available in the range.) $(LI $(D r.front) returns the current
element in the range. It may return by value or by reference. Calling
$(D r.front) is allowed only if calling $(D r.empty) has, or would
have, returned $(D false).) $(LI $(D r.popFront) advances to the next
element in the range. Calling $(D r.popFront) is allowed only if
calling $(D r.empty) has, or would have, returned $(D false).))
The following are rules of input ranges are assumed to hold true in all
Phobos code. These rules are not checkable at compile-time, so not conforming
to these rules when writing ranges or range based code will result in
undefined behavior.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/undefined/undefined unless specified otherwise by a range type/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

otherwise by a range type

Do you mean derivative range types like bidirectional and random access?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, not kind. E.g. I mean "I define MyRange that does this and that."

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why this distinction should be made here. If a MyRange violates these rules then a lot of the code in std.range isn't going to work, and they're allowed to throw an Error, and Exception, or corrupt memory, etc.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ping @andralex

Copy link
Contributor

@dnadlinger dnadlinger Jul 12, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think Andrei is saying that a range type might always strengthen the guarantees to actually make the behaviour defined. But, of course, generic code still cannot make any such assumptions.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought so, but wanted to check whether the text should be modified accordingly, or is this PR ready to merge?


$(UL
$(LI `r.empty` returns `false` if and only if there is more data
available in the range.)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"iff" is math speak. Maybe "if and only if" is more appropriate here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was in the original. I think most programmers know what iff means.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @qznc that our docs shouldn't require math background - at least for such basic and common rules. They should be easy to understand for everyone out there.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's just go with "if and only if". It's come before, and if a couple of us mention it it's enough. Nobody will raise a brow at the explicit version.

$(LI `r.empty` evaluated multiple times, without calling
`r.popFront`, or otherwise mutating the range object or the
underlying data, yields the same result for every evaluation.)
$(LI `r.front` returns the current element in the range.
It may return by value or by reference.)
$(LI `r.front` can be legally evaluated if and only if evaluating
`r.empty` has, or would have, equaled `false`.)
$(LI `r.front` evaluated multiple times, without calling
`r.popFront`, or otherwise mutating the range object or the
underlying data, yields the same result for every evaluation.)
$(LI `r.popFront` advances to the next element in the range.)
$(LI `r.popFront` can be called if and only if evaluating `r.empty`
has, or would have, equaled `false`.)
)

Also, note that Phobos code assumes that the primitives `r.front` and
`r.empty` are $(BIGOH 1) time complexity wise or "cheap" in terms of
running time. $(BIGOH) statements in the documentation of range functions
are made with this assumption.

Params:
R = type to be tested
Expand Down