Jump to page: 1 2 3
Thread overview
Is there any hope for "lazy" and @nogc?
Jul 31, 2018
Shachar Shemesh
Jul 31, 2018
rikki cattermole
Jul 31, 2018
Mike Franklin
Jul 31, 2018
Shachar Shemesh
Jul 31, 2018
Guillaume Boucher
Jul 31, 2018
Seb
Jul 31, 2018
Jacob Carlborg
Jul 31, 2018
ag0aep6g
Aug 01, 2018
Shachar Shemesh
Aug 01, 2018
Shachar Shemesh
Aug 01, 2018
Iain Buclaw
Aug 02, 2018
Seb
Aug 03, 2018
Iain Buclaw
Aug 02, 2018
Shachar Shemesh
Aug 04, 2018
Jacob Carlborg
Aug 04, 2018
Jacob Carlborg
Aug 05, 2018
Nick Treleaven
Aug 05, 2018
Jacob Carlborg
July 31, 2018
I'm trying to figure out what's the signature of the built-in assert. It does not seem that I can define a similar function myself.

First attempt:
void myAssert(bool cond, string msg) @nogc nothrow;

No, because msg gets evaluated unconditionally.

void myAssert(bool cond, lazy string msg) @nogc nothrow;

test.d(8): Error: @nogc function test.myAssert cannot call non-@nogc delegate msg

void myAssert(bool cond, lazy string msg @nogc nothrow ) @nogc nothrow;

test.d(4): Error: found @ when expecting )
test.d(4): Error: semicolon expected following function declaration
test.d(4): Error: no identifier for declarator nogc
test.d(4): Error: declaration expected, not )
test.d(9): Error: unrecognized declaration

Templates to the rescue!!!
void myAssert(STR)(bool cond, lazy STR msg );

test.d(14): Error: @nogc function D main cannot call non-@nogc function test.myAssert!string.myAssert

Help??

Shachar
July 31, 2018
On 31/07/2018 7:17 PM, Shachar Shemesh wrote:
> I'm trying to figure out what's the signature of the built-in assert. It does not seem that I can define a similar function myself.

That is because it isn't a function.
It's a language feature that is backed by functions.
July 31, 2018
On Tuesday, 31 July 2018 at 07:17:34 UTC, Shachar Shemesh wrote:
> I'm trying to figure out what's the signature of the built-in assert. It does not seem that I can define a similar function myself.
>
> Help??
>

I'm not sure why you want a different assert, but you can consider these options.

1) Assign your own assert handler:  https://github.com/dlang/druntime/blob/52d3fe02272d16d32c150ce6f78bc00241a9dd5d/src/core/exception.d#L393

2) You can provide your own implementations of the runtime hooks at https://github.com/dlang/druntime/blob/cb5efa9854775c5a72acd6870083b16e5ebba369/src/core/exception.d#L628

extern(C) void _d_assertp(immutable(char)* file, uint line)
{
    import core.stdc.stdio;
    printf("Houston, we have a problem at %s:%u\n", file, line);
}

void main()
{
    assert(false);
}

https://run.dlang.io/is/QZEO9W

3) -betterC seems to forward runtime assertions to the C implementation.  See https://run.dlang.io/is/QZEO9W

For that you have to provide a new implementation of `__assert`:

extern(C) void __assert(const char *msg, const char *file, int line)
{
    import core.stdc.stdio;
    printf("Houston, we have a problem at %s:%u\n", file, line);
}

extern(C) void main()
{
    assert(false);
}

https://run.dlang.io/is/D5JxCT

4) Otherwise can't you just implement two `myAssert` overloads?

`void assert(bool condition, string msg);`
`void assert(bool condition)`

Please clarify if I'm missing the point.

Mike
July 31, 2018
On 31/07/18 10:29, Mike Franklin wrote:
> Please clarify if I'm missing the point.

You are. I want something along the lines of:
assertEQ(a, b, "a and b are not equal");

When run, it would issue an assert that says:
Assertion failed: 3!=7: a and b are not equal

Hooking it later is not an option. I am actually interested in a different assert like function.

Whether for asserts or otherwise, the "lazy" feature is completely incompatible with function attributes, and that's not good.

Shachar
July 31, 2018
On Tuesday, 31 July 2018 at 07:49:40 UTC, Shachar Shemesh wrote:
> On 31/07/18 10:29, Mike Franklin wrote:
>> Please clarify if I'm missing the point.
>
> You are. I want something along the lines of:
> assertEQ(a, b, "a and b are not equal");
>
> When run, it would issue an assert that says:
> Assertion failed: 3!=7: a and b are not equal

What D really needs is power asserts.  assertEQ's and its companions (assertLT, assertLE, ...) feel just like hacks.

