October 02, 2015
On Thursday, 1 October 2015 at 17:19:39 UTC, Per Nordlöw wrote:
> On Thursday, 1 October 2015 at 14:37:55 UTC, Andrei Alexandrescu wrote:
>> Whoever wants to work on better assert expression printing: make sure you specify which grammar constructs are supported, and how the parts involved are printed. Expressing semantics via lowering would be great. Write a DIP, discuss, implement. I'll have your six.
>>
>>
>> Andrei
>
> A first version:
>
> http://wiki.dlang.org/DIP83

I like the idea, I just have a practical question on std.experimental.testing: should it go ahead as-is? Should the custom assertions be removed and the rest kept? Should they go in as-is and then deleted when/if this DIP is implemented?

Atila
October 02, 2015
On Friday, 2 October 2015 at 09:32:23 UTC, Atila Neves wrote:
> On Thursday, 1 October 2015 at 17:19:39 UTC, Per Nordlöw wrote:
>> On Thursday, 1 October 2015 at 14:37:55 UTC, Andrei Alexandrescu wrote:
>>> Whoever wants to work on better assert expression printing: make sure you specify which grammar constructs are supported, and how the parts involved are printed. Expressing semantics via lowering would be great. Write a DIP, discuss, implement. I'll have your six.
>>>
>>>
>>> Andrei
>>
>> A first version:
>>
>> http://wiki.dlang.org/DIP83
>
> I like the idea, I just have a practical question on std.experimental.testing: should it go ahead as-is? Should the custom assertions be removed and the rest kept? Should they go in as-is and then deleted when/if this DIP is implemented?

If we're going to be improving the built-in assertions, then I don't think that it makes sense to add custom assertions to Phobos, and I definitely don't like the idea of adding them with the idea that we'll just be deprecating them later. If it turns out that that isn't going work (Walter rejected it the last time it was done, but maybe that will go differently this time - particularly since Andrei is very much in favor of it), then we can add the custom assertions later.

