On Tuesday, 14 February 2017 at 16:25:17 UTC, Andrei Alexandrescu
wrote:
Range remove
(SwapStrategy s = SwapStrategy.stable, Range, Offset...)
(Range range, Offset offset)
if (s != SwapStrategy.stable
&& isBidirectionalRange!Range
&& hasLvalueElements!Range
&& hasLength!Range
&& Offset.length >= 1);
[...]
My recollection is past discussions got stalled because the
approach is combinatorially bankrupt. How would one express the
constraints of the functions above with simple named
constraints? (Not rhetorical; please do provide an example if
possible.) Before long there is an explosion in names
("BidirectionalWithLvalueElementsAndLength", ...). This is what
has buried not one, but two concepts proposals for C++, leading
to the current Concepts Lite proposal. I haven't followed that
lately but I remember it combines an engineering effort to
reduce the number of names introduced (for the standard library
only, which is a limitation) with adding support to Boolean
logic (surprise, surprise) to the feature (see
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4377.pdf), the most recent proposal, which was rejected for C++17. Over time, C++ concepts have moved from the broken combinatorially-bankrupt form slowly toward D's Boolean constraints (just with a gratuitously awkward notation). I presume they will be merged into the language when they'll have capabilities comparable to D's system.
The question is, given this experience, do we want to move the
opposite direction?
I am not familiar with all of the past discussion of this issue,
but something that I have wondered is why we can't do something
like
alias fooConstraint = (s != SwapStrategy.stable
&& isBidirectionalRange!Range
&& hasLvalueElements!Range
&& hasLength!Range
&& Offset.length >= 1);
Range remove
(SwapStrategy s = SwapStrategy.stable, Range, Offset...)
(Range range, Offset offset) if fooConstraint;