digitalmars.D.announce - The ABC's of Templates in D
- Mike Parker (16/16) Jul 31 2020 I'm planning to publish several articles and tutorials about D
- =?UTF-8?Q?Ali_=c3=87ehreli?= (13/15) Jul 31 2020 An excellent article and the ideas are delivered expertly, in a very
- Mike Parker (3/18) Jul 31 2020 As usual, thanks! I should start sending all of my blog posts to
- Greatsam4sure (5/21) Jul 31 2020 Thanks for this excellent article. It is really needed. I can't
- Bruce Carneal (6/11) Jul 31 2020 Good writing for the not-quite-beginner-and-up audience Mike.
- Mike Parker (5/11) Jul 31 2020 Thanks! I'm hoping for a few volunteers to step forward to
- H. S. Teoh (118/121) Jul 31 2020 Not sure how blog-worthy this is, but recently I was writing a utility
- Walter Bright (2/3) Jul 31 2020 It is. Please do it!
- Mike Parker (2/4) Jul 31 2020 It is! I'll be in touch :-)
- Martin Tschierschke (38/42) Aug 05 2020 version(DigitalMars){
- Mario =?UTF-8?B?S3LDtnBsaW4=?= (4/6) Jul 31 2020 Minor detail: in "Even shorter syntax" the point is not that the
- Mike Parker (3/9) Jul 31 2020 Thanks! That I didn't think about it when writing this made me
- Mike Parker (3/9) Aug 01 2020 Double thanks! The entirety of the first sentence in that section
- Vijay Nayar (3/5) Aug 07 2020 This is very well written! I want to share it with my coworkers
- =?utf-8?Q?Robert_M._M=C3=BCnch?= (8/10) Aug 29 2020 * Why is it not a member of the template (specification)?
- Mike Parker (6/14) Aug 29 2020 The variable p is declared outside of the template. The type of p
I'm planning to publish several articles and tutorials about D templates over the next few months. As a means of setting the stage, I've published this tutorial on the basics. The blog: https://dlang.org/blog/2020/07/31/the-abcs-of-templates-in-d/ Reddit: https://www.reddit.com/r/programming/comments/i17n5d/the_abcs_of_templates_in_d/ I've got a few more posts on the topic that I intend to write myself, one of which will incorporate Stefan Koch's dive into a template instantiation. But I'm also looking for guest posts demonstrating specific instantiations (heh) of templates in real-world D code. If you've got a code base that uses templates in interesting ways, please get in touch! We do offer a bounty for guest posts, so you can help with a bit of PR and make a bit of cash at the same time.
Jul 31 2020
On 7/31/20 6:46 AM, Mike Parker wrote:The blog: https://dlang.org/blog/2020/07/31/the-abcs-of-templates-in-d/An excellent article and the ideas are delivered expertly, in a very natural way. And there are almost no typos. ;) comfusing -> confusing a normal a function -> a normal function declare first declare -> first declare implemnted -> implemented Ali
Jul 31 2020
On Friday, 31 July 2020 at 15:24:46 UTC, Ali Çehreli wrote:On 7/31/20 6:46 AM, Mike Parker wrote:As usual, thanks! I should start sending all of my blog posts to you before I publish :-)The blog: https://dlang.org/blog/2020/07/31/the-abcs-of-templates-in-d/An excellent article and the ideas are delivered expertly, in a very natural way. And there are almost no typos. ;) comfusing -> confusing a normal a function -> a normal function declare first declare -> first declare implemnted -> implemented Ali
Jul 31 2020
On Friday, 31 July 2020 at 13:46:43 UTC, Mike Parker wrote:I'm planning to publish several articles and tutorials about D templates over the next few months. As a means of setting the stage, I've published this tutorial on the basics. The blog: https://dlang.org/blog/2020/07/31/the-abcs-of-templates-in-d/ Reddit: https://www.reddit.com/r/programming/comments/i17n5d/the_abcs_of_templates_in_d/ I've got a few more posts on the topic that I intend to write myself, one of which will incorporate Stefan Koch's dive into a template instantiation. But I'm also looking for guest posts demonstrating specific instantiations (heh) of templates in real-world D code. If you've got a code base that uses templates in interesting ways, please get in touch! We do offer a bounty for guest posts, so you can help with a bit of PR and make a bit of cash at the same time.Thanks for this excellent article. It is really needed. I can't wait for the rest part. I will also plead with you to let the articles cover the full capability of the D template while making it simple for a newbie to grab it
Jul 31 2020
On Friday, 31 July 2020 at 13:46:43 UTC, Mike Parker wrote:I'm planning to publish several articles and tutorials about D templates over the next few months. As a means of setting the stage, I've published this tutorial on the basics. The blog: https://dlang.org/blog/2020/07/31/the-abcs-of-templates-in-d/Good writing for the not-quite-beginner-and-up audience Mike. Reading it reminded me of how much I had been taking for granted, of how much power D provides with minimal drag. Really hope I never have to go back to C++/CUDA. Also enjoying your book. Looking forward to additional blog posts.
Jul 31 2020
On Friday, 31 July 2020 at 17:55:54 UTC, Bruce Carneal wrote:Good writing for the not-quite-beginner-and-up audience Mike. Reading it reminded me of how much I had been taking for granted, of how much power D provides with minimal drag. Really hope I never have to go back to C++/CUDA. Also enjoying your book. Looking forward to additional blog posts.Thanks! I'm hoping for a few volunteers to step forward to produce some of those additional posts. There's a pile of unpublished D template know-how out there that would make for some interesting reading.
Jul 31 2020
On Fri, Jul 31, 2020 at 01:46:43PM +0000, Mike Parker via Digitalmars-d-announce wrote: [...]If you've got a code base that uses templates in interesting ways, please get in touch! We do offer a bounty for guest posts, so you can help with a bit of PR and make a bit of cash at the same time.Not sure how blog-worthy this is, but recently I was writing a utility that used std.regex extensively, and I wanted to globally initialize all regexes (for performance), but I didn't want to use ctRegex because of onerous compile-time overhead. So my initial solution was to create a global struct `Re`, that declared all regexes as static fields and used a static ctor to initialize them upon startup. Something like this: struct Re { static Regex!char pattern1; static Regex!char pattern2; ... // etc. static this() { pattern1 = regex(`foo(\w+)bar`); pattern2 = regex(`...`); ... // etc. } } auto myFunc(string input) { ... auto result = input.replaceAll(Re.pattern1, `blah $1 bleh`); ... } This worked, but was ugly because (1) there's too much boilerplate to declare each regex and individually initialize them in the static ctor; (2) the definition of each regex was far removed from its usage context, so things like capture indices were hard to read (you had to look at two places in the file at the same time to see the correspondence, like the $1 in the above snippet). Eventually, I came up with this little trick: Regex!char staticRe(string reStr)() { static struct Impl { static Regex!char re; static this() { re = regex(reStr); } } return Impl.re; } auto myFunc(string input) { ... auto result = input.replaceAll(staticRe!"foo(\w+)bar", `blah $1 bleh`); ... } This allowed the regex definition to be right where it's used, making things like capture indices immediately obvious in the surrounding code. Points of interest: 1) staticRe is a template function that takes its argument as a compile-time parameter, but at runtime, it simply returns a globally-initialized regex (so runtime overhead is basically nil at the caller's site, if the compiler inlines the call). 2) The regex is not initialized by ctRegex in order to avoid the compile-time overhead; instead, it's initialized at program startup time. 3) Basically, this is equivalent to a global variable initialized by a module static ctor, but since we can't inject global variables into module scope from a template function, we instead declare a wrapper struct inside the template function (which ensures a unique instantiation -- which also sidesteps the issue of generating unique global variable names at compile-time), with a static field that basically behaves like a global variable. To ensure startup initialization, we use a struct static ctor, which essentially gets concatenated to the list of module-static ctors that are run before main() at runtime. Well, OK, strictly speaking the regex is re-created per thread because it's in TLS. But since this is a single-threaded utility, it's Good Enough(tm). (I didn't want to deal with `shared` or __gshared issues since I don't strictly need it. But in theory you could do that if you needed to.) // Here's a related trick using the same principles that I posted a while ago: a D equivalent of gettext that automatically extracts translatable strings. Basically, something like this: class Language { ... } Language curLang = ...; version(extractStrings) { private int[string] translatableStrings; string[] getTranslatableStrings() { return translatableStrings.keys; } } string gettext(string str)() { version(extractStrings) { static struct StrInjector { static this() { translatableStrings[str]++; } } } return curLang.translate(str); } ... auto myFunc() { ... writeln(gettext!"Some translatable message"); ... } The gettext function uses a static struct to inject a static ctor into the program that inserts all translatable strings into a global AA. Then, when compiled with -version=extractStrings, this will expose the function getTranslatableStrings that returns a list of all translatable strings. Voila! No need for a separate utility to parse source code to discover translatable strings; this does it for you automatically. :-) It could be made more fancy, of course, like having a function that parses the current l10n files and doing a diff between strings that got deleted / added / changed, and generating a report to inform the translator which strings need to be updated. This is guaranteed to be 100% reliable since the extracted strings are obtained directly from actual calls to gettext, rather than a 3rd party parser that may choke over uncommon syntax / unexpected formatting. D is just *this* awesome. T -- Computerese Irregular Verb Conjugation: I have preferences. You have biases. He/She has prejudices. -- Gene Wirchenko
Jul 31 2020
On 7/31/2020 10:57 AM, H. S. Teoh wrote:Not sure how blog-worthy this is,It is. Please do it!
Jul 31 2020
On Friday, 31 July 2020 at 17:57:58 UTC, H. S. Teoh wrote:On Fri, Jul 31, 2020 at 01:46:43PM +0000, Mike Parker viaNot sure how blog-worthy this is,It is! I'll be in touch :-)
Jul 31 2020
On Friday, 31 July 2020 at 17:57:58 UTC, H. S. Teoh wrote: I choosed the following way regarding:2) The regex is not initialized by ctRegex in order to avoid the compile-time overhead; instead, it's initialized at program startup time.version(DigitalMars){ auto reg(alias var)(){ return(regex(var)); pragma(msg,"regex used"); } } version(LDC){ // reg!() is an alias method, which can check which kind of parameter it got auto reg(alias var)(){ static if (__traits(compiles, {enum ctfeFmt = var;}) ){ // "Promotion" to compile time value enum ctfeReg = var ; pragma(msg, "ctRegex used"); return(ctRegex!ctfeReg); }else{ return(regex(var)); pragma(msg,"regex used"); } } } So when compiling with DMD my reg!("....") expression is using the runtime version. When compiling with LDC (for release) I use the ctRegex version, if possible. The (alias var) combined with the check if the var is known at compile time: __traits(compiles, {enum ctfeFmt = var;} I have to admit that the idea was mine, but the crafting only with the help of forum members! // Function to mark all ocurences of the word offshore within html bold. string markoffshore(string to_mark){ return to_mark.replaceAll(reg!(r"([oO]ffshore)"),"<b>$1</b>"); }
Aug 05 2020
On Friday, 31 July 2020 at 13:46:43 UTC, Mike Parker wrote:The blog: https://dlang.org/blog/2020/07/31/the-abcs-of-templates-in-d/Minor detail: in "Even shorter syntax" the point is not that the template has only one parameter, but that the template argument is only one token long (for example, no `char[]`).
Jul 31 2020
On Friday, 31 July 2020 at 22:58:07 UTC, Mario Kröplin wrote:On Friday, 31 July 2020 at 13:46:43 UTC, Mike Parker wrote:Thanks! That I didn't think about it when writing this made me wonder if I noted it in the book.The blog: https://dlang.org/blog/2020/07/31/the-abcs-of-templates-in-d/Minor detail: in "Even shorter syntax" the point is not that the template has only one parameter, but that the template argument is only one token long (for example, no `char[]`).
Jul 31 2020
On Friday, 31 July 2020 at 22:58:07 UTC, Mario Kröplin wrote:On Friday, 31 July 2020 at 13:46:43 UTC, Mike Parker wrote:Double thanks! The entirety of the first sentence in that section was problematic.The blog: https://dlang.org/blog/2020/07/31/the-abcs-of-templates-in-d/Minor detail: in "Even shorter syntax" the point is not that the template has only one parameter, but that the template argument is only one token long (for example, no `char[]`).
Aug 01 2020
On Friday, 31 July 2020 at 13:46:43 UTC, Mike Parker wrote:The blog: https://dlang.org/blog/2020/07/31/the-abcs-of-templates-in-d/This is very well written! I want to share it with my coworkers using Java to see if it piques their interest.
Aug 07 2020
A bit late... but I don't understand this part:"Unlike x, p is not a member of the template. The type Pair is a member, so we can’t refer to it without the prefix."* Why is it not a member of the template (specification)? * Later it is a member... of what if not of the template (specification)? Confusing... -- Robert M. Münch http://www.saphirion.com smarter | better | faster
Aug 29 2020
On Saturday, 29 August 2020 at 09:18:56 UTC, Robert M. Münch wrote:A bit late... but I don't understand this part:The variable p is declared outside of the template. The type of p is a template member, it's declared inside the template, but p itself is not."Unlike x, p is not a member of the template. The type Pair is a member, so we can’t refer to it without the prefix."* Why is it not a member of the template (specification)?* Later it is a member... of what if not of the template (specification)?I don't understand what you mean. p is not a member of anything.Confusing...
Aug 29 2020