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.