www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - Introduction to programming with compile time sequences in D

reply data pulverizer <data.pulverizer gmail.com> writes:
I have a draft new blog article "Introduction to programming with 
compile time sequences in D", it's on Github and I would 
appreciate feedback before it goes live 
https://gist.github.com/dataPulverizer/67193772c52e7bd0a16414cb01ae4250

Comment welcome.

Many thanks
Aug 24 2020
next sibling parent reply Petar Kirov [ZombineDev] <petar.p.kirov gmail.com> writes:
On Tuesday, 25 August 2020 at 02:11:42 UTC, data pulverizer wrote:
 I have a draft new blog article "Introduction to programming 
 with compile time sequences in D", it's on Github and I would 
 appreciate feedback before it goes live 
 https://gist.github.com/dataPulverizer/67193772c52e7bd0a16414cb01ae4250

 Comment welcome.

 Many thanks
Nice article! I haven't had the chance to read it fully, so far now I have just one quick suggestion regarding removing items from sequences [0]. I think it would be much simpler (and likely more efficient) to avoid both recursion and static foreach and simply use slicing + concatenation. Here's an example: template removeFromSeqAt(size_t idx, seq...) { static if (seq.length > 0 && idx < seq.length) alias removeFromSeqAt = AliasSeq!(seq[0 .. idx], seq[idx + 1 .. $]); else static assert (0); } You can find a full example of this here: https://run.dlang.io/gist/run-dlang/80e120e989a6b0f72fd7244b17021e2f [0]: https://gist.github.com/dataPulverizer/67193772c52e7bd0a16414cb01ae4250#removing-items-from-a-compile-time-sequence
Aug 25 2020
next sibling parent data pulverizer <data.pulverizer gmail.com> writes:
On Tuesday, 25 August 2020 at 14:02:33 UTC, Petar Kirov 
[ZombineDev] wrote:
 Nice article! I haven't had the chance to read it fully, so far 
 now I have just one quick suggestion regarding removing items 
 from sequences [0]. I think it would be much simpler (and 
 likely more efficient) to avoid both recursion and static 
 foreach and simply use slicing + concatenation. Here's an 
 example:

 template removeFromSeqAt(size_t idx, seq...)
 {
     static if (seq.length > 0 && idx < seq.length)
     	alias removeFromSeqAt = AliasSeq!(seq[0 .. idx], seq[idx + 
 1 .. $]);
     else
         static assert (0);
 }

 You can find a full example of this here:
 https://run.dlang.io/gist/run-dlang/80e120e989a6b0f72fd7244b17021e2f


 [0]: 
 https://gist.github.com/dataPulverizer/67193772c52e7bd0a16414cb01ae4250#removing-items-from-a-compile-time-sequence
I could probably apply the same thing to some if not all the other template operations. Many Thanks!
Aug 25 2020
prev sibling next sibling parent reply data pulverizer <data.pulverizer gmail.com> writes:
On Tuesday, 25 August 2020 at 14:02:33 UTC, Petar Kirov 
[ZombineDev] wrote:
 Nice article! I haven't had the chance to read it fully, so far 
 [snip]
I though of writing at the beginning that it was long and that readers could dip in and out of the article as they wished but decided that people could decide that for themselves and that placing a length warning might be counter-productive. Thanks
Aug 25 2020
parent reply Petar Kirov [ZombineDev] <petar.p.kirov gmail.com> writes:
On Tuesday, 25 August 2020 at 15:30:17 UTC, data pulverizer wrote:
 On Tuesday, 25 August 2020 at 14:02:33 UTC, Petar Kirov 
 [ZombineDev] wrote:
 Nice article! I haven't had the chance to read it fully, so 
 far [snip]
