www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - D beginner's article about D's Metaprogramming and Testing

reply Renato <renato athaydes.com> writes:
Hi.

I'm new to D and after playing around with D a bit I decided to 
publish my thoughts about the language, focusing on its 
metaprogramming and testing support.

https://renato.athaydes.com/posts/testing-dlang

I would be interested in feedback and corrections from more 
experienced D enthusiasts :).

Hope you like it!
Dec 17 2023
next sibling parent aberba <karabutaworld gmail.com> writes:
On Sunday, 17 December 2023 at 21:51:59 UTC, Renato wrote:
 Hi.

 I'm new to D and after playing around with D a bit I decided to 
 publish my thoughts about the language, focusing on its 
 metaprogramming and testing support.

 https://renato.athaydes.com/posts/testing-dlang

 I would be interested in feedback and corrections from more 
 experienced D enthusiasts :).

 Hope you like it!
This:
 D seems like a good balance. It looks familiar while having 
 some very interesting features. It’s been around long enough 
 that it’s no longer trying to find itself and changing every 6 
 months.
...is exactly why I love D. It's the only system programming language that's a joy to write. Also, unlike others wanting D to change, I personally like that the focus in on stability and improvements. I'm addition, I want code written 8yrs ago to still work. I wanted dub packages to still work even with update for the next 8yrs+.
Dec 17 2023
prev sibling next sibling parent monkyyy <crazymonkyyy gmail.com> writes:
On Sunday, 17 December 2023 at 21:51:59 UTC, Renato wrote:
 Hi.

 I'm new to D and after playing around with D a bit I decided to 
 publish my thoughts about the language, focusing on its 
 metaprogramming and testing support.

 https://renato.athaydes.com/posts/testing-dlang

 I would be interested in feedback and corrections from more 
 experienced D enthusiasts :).

 Hope you like it!
assuming your are trying to be a resource, I'd focus more on template specialization, the variadic functions, and op overloads; before mixin templates. Mixin templates are more "walter doesnt like templates that work like this so they are ugly and require 2 keywords now"
Dec 18 2023
prev sibling next sibling parent Sergey <kornburn yandex.ru> writes:
On Sunday, 17 December 2023 at 21:51:59 UTC, Renato wrote:
 Hi.

 I'm new to D and after playing around with D a bit I decided to 
 publish my thoughts about the language, focusing on its 
 metaprogramming and testing support.

 https://renato.athaydes.com/posts/testing-dlang

 I would be interested in feedback and corrections from more 
 experienced D enthusiasts :).

 Hope you like it!
Nice article! Thanks for sharing it :)
Dec 19 2023
prev sibling next sibling parent Mike Shah <mshah.475 gmail.com> writes:
On Sunday, 17 December 2023 at 21:51:59 UTC, Renato wrote:
 Hi.

 I'm new to D and after playing around with D a bit I decided to 
 publish my thoughts about the language, focusing on its 
 metaprogramming and testing support.

 https://renato.athaydes.com/posts/testing-dlang

 I would be interested in feedback and corrections from more 
 experienced D enthusiasts :).

 Hope you like it!
Very nice -- might I recommend adding to the wiki here? https://wiki.dlang.org/Articles#Metaprogramming
Dec 19 2023
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On Sunday, 17 December 2023 at 21:51:59 UTC, Renato wrote:
 Hi.

 I'm new to D and after playing around with D a bit I decided to 
 publish my thoughts about the language, focusing on its 
 metaprogramming and testing support.

 https://renato.athaydes.com/posts/testing-dlang
Excellent!
 I would be interested in feedback and corrections from more 
 experienced D enthusiasts :).
Some comments: "static if is an if block that’s executed at compile-time… it doesn’t exist at runtime." I see what you are going for, but the static if *block* is included or excluded based on what the compile-time condition is. The *condition* is executed at compile time, and if the condition is true, the block exists, if not, it doesn't exist. But in the case of your code, clearly the block exists at runtime (you are adding 2 runtime values together). Regarding more descriptive unittests, try out the compiler parameter `-checkaction=context` to get more descriptive asserts: https://dlang.org/dmd-osx.html#switch-checkaction there are also options to build your own unittest runner, see https://dlang.org/phobos/core_runtime.html#.Runtime.extendedModuleUnitTester While this gives you only granularity of the module-level unittests, it allows you to do things like select only certain modules to run. And you do not need to build compile-time lists of all unittests yourself, the compiler links it all together for you (see the example in that function on what the default does). -Steve
Dec 19 2023
next sibling parent reply Renato <renato athaydes.com> writes:
On Tuesday, 19 December 2023 at 23:56:59 UTC, Steven 
Schveighoffer wrote:
 "static if is an if block that’s executed at compile-time… it 
 doesn’t exist at runtime."

 I see what you are going for, but the static if *block* is 
 included or excluded based on what the compile-time condition 
 is. The *condition* is executed at compile time, and if the 
 condition is true, the block exists, if not, it doesn't exist. 
 But in the case of your code, clearly the block exists at 
 runtime (you are adding 2 runtime values together).
Hm, I meant that the `if` condition, which was `static if (is(T: double))`, is evaluated at compile-time and hence, "disappears" at runtime. Did you interpret that as "the whole if block disappears at runtime"? If so, how can I make that clearer that I am talking about the if check, not the branch which gets executed? Perhaps "static if is evaluated at compile-time, and only the branch that executes is present at runtime, i.e. the if condition itself doesn't exist at runtime"?
 Regarding more descriptive unittests, try out the compiler 
 parameter `-checkaction=context` to get more descriptive 
 asserts: https://dlang.org/dmd-osx.html#switch-checkaction
