Policy for exposing range structs

H. S. Teoh via Digitalmars-d digitalmars-d at puremagic.com
Fri Mar 25 07:29:42 PDT 2016


On Fri, Mar 25, 2016 at 11:37:24AM +0000, Seb via Digitalmars-d wrote:
> If I understand it correctly, the current policy in Phobos is that
> range methods should use static nested structs to avoid the name
> clutter and document the capabilities of the returned ranges in the
> documentation.  However there are a lot of old functions that still
> use public structs, which leads to the rather confusing documentation
> output in std.range:

Actually, certain types of range structs *have* to be in module space
rather than inside the function, because of compiler limitations /
language restrictions. An example that comes to mind is a range with an
alias parameter -- I forget the details, but basically there are some
cases where this will not work correctly with certain uses if it's
declared inside the function, so it has to be in module space.

This should probably be investigated more, though. It seems to be a grey
area of semantics that could use a DIP.


[...]
> (off-topic: it's quite interesting to see that sometimes the structs
> are before the method and sometimes after it)

I think it's a recent change in convention that recommends declaring
such structs after the function. In any case, declaration order in D is
(generally -- mostly in module space) not important, so it's not a big
deal.


> Two arguments to keep exposing the structs are that (1) an API user
> can explicitly specify the return type (in contrast to auto) and (2)
> one can see the capabilities of the struct in the documentation.

I think (1) is moot, because there's always typeof and ReturnType.  In
fact, I'd argue that it's better to use typeof / ReturnType, because
sometimes the user *shouldn't* need to know exactly what the template
arguments are. For example, if some of the template arguments come from
IFTI, where the exact types may not be immediately obvious from the
user's POV, or if there are default template parameters that are a pain
to spell out every single time.

I argue that (2) is a bad idea, because a range ought to be opaque. The
whole point of the range API is that it should be possible for the
implementation to change drastically or be replaced by a different
implementation, yet user code should still continue to Just Work(tm)
without any modifications.  As such, user code should not depend on
implementation details of the range, and really shouldn't know anything
else about the range other than what is specified in the range API.  All
the user ought to know is whether it's an input range, forward range,
bidirectional range, etc.. Anything more than that leads to breakage
when the range implementation is updated/replaced, which breaks the
whole premise of using ranges in the first place.


> There are many cases where methods in these structs are optional and
> depend on the capabilities of the input range (e.g. backward, length,
> random access, ...). I could imagine that
> 
> 1) We rework ddoc, s.t. it doesn't list these structs in the overview
> and adds the struct methods to the function (could get ugly)

No. The docs of the function should simply state what kind of range it
returns -- input, forward, bidirectional, or random access. If it
depends on what the function is given, the docs should explain under
what conditions the function will return which kind of range.  Listing
individual range methods for every range function in Phobos is a lot of
needless repetition, and is error-prone.  If anything, we should write a
page that explains exactly what methods are available to each kind of
range, and just link to that from the function docs. That's what
hyperlinks are for.


> 2) We deprecate those exposed structs and make them private/nested
> (does anyone know whether it's common to depend on those structs?)
[...]

I don't know if it's common, but I *have* seen people spell out the type
explicitly.  So changing this now will probably break existing code, and
people will likely be resistant to that.  (Arguably, though, it would be
for the better -- users really shouldn't need to know the exact range
type.)


T

-- 
Winners never quit, quitters never win.
But those who never quit AND never win are idiots.


More information about the Digitalmars-d mailing list