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