I though of writing at the beginning that it was long and that readers could dip in and out of the article as they wished but decided that people could decide that for themselves and that placing a length warning might be counter-productive. Thanks
I think your article is quite valuable is it covers many aspects of template programming in D, while being quite approachable as well. May I suggest contributing it in some form to https://tour.dlang.org? Contributing is as easy as opening a pull request to this repo: https://github.com/dlang-tour/english. Just check the format of some of the other *.md and *.yml files there and you'll figure it out. We already have a section on templates there, but I think it's way too brief and doesn't do justice to the D's extensive template features. Perhaps it could be organized as a fully separate section with different articles, corresponding to each paragraph in your article.
Aug 25 2020
next sibling parent reply data pulverizer <data.pulverizer gmail.com> writes:
On Tuesday, 25 August 2020 at 15:58:46 UTC, Petar Kirov 
[ZombineDev] wrote:
 On Tuesday, 25 August 2020 at 15:30:17 UTC, data pulverizer 
 wrote:
 I think your article is quite valuable is it covers many 
 aspects of template programming in D, while being quite 
 approachable as well. May I suggest contributing it in some 
 form to https://tour.dlang.org? Contributing is as easy as 
 opening a pull request to this repo: 
 https://github.com/dlang-tour/english. Just check the format of 
 some of the other *.md and *.yml files there and you'll figure 
 it out.
 We already have a section on templates there, but I think it's 
 way too brief and doesn't do justice to the D's extensive 
 template features. Perhaps it could be organized as a fully 
 separate section with different articles, corresponding to each 
 paragraph in your article.
I'd be happy to work on that!
Aug 25 2020
parent Petar Kirov [ZombineDev] <petar.p.kirov gmail.com> writes:
On Tuesday, 25 August 2020 at 16:04:36 UTC, data pulverizer wrote:
 On Tuesday, 25 August 2020 at 15:58:46 UTC, Petar Kirov 
 [ZombineDev] wrote:
 On Tuesday, 25 August 2020 at 15:30:17 UTC, data pulverizer 
 wrote:
 I think your article is quite valuable is it covers many 
 aspects of template programming in D, while being quite 
 approachable as well. May I suggest contributing it in some 
 form to https://tour.dlang.org? Contributing is as easy as 
 opening a pull request to this repo: 
 https://github.com/dlang-tour/english. Just check the format 
 of some of the other *.md and *.yml files there and you'll 
 figure it out.
 We already have a section on templates there, but I think it's 
 way too brief and doesn't do justice to the D's extensive 
 template features. Perhaps it could be organized as a fully 
 separate section with different articles, corresponding to 
 each paragraph in your article.
I'd be happy to work on that!
Great! Me and the other maintainers and contributors would be happy to assist you. If you want to just start a discussion on how to proceed, perhaps you can open an issue where we can discuss things in more detail. By the way, are you on the https://dlang.slack.com ? If not you should definetely join! I am not able to check all of GitHub notifications these days, so you can ping me and or other people there on Slack if we don't respond in time on GitHub. We have a #tour channel that we can use for discussions.
Aug 25 2020
prev sibling next sibling parent reply data pulverizer <data.pulverizer gmail.com> writes:
On Tuesday, 25 August 2020 at 15:58:46 UTC, Petar Kirov 
[ZombineDev] wrote:
 I think your article is quite valuable is it covers many 
 aspects of template programming in D, while being quite 
 approachable as well. May I suggest contributing it in some 
 form to https://tour.dlang.org? Contributing is as easy as 
 opening a pull request to this repo: 
 https://github.com/dlang-tour/english. Just check the format of 
 some of the other *.md and *.yml files there and you'll figure 
 it out.
 We already have a section on templates there, but I think it's 
 way too brief and doesn't do justice to the D's extensive 
 template features. Perhaps it could be organized as a fully 
 separate section with different articles, corresponding to each 
 paragraph in your article.
Just to keep you updated, I've begun to write a fresh section on templates for dlang-tour quite separate from the blog article - something more appropriate for the website, though I'll take some elements of what I've already done. Once it's finished I'll do a pull request. Thanks
Aug 28 2020
parent reply Petar Kirov [ZombineDev] <petar.p.kirov gmail.com> writes:
On Friday, 28 August 2020 at 11:05:09 UTC, data pulverizer wrote:
 On Tuesday, 25 August 2020 at 15:58:46 UTC, Petar Kirov 
 [ZombineDev] wrote:
 [...]
Just to keep you updated, I've begun to write a fresh section on templates for dlang-tour quite separate from the blog article - something more appropriate for the website, though I'll take some elements of what I've already done. Once it's finished I'll do a pull request. Thanks
Sounds great, thank you!
Aug 28 2020
parent reply data pulverizer <data.pulverizer gmail.com> writes:
On Saturday, 29 August 2020 at 04:41:36 UTC, Petar Kirov 
[ZombineDev] wrote:
 On Friday, 28 August 2020 at 11:05:09 UTC, data pulverizer 
 wrote:
 On Tuesday, 25 August 2020 at 15:58:46 UTC, Petar Kirov 
 [ZombineDev] wrote:
 [...]
