RFC: std.*.concept convention
Jakob Ovrum via Digitalmars-d
digitalmars-d at puremagic.com
Wed Feb 11 00:00:53 PST 2015
------------
Preface
------------
I'd like to start by saying that this is a relatively low-impact
enhancement in the short term, but should pay off in the long
term. It also requires very little effort, so it is low-hanging
fruit, although it requires some foresight to see the benefit.
------------
Primer of type concepts for the uninitiated (skip if you know
this stuff)
------------
In D we have the idea of a type concept. Current notable concepts
are the range concept and the container concept. The idea is that
any type that satisfies the operations of a certain usage pattern
can be said to satisfy a certain type concept, and thus be usable
in algorithms that use a permutation of said usage pattern. The
operations making up a type concept are called the primitives of
the concept.
For example, for a type to satisfy the input range concept, the
following usage pattern must compile:
---
R r; // can define a range object
if (r.empty) {} // can test for empty
r.popFront(); // can invoke popFront()
auto h = r.front; // can get the front of the range of non-void
type
---
The three required operations for the input range concept are the
front, empty and popFront primitives. In addition there may be
certain restrictions on runtime behaviour; for example, `front`
should never be called on an empty range.
For convenient verification of a type satisfying a concept, we
have concept checker templates such as isInputRange[1].
------------
Suggestion
------------
Lately there is a trend of splitting up modules into packages in
Phobos. Notably, std.range and std.container have been split up
into packages.
Currently all the range concept checkers are defined in a module
std.range.primitives, bundled with the UFCS implementations of
the range primitives for in-built slice types.
Containers do not (yet) have concept checkers, but I consider it
likely we'll see them in the future, as we see more generic
container algorithms as well as higher-order containers.
Additionally, Andrei has suggested a new type RefCountedSlice!T
that presents the same dynamic array interface of T[], but with a
reference-counted backend in lieu of the GC backend of T[]. It is
conceivable that generic array algorithms may want to accept
either type, and thus the "dynamic slice" concept is born.
Putting the complexity of the container concept aside; I think we
should factor out the concept checkers from std.range.primitives
and put them in std.range.concept and establish a convention of
using modules named std.*.concept for concept checkers in the
future. The consistency gained by such a convention makes type
concepts easier to understand and commonly used module names
easier to remember. If we do it now, there is no breakage, as the
splitting of std.range has not yet been released: hence the
otherwise clumsy timing of this suggestion.
It is very little work, but anticipating complaints of
bike-shedding if I didn't explain myself, I decided to post here
first. I'd like to get some feedback before I file a PR.
[1] http://dlang.org/phobos/std_range#isInputRange
More information about the Digitalmars-d
mailing list