That would be awesome! But it seems there's some problem on my machine: ``` dmd -L-ld_classic -unittest -checkaction=context -run main.d Undefined symbols for architecture x86_64: "__D4core8internal7dassert__T24miniFormatFakeAttributesTiZQB FNaNbNiNfMKxiZAya", referenced from: __D4core8internal7dassert__T14_d_assert_failTxiZ__TQxTiZQBcFNaNb iNfMxAyaMKxiMxiZAya in main.o __D4core8internal7dassert__T14_d_assert_failTmZ__TQwTiZQBbFNaNb iNfMxAyaMKxmMxiZAya in main.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) Error: linker exited with status 1 Compilation exited abnormally with code 1 at Wed Dec 20 19:34:11 ``` Do you know what this may be? Looks like the Mac OS's linker just doesn't work well with the DMD compiler?!
 there are also options to build your own unittest runner, see 
 https://dlang.org/phobos/core_runtime.html#.Runtime.extendedModuleUnitTester

 While this gives you only granularity of the module-level 
 unittests, it allows you to do things like select only certain 
 modules to run. And you do not need to build compile-time lists 
 of all unittests yourself, the compiler links it all together 
 for you (see the example in that function on what the default 
 does).

 -Steve
Didn't I mention that in my blog post? Or is this not the same as that example where I showed this: ```d Runtime.moduleUnitTester = &tester; ``` Thanks for the feedback, and thanks everyone for the kind words! I really appreciated it :)
Dec 20 2023
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On Wednesday, 20 December 2023 at 18:39:12 UTC, Renato wrote:
 Perhaps "static if is evaluated at compile-time, and only the 
 branch that executes is present at runtime, i.e. the if 
 condition itself doesn't exist at runtime"?
Looks better now!
 Regarding more descriptive unittests, try out the compiler 
 parameter `-checkaction=context` to get more descriptive 
 asserts: https://dlang.org/dmd-osx.html#switch-checkaction
That would be awesome! But it seems there's some problem on my machine: ``` dmd -L-ld_classic -unittest -checkaction=context -run main.d Undefined symbols for architecture x86_64: "__D4core8internal7dassert__T24miniFormatFakeAttributesTiZQB FNaNbNiNfMKxiZAya", referenced from: __D4core8internal7dassert__T14_d_assert_failTxiZ__TQxTiZQBcFNaNb iNfMxAyaMKxiMxiZAya in main.o __D4core8internal7dassert__T14_d_assert_failTmZ__TQwTiZQBbFNaNb iNfMxAyaMKxmMxiZAya in main.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) Error: linker exited with status 1 Compilation exited abnormally with code 1 at Wed Dec 20 19:34:11 ``` Do you know what this may be? Looks like the Mac OS's linker just doesn't work well with the DMD compiler?!
From your later message:
 I got this working, obviously I forgot the -main flag before... 
 too many flags to remember, I need to start using dub I suppose.
Great to hear, but man that is a *terrible* error message for such a thing! I wonder why this is the result? And what is "miniFormatFakeAttributes"?!
 there are also options to build your own unittest runner, see 
 https://dlang.org/phobos/core_runtime.html#.Runtime.extendedModuleUnitTester

 While this gives you only granularity of the module-level 
 unittests, it allows you to do things like select only certain 
 modules to run. And you do not need to build compile-time 
 lists of all unittests yourself, the compiler links it all 
 together for you (see the example in that function on what the 
 default does).
Didn't I mention that in my blog post? Or is this not the same as that example where I showed this: ```d Runtime.moduleUnitTester = &tester; ```
First, I did not see that you are using the module unit tester assignment, though it does make sense because that's how you override it. But I should clarify that it is possible to override the unittest tester *and still* use the module unittests provided by the compiler. What you get is a function pointer per module to the unittest aggregate that calls all the individual unittests. And of course you have the module name. So for example, if you wanted to catalog which modules run unittests, you do not need to use __traits(getUnittests). If you wanted to only run unittests from a given module/package based on runtime args, that also is possible. And the further advantage is that it works without having to use compile-time introspection to build the tester (i.e. you don't have to import all the testable modules). I hope this makes things a bit clearer. -Steve
Dec 20 2023
prev sibling parent Renato <renato athaydes.com> writes:
On Tuesday, 19 December 2023 at 23:56:59 UTC, Steven 
Schveighoffer wrote:
 On Sunday, 17 December 2023 at 21:51:59 UTC, Renato wrote:
 Hi.
I see what you are going for, but the static if *block* is included or excluded based on what the compile-time condition is. The *condition* is executed at compile time, and if the condition is true, the block exists, if not, it doesn't exist. But in the case of your code, clearly the block exists at runtime (you are adding 2 runtime values together).
I've edited the post to clarify this.
 Regarding more descriptive unittests, try out the compiler 
 parameter `-checkaction=context` to get more descriptive 
 asserts: https://dlang.org/dmd-osx.html#switch-checkaction
I got this working, obviously I forgot the `-main` flag before... too many flags to remember, I need to start using dub I suppose. Also, added a note mentioning this and linked to your post. Thanks!
Dec 20 2023