June 11, 2017
On 6/11/2017 8:25 AM, Andrei Alexandrescu wrote:
> Ostensibly the function is trivial:
> 
> bool msg(string) { return true; }
> 
> It doesn't change the semantics. The compiler would recognize it as an intrinsic and would print the message if the clause to its left has failed.

There was a proposal a while back to enable CTFE to print messages, which is probably a better solution. msg() could be something along the lines of:

    bool msg(string) { __ctfeprint(string); return true; }

which would involve considerably less compiler magic. Furthermore, `msg` could be a local private function, which would avoid "but I'm already using `msg`" problems.
June 11, 2017
On Sunday, 11 June 2017 at 15:25:11 UTC, Andrei Alexandrescu wrote:

>>> // Also possible (no change to the language)
>>> enum bool isInputRange(R) =
>>>     is(typeof((ref R r) => r)) && msg("must be copyable")
>>>     && is(ReturnType!((R r) => r.empty) == bool) && msg("must support bool empty")
>>>     && is(typeof(lvalueOf!R.front)) && msg("must support front")
>>>     && is(typeof(lvalueOf!R.popFront)) && msg("must support back");

This would be a very nice change, but this syntax feels more natural to me:

is(ReturnType!((R r) => r.empty) == bool, "must support bool empty")


June 11, 2017
On 6/10/2017 5:28 PM, Andrei Alexandrescu wrote:
>      && is(typeof(lvalueOf!R.popFront)) && msg("must support back");

Wouldn't it work better as:

    && (is(typeof(lvalueOf!R.popFront)) || msg("must support back"));

    bool msg(string) { return false; }

? Then msg() is only called if the first clause fails.
June 11, 2017
On 6/11/2017 12:07 PM, crimaniak wrote:
> Regardless of the implementation method, this will require the previously proposed Phobos refactoring. Independent special definitions have to be reduced to general ones and use "static if" to select the algorithm. Otherwise, each failed independent definition will give an additional error message, and the compiler does not have the ability to determine which one is relevant.

You're right that there are issues with the `msg` thing in the presence of overloading.
June 11, 2017
Walter Bright wrote:

> On 6/11/2017 8:25 AM, Andrei Alexandrescu wrote:
>> Ostensibly the function is trivial:
>> bool msg(string) { return true; }
>> It doesn't change the semantics. The compiler would recognize it as an intrinsic and would print the message if the clause to its left has failed.
>
> There was a proposal a while back to enable CTFE to print messages, which is probably a better solution. msg() could be something along the lines of:
>
>      bool msg(string) { __ctfeprint(string); return true; }
>
> which would involve considerably less compiler magic. Furthermore, `msg` could be a local private function, which would avoid "but I'm already using `msg`" problems.

that has another problem: there may be overload set, where some overloads are failed, but one is fitting. using `ctfeprint` will spam user with alot of non-sensical messages about failed constraints.
June 11, 2017
Walter Bright wrote:

> On 6/11/2017 8:25 AM, Andrei Alexandrescu wrote:
>> Ostensibly the function is trivial:
>> bool msg(string) { return true; }
>> It doesn't change the semantics. The compiler would recognize it as an intrinsic and would print the message if the clause to its left has failed.
>
> There was a proposal a while back to enable CTFE to print messages, which is probably a better solution. msg() could be something along the lines of:
>
>      bool msg(string) { __ctfeprint(string); return true; }
>
> which would involve considerably less compiler magic. Furthermore, `msg` could be a local private function, which would avoid "but I'm already using `msg`" problems.

i think, that something like `__constraint(condition, "message")` is ok, and it should be built-in, just like `__traits()`. so compiler can collect those messages, and only show 'em if the matcher is failed to find anything. yeah, another hack in interpreter, but fairly small, and should solve "what constraint is really failed" problem.
June 11, 2017
On Sunday, 11 June 2017 at 19:45:37 UTC, Walter Bright wrote:
> On 6/10/2017 5:28 PM, Andrei Alexandrescu wrote:
>>      && is(typeof(lvalueOf!R.popFront)) && msg("must support back");
>
> Wouldn't it work better as:
>
>     && (is(typeof(lvalueOf!R.popFront)) || msg("must support back"));
>
>     bool msg(string) { return false; }
>
> ? Then msg() is only called if the first clause fails.

I can do a __ctfePrint for string literals.
(is(typeof(lvalueOf!R.popFront)) || __ctfePrint("bla"))

would work in a short amount of time.

June 11, 2017
On Sunday, 11 June 2017 at 19:51:11 UTC, ketmar wrote:
> Walter Bright wrote:
>
>> [...]
>
> i think, that something like `__constraint(condition, "message")` is ok, and it should be built-in, just like `__traits()`. so compiler can collect those messages, and only show 'em if the matcher is failed to find anything. yeah, another hack in interpreter, but fairly small, and should solve "what constraint is really failed" problem.

+1
Implementation wise this one is easiest ... I guess.
June 11, 2017
On Sunday, 11 June 2017 at 00:28:58 UTC, Andrei Alexandrescu wrote:
> // Also possible (no change to the language)
> enum bool isInputRange(R) =
>     is(typeof((ref R r) => r)) && msg("must be copyable")
>     && is(ReturnType!((R r) => r.empty) == bool) && msg("must support bool empty")
>     && is(typeof(lvalueOf!R.front)) && msg("must support front")
>     && is(typeof(lvalueOf!R.popFront)) && msg("must support back");
>
>
> Andrei

What about using ddoc?

enum bool isInputRange(R) =
    is(typeof((ref R r) => r)) /// must be copyable
    && is(ReturnType!((R r) => r.empty) == bool) /// must support bool empty
    && is(typeof(lvalueOf!R.front)) /// must support front
    && is(typeof(lvalueOf!R.popFront)) /// must support back
June 11, 2017
On 6/11/17 3:45 PM, Walter Bright wrote:
> On 6/10/2017 5:28 PM, Andrei Alexandrescu wrote:
>>      && is(typeof(lvalueOf!R.popFront)) && msg("must support back");
> 
> Wouldn't it work better as:
> 
>      && (is(typeof(lvalueOf!R.popFront)) || msg("must support back"));
> 
>      bool msg(string) { return false; }
> 
> ? Then msg() is only called if the first clause fails.

The added parens are a small liability. -- Andrei