On 2017-02-14 17:25, Andrei Alexandrescu wrote:

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.)

It would obviously take a while for me to figure that out. Is not like I have a fully defined new language feature in my head.

I do see a possibility for a slightly improvement in a different area, in the example of "remove". If we look at the signature, without the constraints:

Range remove
(SwapStrategy s = SwapStrategy.stable, Range, Offset...)
(Range range, Offset offset)

Why isn't it possible to use "auto" when declaring a parameter with a default argument?

Range remove
(auto s = SwapStrategy.stable, Range, Offset...)
(Range range, Offset offset)

A minor improvement, but I also feel like it would lift an arbitrary limitation in the language.

Alternatively something that Swift supports:

Range remove
(SwapStrategy s = .stable, Range, Offset...)
(Range range, Offset offset)

The compiler knows that the type of "s" is SwapStrategy, therefore "stable" has to be a member of SwapStrategy. In the case of D, the leading dot has a different meaning so another syntax would be required. Unfortunately this has already been discussed and rejected by Walter.

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 don't see that as a problem, but I would rather name it "Removable" or something that does not include all the conditions in the name. But I imagine that a constraint would consist of a combination of declarations (like an interface) and boolean conditions.

Lets look it differently. For a regular (non-template) function with a user defined type (class, struct). If it was possible to define the type inline, would you? I hope that answer is no. Example:

Standard D:

struct Bar
{
    int a;
    int b;
}

void foo(Bar bar);

With inline user defined types:

void foo(struct { int a; int b; } bar);

Assuming the answer is no, why would it be any different for a template type? You can see all the template constraints for a type as a form of metatype.

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 haven't followed the C++ concepts lately either and not very closely at all so I don't feel I can comment on the C++ concepts. But if I recall correctly, you're "static if" proposal wasn't well received [1]. But now with "if constexpr" it looks like they're changing their minds.

[1] "The static if feature recently proposed for C++ [1, 2] is fundamentally flawed, and its adoption would be a disaster for the language" http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3613.pdf

--
/Jacob Carlborg

Reply via email to