digitalmars.D - D beginner's article about D's Metaprogramming and Testing
- Renato (8/8) Dec 17 2023 Hi.
- aberba (9/21) Dec 17 2023 ...is exactly why I love D. It's the only system programming
- monkyyy (6/14) Dec 18 2023 assuming your are trying to be a resource, I'd focus more on
- Sergey (2/10) Dec 19 2023 Nice article! Thanks for sharing it :)
- Mike Shah (3/11) Dec 19 2023 Very nice -- might I recommend adding to the wiki here?
- Steven Schveighoffer (22/29) Dec 19 2023 Some comments:
- Renato (36/56) Dec 20 2023 Hm, I meant that the `if` condition, which was `static if (is(T:
- Steven Schveighoffer (23/65) Dec 20 2023 From your later message:
- Renato (7/19) Dec 20 2023 I've edited the post to clarify this.
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
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
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
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
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
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-dlangExcellent!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
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-checkactionThat 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). -SteveDidn'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
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!From your later message:Regarding more descriptive unittests, try out the compiler parameter `-checkaction=context` to get more descriptive asserts: https://dlang.org/dmd-osx.html#switch-checkactionThat 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?!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"?!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. -Stevethere 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; ```
Dec 20 2023
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:I've edited the post to clarify this.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).Regarding more descriptive unittests, try out the compiler parameter `-checkaction=context` to get more descriptive asserts: https://dlang.org/dmd-osx.html#switch-checkactionI 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