Just to keep you updated, I've begun to write a fresh section on templates for dlang-tour quite separate from the blog article - something more appropriate for the website, though I'll take some elements of what I've already done. Once it's finished I'll do a pull request. Thanks
Sounds great, thank you!
I've finished writing the fresh section and checked it through a few times. It is pretty detailed and long and before releasing it and doing a pull request I'll check it through once or twice more over the next day or two. The document content structure is: ``` * Introduction * Templates in D * Function templates * Longhand and shorthand declarations * Inference of parameters * Access patterns for template internals * Alias template parameter * Variadic template functions * The is() directive * More on template constraints and partial specialization * Struct, class, and interface templates * Struct template longhand and shorthand declarations * Variadic template objects * Template constraints and specialization * Enumeration templates * Alias templates * static if * Traits * Metaprogramming in D * Introduction * AliasSeq!(T) compile time sequences * Append, prepend and concatenating compile time lists * Replacing items in compile time sequences * Replacing multiple items with an individual type * String mixins * static foreach * Replacing multiple items by a tuple of items * Contained type sequences * Template mixins, CTFE, and import * Template mixins * CTFE * import("file.d") ``` I have written lots of code examples in the text but there are also lots of runnable files that can be in code demo "play" sections. The only thing is when I look at the current coding area it is quite large and separate from the text. Sometime in the future, I guess it would be great to have it inline with the text and smaller like the regular fenced code so that multiple files can be included in separate scrollable "play" areas. Thanks
Sep 01 2020
parent reply Petar Kirov [ZombineDev] <petar.p.kirov gmail.com> writes:
On Tuesday, 1 September 2020 at 16:00:14 UTC, data pulverizer 
wrote:
 On Saturday, 29 August 2020 at 04:41:36 UTC, Petar Kirov 
 [ZombineDev] wrote:
 On Friday, 28 August 2020 at 11:05:09 UTC, data pulverizer 
 wrote:
 On Tuesday, 25 August 2020 at 15:58:46 UTC, Petar Kirov 
 [ZombineDev] wrote:
 [...]
Just to keep you updated, I've begun to write a fresh section on templates for dlang-tour quite separate from the blog article - something more appropriate for the website, though I'll take some elements of what I've already done. Once it's finished I'll do a pull request. Thanks
Sounds great, thank you!
I've finished writing the fresh section and checked it through a few times. It is pretty detailed and long and before releasing it and doing a pull request I'll check it through once or twice more over the next day or two. The document content structure is: ``` * Introduction * Templates in D * Function templates * Longhand and shorthand declarations * Inference of parameters * Access patterns for template internals * Alias template parameter * Variadic template functions * The is() directive * More on template constraints and partial specialization * Struct, class, and interface templates * Struct template longhand and shorthand declarations * Variadic template objects * Template constraints and specialization * Enumeration templates * Alias templates * static if * Traits * Metaprogramming in D * Introduction * AliasSeq!(T) compile time sequences * Append, prepend and concatenating compile time lists * Replacing items in compile time sequences * Replacing multiple items with an individual type * String mixins * static foreach * Replacing multiple items by a tuple of items * Contained type sequences * Template mixins, CTFE, and import * Template mixins * CTFE * import("file.d") ```
Looking great so far!
 I have written lots of code examples in the text but there are 
 also lots of runnable files that can be in code demo "play" 
 sections. The only thing is when I look at the current coding 
 area it is quite large and separate from the text. Sometime in 
 the future, I guess it would be great to have it inline with 
 the text and smaller like the regular fenced code so that 
 multiple files can be included in separate scrollable "play" 
 areas.

 Thanks
