On Tuesday, 14 February 2017 at 16:25:17 UTC, Andrei Alexandrescu wrote:
On 02/14/2017 10:49 AM, Jacob Carlborg wrote:
On 2017-02-14 15:37, Andrei Alexandrescu wrote:

How are they so,

Example [1]. That signature spans 8 lines, it took me 10 seconds to find
the actual function name.

Copying here to make things easier:

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

The function name is on the first line. I think 10 seconds would be an exaggeration of an admittedly real issue.

Example [2], 5 lines.

Copying here as well (reflowed for email):

Tuple!(InputRange1, InputRange2)
swapRanges(InputRange1, InputRange2)(InputRange1 r1, InputRange2 r2)
if (isInputRange!(InputRange1) && isInputRange!(InputRange2)
    && hasSwappableElements!(InputRange1)
    && hasSwappableElements!(InputRange2)
&& is(ElementType!(InputRange1) == ElementType!(InputRange2)));

One immediate matter here is redundant parens, of which elimination would lead to the marginally more palatable:

Tuple!(InputRange1, InputRange2)
swapRanges(InputRange1, InputRange2)(InputRange1 r1, InputRange2 r2)
if (isInputRange!InputRange1 && isInputRange!InputRange2
    && hasSwappableElements!InputRange1
    && hasSwappableElements!InputRange2
    && is(ElementType!InputRange1 == ElementType!InputRange2));

and what steps can we take to improve them. Could you
please give a few examples on how to do things better? Thx! -- Andrei

Well, I would prefer to have template constraints as its own entity in the language not not just a bunch of boolean conditions. This has been
talked about before several times. Something like:

constraint Foo
{
    void foo();
}

void bar(T : Foo)(T t);

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

If I had my way, like so:

Tuple!(InputRange1, InputRange2)
swapRanges
(InputRange1: (InputRange, HasSwappableElements),
 InputRange2: (InputRange, HasSwappableElements))
(InputRange1 r1, InputRange2 r2)
if (is(ElementType!(InputRange1) == ElementType!(InputRange2)));

Assuming I'm still having my way, the above would result in the compiler telling me that given:

struct Foo {
     enum empty = false;
     enum front = 42;
}

If I tried to instantiate swapRanges!(Foo, Foo), I'd want to get something akin to:

error: foo.Foo does not satisfy InputRange: no function `popFront` for `foo.Foo`

For now I'm getting quite a bit of mileage from my concepts library.


Atila




Reply via email to