Thread overview | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
July 31, 2018 Is there any hope for "lazy" and @nogc? | ||||
---|---|---|---|---|
| ||||
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 Re: Is there any hope for "lazy" and @nogc? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Shachar Shemesh | 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 Re: Is there any hope for "lazy" and @nogc? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Shachar Shemesh | 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 Re: Is there any hope for "lazy" and @nogc? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Franklin | 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 Re: Is there any hope for "lazy" and @nogc? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Shachar Shemesh | 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 Re: Is there any hope for "lazy" and @nogc? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Shachar Shemesh | 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 Re: Is there any hope for "lazy" and @nogc? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Shachar Shemesh | 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 Re: Is there any hope for "lazy" and @nogc? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Shachar Shemesh | 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 Re: Is there any hope for "lazy" and @nogc? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Shachar Shemesh | 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 Re: Is there any hope for "lazy" and @nogc? | ||||
---|---|---|---|---|
| ||||
Posted in reply to ag0aep6g | 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
|
Copyright © 1999-2021 by the D Language Foundation