On Tuesday, 12 March 2013 at 10:49:57 UTC, monarch_dodra wrote:
On Tuesday, 12 March 2013 at 10:01:38 UTC, deadalnix wrote:
I want to resurrect that thread. Can someone explains the
benefices of isInfinite ? I fail to see how it really benefit
the code.
The advantage of "enum empty = false" is that algorithms gain a
great performance boost by optimizing out any "if (r.empty)".
This can be exploited for things like take, or anything that
iterates as a matter of fact. I don't think anybody will argue
that this is a bad approach.
I think the point is moot for the same reason it is for
SentinelRange. A function that return false will be inlined and
the whole if optimized away anyway. Same goes for a constant.
I'm not talking about a supposed sufficiently smart compiler, but
actual compiler that exist right now.
The trait itself checks if empty can be evaluated at compile
time (to false). The advantage for the *coder* to know if the
range is infinite is less obvious.
One of the advantages is that an infinite range can have random
access (meets RA requirements), even though it has no length
member (normally, any RA range must have length).
Having "isInfinite" can also have the advantage of protecting
users from stupid calls. For example, calling "count" on an
infinite range is forbidden => shifting problems from runtime
to compile time is a HUGE gain.
Clearly this is a good point. I however think that a static
assert within count is much better because it allow to give nicer
feedback. The problem with InfiniteRange is that it does gives
you cryptic error message like the count function do not exists.
One of downsides to having infinite ranges is that their
existence tends to make dealing with generic RA ranges a bit
more difficult. A lot of our algorithms have changed
requirements conditions from:
"if (isRandomAccessRange!R)"
to
"if (isRandomAccessRange!R && hasLength!R)"
or
"if (isRandomAccessRange!R && !isInfinite!R)"
//NOTE: Both are strictly equivalent: An RA range is either
infinite, or has length, but not neither nor both.
Up until not so long ago, it was not possible to slice infinite
ranges. It is now possible. Unfortunatly, because RA ranges
with slicing don't guarantee that r[0 .. $] is legal, things
are still complicated in template code.
I conclude that the fix introduced complexity without solving the
problem, just pushing the limit. I think we should avoid this
kind of stuff.
The last point (IMO minor) that is raised in the thread is
"runtime" infiniteness. EG: a range that may or may not be
infinite at compile time, but which will be known at runtime.
IMO, these a rare enough (arguably, inexistent) to not really
matter. The workarounds are easy:
1) Make the range always infinite, but with a requirement that
user must intialize it or whatnot.
2) Make a runtime fork that will call code that operates on a
compile-time known infinite adaptor/subtype.
A common case is unknown "infinitivenes".