www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - function vs. delegate in a unittest

reply Manfred Nowak <sv1999 hotmail.com> writes:
Because unittests are special functions, the functions declared 
within the body of a unittest have the type of a `delegate'. By 
this the intent to include a unittest for functions with the type 
of a `function' requires the definition of a function outside of 
the body of the unittest.

1: In the docs for unittesting 
https://dlang.org/spec/unittest.html this is a case of usage of 
`version( unittest)' in currently number "7.".

2: Has someone proven, that a super type for `function' and 
`delegate' is not existent or too difficult to implement in the 
compiler? Or is there a good reason for requiring coders to 
manage different versions for both types of functions?
Apr 20
next sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 21/04/2019 6:35 PM, Manfred Nowak wrote:
 Because unittests are special functions, the functions declared within 
 the body of a unittest have the type of a `delegate'. By this the intent 
 to include a unittest for functions with the type of a `function' 
 requires the definition of a function outside of the body of the unittest.
--- void main() { void func() { } pragma(msg, typeof(&func)); } unittest { void func() { } pragma(msg, typeof(&func)); } --- void delegate() pure nothrow nogc safe void delegate() pure nothrow nogc safe vs --- void main() { static void func() { } pragma(msg, typeof(&func)); } unittest { static void func() { } pragma(msg, typeof(&func)); } --- void function() pure nothrow nogc safe void function() pure nothrow nogc safe
Apr 20
parent reply Manfred Nowak <sv1999 hotmail.com> writes:
On Sunday, 21 April 2019 at 06:39:37 UTC, rikki cattermole wrote:
     static void func() {
thy for the hint, that one can use `static' to virtually lift the definition of a function up to the local root of the hierarchy, which makes my oversimplified argument invalid for unittests. But this seems not to solve the underlying problem: unittest{ void f (){} static void fs(){} struct S( T){ T* f; this( T)( T fl){ f= fl; } } //auto sf = new S !( typeof( f ))( &f ); auto sfs= new S !( typeof( fs))( &fs); } Under dmd 2.085.1 this code compiles. But replacing the comment slashes by white space gives an error: cannot implicitly convert expression [...] delegate [...] to function [...] So that's not a problem of unittests but of templates?
Apr 21
next sibling parent reply Meta <jared771 gmail.com> writes:
On Sunday, 21 April 2019 at 08:52:40 UTC, Manfred Nowak wrote:
 Under dmd 2.085.1 this code compiles.
 But replacing the comment slashes by white space gives an error:
   cannot implicitly convert expression
     [...] delegate [...] to function [...]
Are you certain about that? Trying it with the "All dmd compilers" option on run.dlang.io seems to suggest that it won't compile with any version of dmd: https://run.dlang.io/is/MdEpux As per the language rules, your example can't work, because not marking `f` as static means that it will keep a context pointer to the unittest stack frame (unittests are really just functions that get automatically run). Unless you mark it static, or there is some functionality implemented in the future where the compiler can statically determine that f doesn't access anything through its context pointer, and can therefore be converted to a `function` as opposed to a `delegate`, this won't work.
Apr 21
parent Manfred Nowak <sv1999 hotmail.com> writes:
On Sunday, 21 April 2019 at 16:49:54 UTC, Meta wrote:
[...]
 can therefore be converted to a `function`
[...] thy. I know realize, that the error message tempted me onto the wrong track. The error message excluded "implicit" conversions only, but explicit conversions are excluded too by deprecation, which means, that conversions between `delegate' and `function' are currently forbidden in both directions. This reopens number "2." in the original posting.
Apr 21
prev sibling parent Bastiaan Veelo <Bastiaan Veelo.net> writes:
On Sunday, 21 April 2019 at 08:52:40 UTC, Manfred Nowak wrote:
 On Sunday, 21 April 2019 at 06:39:37 UTC, rikki cattermole 
 wrote:
     static void func() {
thy for the hint, that one can use `static' to virtually lift the definition of a function up to the local root of the hierarchy, which makes my oversimplified argument invalid for unittests. But this seems not to solve the underlying problem: unittest{ void f (){} static void fs(){} struct S( T){ T* f; this( T)( T fl){ f= fl; } } //auto sf = new S !( typeof( f ))( &f ); auto sfs= new S !( typeof( fs))( &fs); } Under dmd 2.085.1 this code compiles. But replacing the comment slashes by white space gives an error: cannot implicitly convert expression [...] delegate [...] to function [...] So that's not a problem of unittests but of templates?
This works: unittest { void f (){} static void fs(){} struct S( T){ T f; this( T)( T fl){ f= fl; } } auto sf = new S !( typeof( &f ))( &f ); auto sfs= new S !( typeof( &fs))( &fs); } https://run.dlang.io/is/yu67oN And regarding "requiring coders to manage different versions for both types of functions": there is std.functional.toDelegate, so if you just support delegates, that is enough -- unless you care about safe. Bastiaan.
Apr 21
prev sibling parent ag0aep6g <anonymous example.com> writes:
On 21.04.19 08:35, Manfred Nowak wrote:
 2: Has someone proven, that a super type for `function' and `delegate' 
 is not existent or too difficult to implement in the compiler? Or is 
 there a good reason for requiring coders to manage different versions 
 for both types of functions?
Here's an older thread on how I think functions and delegates could be consolidated pretty easily: https://forum.dlang.org/post/ofc0lj$2u4h$1 digitalmars.com As far as I'm aware, there is nothing fundamentally blocking the feature. But pushing the idea further is in no way a priority for me at the moment. To make it happen, someone would need to implement it in the compiler and convince Walter and Andrei of the change, probably via a DIP.
Apr 21