Yeah, I think we should add the following feature: Whenever there's a snippet of code (fenced code block in markdown), a button should appear under, which when clicked would replace the content of the text editor with the code snippet. There two challenges with this: 1. Many of the code snippets that appear throughout the articles are not meant to be runnable, so we would need a way to provide the necessary scaffolding (e.g. wrap them in `void main() { /+ ... +/ }`) 2. It may surprising and inconvenient for users to have the code they have potentially modified disappear. This could be solved by adding proper support for multiple open files to the editor (along the lines of commercial solutions like codesandbox, github workspaces, etc.). What would happen is that click [Edit] on a code-block would simply open another file.
Sep 01 2020
parent reply data pulverizer <data.pulverizer gmail.com> writes:
On Tuesday, 1 September 2020 at 16:24:29 UTC, Petar Kirov 
[ZombineDev] wrote:
 Yeah, I think we should add the following feature:
 Whenever there's a snippet of code (fenced code block in 
 markdown), a button should appear under, which when clicked 
 would replace the content of the text editor with the code 
 snippet.

 There two challenges with this:
 1. Many of the code snippets that appear throughout the 
 articles are not meant to be runnable, so we would need a way 
 to provide the necessary scaffolding (e.g. wrap them in `void 
 main() { /+ ... +/ }`)
