Jump to page: 1 2 3
Thread overview
Expressing range constraints in CNF form
Jun 11, 2017
Nick Treleaven
Jun 11, 2017
Stefan Koch
Jun 11, 2017
Timon Gehr
Jun 11, 2017
Stanislav Blinov
Jun 11, 2017
Antonio Corbi
Jun 11, 2017
Walter Bright
Jun 11, 2017
ketmar
Jun 11, 2017
ketmar
Jun 11, 2017
Stefan Koch
Jun 11, 2017
bachmeier
Jun 11, 2017
bachmeier
Jun 11, 2017
crimaniak
Jun 11, 2017
Walter Bright
Jun 11, 2017
Walter Bright
Jun 11, 2017
Stefan Koch
Jun 11, 2017
Sebastiaan Koppe
Jun 12, 2017
David Gileadi
Jun 12, 2017
H. S. Teoh
Jun 12, 2017
Sebastiaan Koppe
Jun 12, 2017
Adam D. Ruppe
Jun 12, 2017
Walter Bright
June 10, 2017
https://github.com/dlang/phobos/pull/5461

There's many good advantages to this. The immediate one is the constraint is better structured and easier to understand. Then, the compiler can print the exact clause that failed, which improves the precision and quality of the error message.

We consider adding in the future some capability of printing user-defined error messages, one per clause. For example:

// Current
enum bool isInputRange(R) =
    is(typeof((ref R r) => r))
    && is(ReturnType!((R r) => r.empty) == bool)
    && is(typeof(lvalueOf!R.front))
    && is(typeof(lvalueOf!R.popFront));

// Possible (which change to language)
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";

// 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
June 11, 2017
On Sunday, 11 June 2017 at 00:28:58 UTC, Andrei Alexandrescu wrote:
> https://github.com/dlang/phobos/pull/5461
>
> There's many good advantages to this. The immediate one is the constraint is better structured and easier to understand. Then, the compiler can print the exact clause that failed, which improves the precision and quality of the error message.

Great!

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

I'm not getting how this works.
June 11, 2017
On 6/11/17 11:11 AM, Nick Treleaven wrote:
> On Sunday, 11 June 2017 at 00:28:58 UTC, Andrei Alexandrescu wrote:
>> https://github.com/dlang/phobos/pull/5461
>>
>> There's many good advantages to this. The immediate one is the constraint is better structured and easier to understand. Then, the compiler can print the exact clause that failed, which improves the precision and quality of the error message.
> 
> Great!

Thanks.

>> // 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");
> 
> I'm not getting how this works.

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.


Andrei
June 11, 2017
On Sunday, 11 June 2017 at 15:25:11 UTC, Andrei Alexandrescu wrote:
> On 6/11/17 11:11 AM, Nick Treleaven wrote:
>> On Sunday, 11 June 2017 at 00:28:58 UTC, Andrei Alexandrescu wrote:
>>> https://github.com/dlang/phobos/pull/5461
>>>
>>> There's many good advantages to this. The immediate one is the constraint is better structured and easier to understand. Then, the compiler can print the exact clause that failed, which improves the precision and quality of the error message.
>> 
>> Great!
>
> Thanks.
>
>>> // 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");
>> 
>> I'm not getting how this works.
>
> 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.
>
>
> Andrei

Exposing magic functions which are recognized by name strikes me as being worse then proper compiler intrinsics.

June 11, 2017
On 11.06.2017 17:25, Andrei Alexandrescu wrote:
> On 6/11/17 11:11 AM, Nick Treleaven wrote:
>> On Sunday, 11 June 2017 at 00:28:58 UTC, Andrei Alexandrescu wrote:
>>> https://github.com/dlang/phobos/pull/5461
>>>
>>> There's many good advantages to this. The immediate one is the constraint is better structured and easier to understand. Then, the compiler can print the exact clause that failed, which improves the precision and quality of the error message.
>>
>> Great!
> 
> Thanks.
> 
>>> // 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");
>>
>> I'm not getting how this works.
> 
> 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.
> 
> 
> Andrei

I'd prefer

bool msg(bool constraint, string message){ return constraint; }

This does not require the compiler to dive into a branch it wouldn't consider otherwise, and the pairing of constraint to message is less ad-hoc.
June 11, 2017
On Sunday, 11 June 2017 at 16:28:23 UTC, Timon Gehr wrote:

> I'd prefer
>
> bool msg(bool constraint, string message){ return constraint; }
>
> This does not require the compiler to dive into a branch it wouldn't consider otherwise, and the pairing of constraint to message is less ad-hoc.

Where were you while Steven was destroying me? :)

http://forum.dlang.org/thread/mcxeymbslqtvfijxirmy@forum.dlang.org
June 11, 2017
On 6/11/17 12:28 PM, Timon Gehr wrote:
> bool msg(bool constraint, string message){ return constraint; }

That'd be nice to consider, too, thanks. -- Andrei
June 11, 2017
On 6/11/17 12:15 PM, Stefan Koch wrote:
> Exposing magic functions which are recognized by name strikes me as being worse then proper compiler intrinsics.

This is brainstorming. Let's follow up with better ideas in addition to pointing out flaws in the ideas on the table.

To this point: .msg would solve the problem of "msg" being defined in the current scope (assuming of course msg is defined in object.d).


Andrei
June 11, 2017
On Sunday, 11 June 2017 at 15:25:11 UTC, Andrei Alexandrescu wrote:
> On 6/11/17 11:11 AM, Nick Treleaven wrote:
>> On Sunday, 11 June 2017 at 00:28:58 UTC, Andrei Alexandrescu wrote:
>>> [...]
>> 
>> Great!
>
> Thanks.
>
>>> [...]
>> 
>> I'm not getting how this works.
>
> 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.
>
>
> Andrei

So this is trying to parafrase the perl/bash idiom:
```
commandSucceeds (...) || die ();
```

Isn't it?
So, the '&&' -and- shouldn't be '||' -or-?
Sorry for the noise if I'm wrong.

Antonio
June 11, 2017
On Sunday, 11 June 2017 at 00:28:58 UTC, Andrei Alexandrescu wrote:
> enum bool isInputRange(R) =
>     is(typeof((ref R r) => r)) && "must be copyable"

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.
« First   ‹ Prev
1 2 3