Personally, I think that the parts of this module which really matter are the unittest names (though I still wish that we'd just put that in the language itself - particularly since each unittest block already has a corresponding function that's named after where it is and it really shouldn't be a big deal to just allow the user to provide a name to use instead) and the parts about parallelizing unittest blocks. Even if we don't end up with improvements to the built-in assertions, the custom assertions are just gravy that makes it so that you're less like to have to go change your unit tests to print more info when they fail. So, I don't think that it's a big deal if they get delayed while we wait and see if we can get the built-in assertions improved, and if the built-in assertions do get improved, then we'll never need the custom ones anyway.

- Jonathan M Davis
October 02, 2015
On 10/02/2015 02:47 AM, deadalnix wrote:
> ...
>   - assert already have a fair amount of magic, notably assert(0) change
> the way control flow works.

Yes, and it is not stellar design. Generally, if it is not possible to wrap a statement or expression in a function without changing its semantics, the language provides too much magic and insufficient abstraction capabilities. (Of course, in practice, there might be legitimate reasons to deviate from this principle, but less often than one might think.)

> Having it as an expression is making
> everything very convoluted for no reason.

What is the problem with assert expressions?
October 02, 2015
On 2015-10-02 08:31, Per Nordlöw wrote:

> Could explain what you mean by *lowering*, please?

"lowering" means that a feature is implemented using another feature. For example, "foreach" is lowered to a for-loop:

foreach(i ; 0 .. 10){}

Is lowered to:

for (int i = 0; i < 10; i++) {}

The compiler rewrites the AST of the foreach-loop to the same AST that the corresponding for-loop would have. After that lowering step, the compiler doesn't need to know anything about foreach-loops.

-- 
/Jacob Carlborg
October 02, 2015
On 2015-10-02 11:32, Atila Neves wrote:

> I like the idea, I just have a practical question on
> std.experimental.testing: should it go ahead as-is?

Yes, as-is. That's the whole point of std.experimental.

-- 
/Jacob Carlborg
October 02, 2015
On 10/02/2015 02:31 AM, Per Nordlöw wrote:
> On Thursday, 1 October 2015 at 19:04:51 UTC, Andrei Alexandrescu wrote:
>> * I don't think we need a new flag, just make the new behavior work.
>
> So you mean that extra diagnostics should kick in when extra overloads
> are made visible via import of, for instance, `core.assert`?
>
>> * Should the lowering happen only on the function called if the
>> assertion actually fails? Then no more need for laziness and other
>> complications.
>
> Could explain what you mean by *lowering*, please?

Rewrite proposed constructs into simpler constructs that already exist. That way we don't need to invent semantics, just "see lowering".

> I'm currently unsure whether
>      in L lhs
> or
>      lazy L lhs

That's why I think it's better to go with calling the function only after the assertion has failed. E.g.,

assert(e1 == e2)

could be lowered into:

{
  auto a = e1, b = e2;
  if (a == b) return;
  onAssertFailed!"=="(a, b, __FILE__, __LINE__, __FUNCTION__, __MODULE__);
}()

or something similar (I'm glossing over the details). Point is the expressions are only evaluated once and then passed into onAssertFailed.

There'd be a default definition of onAssertFailed in object.d.

> should be used and whether or not we should use
>      version(assert)

Yah, all expansions related to assert() are only in effect if assertions are used. Otherwise, assert disappears and that's not configurable.

> See the added example at
> http://wiki.dlang.org/DIP83
>
>> * Extend to other expressions (!=, ordering etc).
>
> How should we categorize expressions? Like this
> - Unary: assert(x UNOP y)
> - Binary: assert(x BINOP y)
> - Function Calls: assert(f(x,y))
> - Other: assert(x)
>
> Does it suffice to just mention these or should I be explicit exactly
> about which operators for each category that should be included?

I think you should use the names of the grammatical constructs, e.g. http://dlang.org/expression.html#EqualExpression.


Andrei
October 02, 2015
On 10/02/2015 05:32 AM, Atila Neves wrote:
>
> I like the idea, I just have a practical question on
> std.experimental.testing: should it go ahead as-is? Should the custom
> assertions be removed and the rest kept? Should they go in as-is and
> then deleted when/if this DIP is implemented?

As long as it's in experimental, proceed as you find fit. We can decide later whether changes are in order. -- Andrei
October 02, 2015
On Friday, 2 October 2015 at 11:22:00 UTC, Andrei Alexandrescu wrote:
> On 10/02/2015 05:32 AM, Atila Neves wrote:
>>
>> I like the idea, I just have a practical question on
>> std.experimental.testing: should it go ahead as-is? Should the custom
>> assertions be removed and the rest kept? Should they go in as-is and
>> then deleted when/if this DIP is implemented?
>
> As long as it's in experimental, proceed as you find fit. We can decide later whether changes are in order. -- Andrei

That's what I was hoping for. Good, unless anybody has comments to make on the current state of the PR, I'll leave everything as it is now.

Atila
October 02, 2015
On Friday, 2 October 2015 at 11:54:31 UTC, Atila Neves wrote:
> That's what I was hoping for. Good, unless anybody has comments to make on the current state of the PR, I'll leave everything as it is now.

Fine with me :)
October 02, 2015
On Friday, 2 October 2015 at 11:19:51 UTC, Andrei Alexandrescu wrote:
> assert(e1 == e2)
>
> could be lowered into:
>
> {
>   auto a = e1, b = e2;
>   if (a == b) return;
>   onAssertFailed!"=="(a, b, __FILE__, __LINE__, __FUNCTION__, __MODULE__);
> }()

So lowering is kind of like macro expansion for AST-nodes, then?

Is DMD clever enough to avoid trigger postblits for

>   auto a = e1, b = e2;
>   if (a == b) return;

? Or is that part of the question whether this will work?

I guess we only need on symbol name for `onAssertFailed` then instead of `assertBinOp` and `assertUnOp`, right?