Power asserts come from Groovy and look like this (http://groovy-lang.org/semantics.html#_power_assertion):

assert calc(x,y) == [x,z].sum()
       |    | |  |   | |  |
       15   2 7  |   2 5  7
                 false

A poorer version exists in C++ (https://www.boost.org/doc/libs/1_67_0/libs/test/doc/html/boost_test/testing_tools/boost_test_universal_macro.html)
and of course any language with decent metaprogramming facilities can implement them as a library solution (such as Rust: https://github.com/gifnksm/power-assert-rs and Go: https://github.com/ToQoz/gopwt).
If you can not go the route of metaprogramming, provide an assert backend (Javascript: https://github.com/power-assert-js/power-assert).
D needs something like this as well, and you can not get there just with lazy.
July 31, 2018
On 2018-07-31 09:17, Shachar Shemesh wrote:
> I'm trying to figure out what's the signature of the built-in assert. It
> does not seem that I can define a similar function myself.
>
> First attempt:
> void myAssert(bool cond, string msg) @nogc nothrow;
>
> No, because msg gets evaluated unconditionally.
>
> void myAssert(bool cond, lazy string msg) @nogc nothrow;
>
> test.d(8): Error: @nogc function test.myAssert cannot call non-@nogc
> delegate msg
>
> void myAssert(bool cond, lazy string msg @nogc nothrow ) @nogc nothrow;
>
> test.d(4): Error: found @ when expecting )
> test.d(4): Error: semicolon expected following function declaration
> test.d(4): Error: no identifier for declarator nogc
> test.d(4): Error: declaration expected, not )
> test.d(9): Error: unrecognized declaration
>
> Templates to the rescue!!!
> void myAssert(STR)(bool cond, lazy STR msg );
>
> test.d(14): Error: @nogc function D main cannot call non-@nogc function
> test.myAssert!string.myAssert

It seems this is a limitation in the syntax. It works with an explicit delegate, but then that is required at the call site as well. A lazy parameter is basically just a delegate with a nicer syntax.

void myAssert(bool cond, string delegate() @nogc nothrow msg) @nogc nothrow
{
    auto a = msg();
}

Support for adding UDAs to function parameters was recently added. Perhaps we need to support other attributes as well.

Please report an issue to http://issues.dlang.org.

-- 
/Jacob Carlborg
July 31, 2018
On Tuesday, 31 July 2018 at 07:49:40 UTC, Shachar Shemesh wrote:
> On 31/07/18 10:29, Mike Franklin wrote:
>> Please clarify if I'm missing the point.
>
> You are. I want something along the lines of:
> assertEQ(a, b, "a and b are not equal");
> When run, it would issue an assert that says:
> Assertion failed: 3!=7: a and b are not equal

You could also vote for this PR (https://github.com/dlang/dmd/pull/8517) - this PR will generate such error messages. It's intended to work in -betterC and @nogc (once the PR is ready).
July 31, 2018
On 7/31/18 3:17 AM, Shachar Shemesh wrote:
> I'm trying to figure out what's the signature of the built-in assert. It does not seem that I can define a similar function myself.
> 
> First attempt:
> void myAssert(bool cond, string msg) @nogc nothrow;
> 
> No, because msg gets evaluated unconditionally.
> 
> void myAssert(bool cond, lazy string msg) @nogc nothrow;
> 
> test.d(8): Error: @nogc function test.myAssert cannot call non-@nogc delegate msg

Hm... I would say compiler should be smart enough to know that lazy string messages that are not @nogc shouldn't be able to be passed in here.

e.g.:

myAssert(a == b, "a and b should be equal); // ok
myAssert(a == b, a.name ~ " and " ~ b.name ~ " should be equal"); // error

It appears that lazy is not inferring anything, it's strictly transformed into a normal delegate. I'd say at least the template solution should be made to work.

-Steve
July 31, 2018
On 07/31/2018 09:17 AM, Shachar Shemesh wrote:
> I'm trying to figure out what's the signature of the built-in assert. It does not seem that I can define a similar function myself.

Looks like you can do it with a "lazy variadic function" [1], but it's not pretty:

----
alias Dg = string delegate() @nogc nothrow;

void myAssert(bool cond, Dg[1] msg_dg ...) @nogc nothrow
{
    import core.stdc.stdio;
    if (!cond)
    {
        string msg = msg_dg[0]();
        printf("%*s\n", msg.length, msg.ptr);
    }
}
----

[1] https://dlang.org/spec/function.html#lazy_variadic_functions
August 01, 2018
Thank you! Finally!

Let me just state, for the record, that having *yet another* syntax special case is just appalling.

With that said, I was hoping that specifying it explicitly as a delegate would allow me to scope it. Apparently, that doesn't work :-(

Shachar

On 31/07/18 23:03, ag0aep6g wrote:
> On 07/31/2018 09:17 AM, Shachar Shemesh wrote:
>> I'm trying to figure out what's the signature of the built-in assert. It does not seem that I can define a similar function myself.
> 
> Looks like you can do it with a "lazy variadic function" [1], but it's not pretty:
> 
> ----
> alias Dg = string delegate() @nogc nothrow;
> 
> void myAssert(bool cond, Dg[1] msg_dg ...) @nogc nothrow
> {
>      import core.stdc.stdio;
>      if (!cond)
>      {
>          string msg = msg_dg[0]();
>          printf("%*s\n", msg.length, msg.ptr);
>      }
> }
> ----
> 
> [1] https://dlang.org/spec/function.html#lazy_variadic_functions

« First   ‹ Prev
1 2 3