I think there should be two kinds of code area. i. The regular "dumb code" fences (as we already have) which is just for displaying code. I have lots of these throughout my text, the code they contain are in general not runnable because they are designed to show only part of it or some output for discussion. ii. Runnable code areas for actual scripts, the same width and in line with the text like the "dumb code" fences but as you said with a few buttons on the top for running the code (I'm not really bothered if they can pop out to another window/tab and so on). They should be scrollable because you don't want a huge amount of code just pasted in going potentially over one or more pages long. I wonder if that is doable?
 2. It may surprising and inconvenient for users to have the 
 code they have potentially modified disappear. This could be 
 solved by adding proper support for multiple open files to the 
 editor (along the lines of commercial solutions like 
 codesandbox, github workspaces, etc.). What would happen is 
 that click [Edit] on a code-block would simply open another 
 file.
I leave that to your expertise. The main thing is that people should be able to run and/or modify the code, and that the original content comes back on reload. I'm not sure it needs to be super-robust in terms of storing everything from the user because it's not a proper development area, only for learning. [:shrug:]
Sep 01 2020
parent data pulverizer <data.pulverizer gmail.com> writes:
On Tuesday, 1 September 2020 at 17:12:05 UTC, data pulverizer 
wrote:
 ii. Runnable code areas for actual scripts, the same width and 
 in line with the text like the "dumb code" fences but as you 
 said with a few buttons on the top for running the code (I'm 
 not really bothered if they can pop out to another window/tab 
 and so on). They should be scrollable because you don't want a 
 huge amount of code just pasted in going potentially over one 
 or more pages long.
p.s. The nice thing about having something like this is that you build up a theme throughout the writing and regular code areas and then have the live demo area and carry on with another related theme and have another live demo in the same page and so forth - a bit like a Jupyter notebook where it flows nicely with the text for the reader who can scroll up and down to view different things.
Sep 01 2020
prev sibling parent data pulverizer <data.pulverizer gmail.com> writes:
On Tuesday, 25 August 2020 at 15:58:46 UTC, Petar Kirov 
[ZombineDev] wrote:
 I think your article is quite valuable is it covers many 
 aspects of template programming in D, while being quite 
 approachable as well. May I suggest contributing it in some 
 form to https://tour.dlang.org? Contributing is as easy as 
 opening a pull request to this repo: 
 https://github.com/dlang-tour/english. Just check the format of 
 some of the other *.md and *.yml files there and you'll figure 
 it out.
 We already have a section on templates there, but I think it's 
 way too brief and doesn't do justice to the D's extensive 
 template features. Perhaps it could be organized as a fully 
 separate section with different articles, corresponding to each 
 paragraph in your article.
I've written a more comprehensive tutorial for generic and compile time programming in D, and submitted a pull request to replace the current template material in the tour: https://github.com/dlang-tour/english/pull/341 Thanks.
Sep 03 2020
prev sibling parent reply data pulverizer <data.pulverizer gmail.com> writes:
On Tuesday, 25 August 2020 at 14:02:33 UTC, Petar Kirov 
[ZombineDev] wrote:
 ...
 You can find a full example of this here:
 https://run.dlang.io/gist/run-dlang/80e120e989a6b0f72fd7244b17021e2f
There is an issue with `AliasTuple` though, you can't directly print its collections with pragma: ```d alias coll = AliasSeq!(s1, s2, s3, s7); pragma(msg, coll); ``` I get the following error: ```d onlineapp.d(29): Error: cannot interpret AliasTuple!1 at compile time onlineapp.d(29): Error: cannot interpret AliasTuple!(1, 2) at compile time ... tuple((__error), (__error), (__error), (__error)) ```
Aug 25 2020
next sibling parent reply data pulverizer <data.pulverizer gmail.com> writes:
On Tuesday, 25 August 2020 at 16:01:25 UTC, data pulverizer wrote:
 On Tuesday, 25 August 2020 at 14:02:33 UTC, Petar Kirov 
 [ZombineDev] wrote:
 ...
 You can find a full example of this here:
 https://run.dlang.io/gist/run-dlang/80e120e989a6b0f72fd7244b17021e2f
There is an issue with `AliasTuple` though, you can't directly print its collections with pragma: ```d alias coll = AliasSeq!(s1, s2, s3, s7); pragma(msg, coll); ``` I get the following error: ```d onlineapp.d(29): Error: cannot interpret AliasTuple!1 at compile time onlineapp.d(29): Error: cannot interpret AliasTuple!(1, 2) at compile time ... tuple((__error), (__error), (__error), (__error)) ```
p.s. I did include a `Tuple` - like implementation in my article at the later sections, but it was based on a template struct.
Aug 25 2020
next sibling parent data pulverizer <data.pulverizer gmail.com> writes:
On Tuesday, 25 August 2020 at 16:10:21 UTC, data pulverizer wrote:
 On Tuesday, 25 August 2020 at 16:01:25 UTC, data pulverizer 
 wrote:
 On Tuesday, 25 August 2020 at 14:02:33 UTC, Petar Kirov 
 [ZombineDev] wrote:
 ...
 You can find a full example of this here:
 https://run.dlang.io/gist/run-dlang/80e120e989a6b0f72fd7244b17021e2f
There is an issue with `AliasTuple` though, you can't directly print its collections with pragma: ```d alias coll = AliasSeq!(s1, s2, s3, s7); pragma(msg, coll); ``` I get the following error: ```d onlineapp.d(29): Error: cannot interpret AliasTuple!1 at compile time onlineapp.d(29): Error: cannot interpret AliasTuple!(1, 2) at compile time ... tuple((__error), (__error), (__error), (__error)) ```
p.s. I did include a `Tuple` - like implementation in my article at the later sections, but it was based on a template struct.
Fixed it, using this now works: ```d template AliasTuple(seq...) { struct AliasTuple { alias expand = seq; enum length = seq.length; } } ```
Aug 25 2020
prev sibling parent Petar Kirov [ZombineDev] <petar.p.kirov gmail.com> writes:
On Tuesday, 25 August 2020 at 16:10:21 UTC, data pulverizer wrote:
 On Tuesday, 25 August 2020 at 16:01:25 UTC, data pulverizer 
 wrote:
 On Tuesday, 25 August 2020 at 14:02:33 UTC, Petar Kirov 
 [ZombineDev] wrote:
 ...
 You can find a full example of this here:
 https://run.dlang.io/gist/run-dlang/80e120e989a6b0f72fd7244b17021e2f
There is an issue with `AliasTuple` though, you can't directly print its collections with pragma: ```d alias coll = AliasSeq!(s1, s2, s3, s7); pragma(msg, coll); ``` I get the following error: ```d onlineapp.d(29): Error: cannot interpret AliasTuple!1 at compile time onlineapp.d(29): Error: cannot interpret AliasTuple!(1, 2) at compile time ... tuple((__error), (__error), (__error), (__error)) ```
p.s. I did include a `Tuple` - like implementation in my article at the later sections, but it was based on a template struct.
Yeah, I agree that using structs offers better ergonomics. Such design also enables cool things like UFCS and lambda functions. You can find an example of this here: https://gist.github.com/PetarKirov/a808c94857de84858accfb094c19bf77#file-rxd-meta2-d-L65-L123
Aug 25 2020
prev sibling parent Petar Kirov [ZombineDev] <petar.p.kirov gmail.com> writes:
On Tuesday, 25 August 2020 at 16:01:25 UTC, data pulverizer wrote:
 On Tuesday, 25 August 2020 at 14:02:33 UTC, Petar Kirov 
 [ZombineDev] wrote:
 ...
 You can find a full example of this here:
 https://run.dlang.io/gist/run-dlang/80e120e989a6b0f72fd7244b17021e2f
There is an issue with `AliasTuple` though, you can't directly print its collections with pragma: ```d alias coll = AliasSeq!(s1, s2, s3, s7); pragma(msg, coll); ``` I get the following error: ```d onlineapp.d(29): Error: cannot interpret AliasTuple!1 at compile time onlineapp.d(29): Error: cannot interpret AliasTuple!(1, 2) at compile time ... tuple((__error), (__error), (__error), (__error)) ```
Yeah, I wrote a quick implementation, just for this example. For sure there are better ways to implement it.
Aug 25 2020
prev sibling parent reply Twilight <drphilphd sbcglobal.net> writes:
On Tuesday, 25 August 2020 at 02:11:42 UTC, data pulverizer wrote:
 I have a draft new blog article "Introduction to programming 
 with compile time sequences in D", it's on Github and I would 
 appreciate feedback before it goes live 
 https://gist.github.com/dataPulverizer/67193772c52e7bd0a16414cb01ae4250

 Comment welcome.

 Many thanks
Not being a Dlang expert, I probably qualify as the intended target audience for this article and having absorbed your previous article so readily, I thought I would try to expound a little where I stumbled with this article. I was clipping along until I reached the "Replacing a single item by index" section. Having mentioned earlier that AliasSeq was defined in std.meta, I thought this section started out by saying that this was the implementation of the Replace meta-function in the internals of std.meta, and consequently, because it is marked as private (to the std.meta module), I can not use this function (confusingly). As you can see, the wording took me down a path you did not intend. When I reached the bottom of this section, it was helpful to see the intended call with 3 arguments. The earlier 4 arguments was puzzling. I now think that the "internal" implementation was meant to convey the role that "ReplaceImpl" would if this were C++ templates (with the extra argument used to count to the match). Anyway, this particular section seems to be better digested for me from the bottom upwards, i.e., starting with an example of its use. Also, the Join function might be better placed in the previous section. Do consider that I may just be a little off in my reading comprehension today so please weigh my thoughts accordingly. I have greatly appreciated the recent articles by you and others. Thanks authors!
Aug 27 2020
parent data pulverizer <data.pulverizer gmail.com> writes:
On Thursday, 27 August 2020 at 20:56:43 UTC, Twilight wrote:
 On Tuesday, 25 August 2020 at 02:11:42 UTC, data pulverizer 
 wrote:
 I have a draft new blog article "Introduction to programming 
 with compile time sequences in D", it's on Github and I would 
 appreciate feedback before it goes live 
 https://gist.github.com/dataPulverizer/67193772c52e7bd0a16414cb01ae4250

 Comment welcome.

 Many thanks
Not being a Dlang expert, I probably qualify as the intended target audience for this article and having absorbed your previous article so readily, I thought I would try to expound a little where I stumbled with this article. I was clipping along until I reached the "Replacing a single item by index" section. Having mentioned earlier that AliasSeq was defined in std.meta, I thought this section started out by saying that this was the implementation of the Replace meta-function in the internals of std.meta, and consequently, because it is marked as private (to the std.meta module), I can not use this function (confusingly). As you can see, the wording took me down a path you did not intend. When I reached the bottom of this section, it was helpful to see the intended call with 3 arguments. The earlier 4 arguments was puzzling. I now think that the "internal" implementation was meant to convey the role that "ReplaceImpl" would if this were C++ templates (with the extra argument used to count to the match). Anyway, this particular section seems to be better digested for me from the bottom upwards, i.e., starting with an example of its use. Also, the Join function might be better placed in the previous section. Do consider that I may just be a little off in my reading comprehension today so please weigh my thoughts accordingly. I have greatly appreciated the recent articles by you and others. Thanks authors!
Thanks for your feedback, when I look at my introduction I clearly mention the `text` function that I imported from `std.conv` but not `AliasSeq`, and `Nothing` that I implemented from `std.meta`, I have now put these in the introduction along with `text` which should make things clearer.
Aug 28 2020