digitalmars.D.learn - Compiletime Table
- D_Learner (28/28) Aug 13 2015 I was wondering how I could change the code below such the `bmBc`
- Adam D. Ruppe (25/27) Aug 13 2015 It is currently not possible to build an associative array at
- D_Learner (8/35) Aug 13 2015 Thanks, the 128 is fine since I was considering the whole ASCII
- D_Learner (4/10) Aug 14 2015 Am aware you have published a book on D. Perhaps I have to get
- Adam D. Ruppe (8/10) Aug 14 2015 My blasphemous talk as I like to call it :)
- D_Learner (2/12) Aug 14 2015 Just downloaded the demo, cheers!
- anonymous (40/68) Aug 13 2015 I think you may have some fundamental misunderstandings regarding
- D_Learner (6/47) Aug 14 2015 Thanks so much for the advice, it works fine. Just experimented
I was wondering how I could change the code below such the `bmBc` is computed at compile time . The one below works for runtime but it is not ideal since I need to know the `bmBc` table at compile-time . I could appreciate advice on how I could improve on this. import std.conv:to; import std.stdio; int [string] bmBc; immutable string pattern = "GCAGAGAG"; const int size = to!int(pattern.length); struct king { void calculatebmBc(int i)() { static if ( i < size -1 ) bmBc[to!string(pattern[i])]=to!int(size-i-1); // bmBc[pattern[i]] ~= i-1; calculatebmBc!(i+1)(); } void calculatebmBc(int i: size-1)() { } } void main(){ king myKing; const int start = 0; myKing.calculatebmBc!(start)(); //1. enum bmBcTable = bmBc; }
Aug 13 2015
On Thursday, 13 August 2015 at 19:13:55 UTC, D_Learner wrote:I was wondering how I could change the code below such the `bmBc` is computed at compile time .It is currently not possible to build an associative array at compile time and keep it as a runtime table due to the implementation. However, looking at your code, you don't need a full AA... the key is a single char, right? Do something like this: int[128] bmBc = calculate(); // .... And then a line like this should work to set it in the calculate function: bmBc[pattern[i]] = i-1; Adjust this code to fit you: int[128] a = calc(); enum string pattern = "abc"; int[128] calc() { int[128] a; // local copy to work on as we build a[pattern[0]] = 0; return a; // return the completed table } This works because individual characters have a numeric value. If they are all A-Z, you can easily fit them in a small array and access them even faster than an associative array (doesn't even have to be full size 128 if the only keys are the letters). And these can be built at CTFE and stored in the program's data segment.
Aug 13 2015
On Thursday, 13 August 2015 at 19:26:12 UTC, Adam D. Ruppe wrote:On Thursday, 13 August 2015 at 19:13:55 UTC, D_Learner wrote:Thanks, the 128 is fine since I was considering the whole ASCII character set . I was a bit skeptical of writing the code in that manor though since I have to still compare runtime and compiletime implementation performance(benchmarks ). That is why my code seemed to mimic templating . Maybe the question would then be, how do I force this function to be fully executed at compiletime and later make it be executed at runntime ?I was wondering how I could change the code below such the `bmBc` is computed at compile time .It is currently not possible to build an associative array at compile time and keep it as a runtime table due to the implementation. However, looking at your code, you don't need a full AA... the key is a single char, right? Do something like this: int[128] bmBc = calculate(); // .... And then a line like this should work to set it in the calculate function: bmBc[pattern[i]] = i-1; Adjust this code to fit you: int[128] a = calc(); enum string pattern = "abc"; int[128] calc() { int[128] a; // local copy to work on as we build a[pattern[0]] = 0; return a; // return the completed table } This works because individual characters have a numeric value. If they are all A-Z, you can easily fit them in a small array and access them even faster than an associative array (doesn't even have to be full size 128 if the only keys are the letters). And these can be built at CTFE and stored in the program's data segment.
Aug 13 2015
On Thursday, 13 August 2015 at 19:26:12 UTC, Adam D. Ruppe wrote:On Thursday, 13 August 2015 at 19:13:55 UTC, D_Learner wrote:Am aware you have published a book on D. Perhaps I have to get myself a copy. Am currently looking at your Dconf2015 talk . Thanks for your advice.[...]It is currently not possible to build an associative array at compile time and keep it as a runtime table due to the implementation. [...]
Aug 14 2015
On Friday, 14 August 2015 at 20:40:13 UTC, D_Learner wrote:you should! There's a lot of little tips and tricks in there.Perhaps I have to get myself a copy.Am currently looking at your Dconf2015 talk .My blasphemous talk as I like to call it :) There's a bit in the video where i went off script and started demoing and it wasn't shown. It was just this program fyi: https://github.com/adamdruppe/inspector not that magical but kinda cool in how simple the code was able to be.
Aug 14 2015
On Friday, 14 August 2015 at 20:48:43 UTC, Adam D. Ruppe wrote:On Friday, 14 August 2015 at 20:40:13 UTC, D_Learner wrote:Just downloaded the demo, cheers!you should! There's a lot of little tips and tricks in there.Perhaps I have to get myself a copy.Am currently looking at your Dconf2015 talk .My blasphemous talk as I like to call it :) There's a bit in the video where i went off script and started demoing and it wasn't shown. It was just this program fyi: https://github.com/adamdruppe/inspector not that magical but kinda cool in how simple the code was able to be.
Aug 14 2015
On Thursday, 13 August 2015 at 19:13:55 UTC, D_Learner wrote:I was wondering how I could change the code below such the `bmBc` is computed at compile time . The one below works for runtime but it is not ideal since I need to know the `bmBc` table at compile-time . I could appreciate advice on how I could improve on this. import std.conv:to; import std.stdio; int [string] bmBc; immutable string pattern = "GCAGAGAG"; const int size = to!int(pattern.length); struct king { void calculatebmBc(int i)() { static if ( i < size -1 ) bmBc[to!string(pattern[i])]=to!int(size-i-1); // bmBc[pattern[i]] ~= i-1; calculatebmBc!(i+1)(); } void calculatebmBc(int i: size-1)() { } } void main(){ king myKing; const int start = 0; myKing.calculatebmBc!(start)(); //1. enum bmBcTable = bmBc; }I think you may have some fundamental misunderstandings regarding CTFE, templates, etc. Your code seems to be half-way between a template-based and a CTFE-based solution. The simple way to do compile-time computation in D is CTFE (Compile Time Function Evaluation). That is, you write a pure function that can be evaluated both at run-time and at compile-time. CTFE doesn't need template parameters. Here's some code that should do the same as yours and is compatible with CTFE: ---- import std.conv: to; import std.stdio; int[char] calculatebmBc(string pattern) pure { const int size = to!int(pattern.length); int[char] result; foreach(i; 0 .. size - 1) { result[pattern[i]] = to!int(size - i - 1); } return result; } void main() { auto bmBc = calculatebmBc("GCAGAGAG"); enum bmBcTable = calculatebmBc("GCAGAGAG"); } ---- The key is that calculatebmBc is pure, i.e. it doesn't read or write any module-level mutables. I touched some things here and here I didn't like that are not related to purity/CTFE. Adam D. Ruppe already mentioned an issue with associative arrays: This doesn't work: ---- static foo = calculatebmBc("GCAGAGAG"); ---- It's annoying, but if you need that you have to use some other data structure. See Adam's post.
Aug 13 2015
On Thursday, 13 August 2015 at 19:54:18 UTC, anonymous wrote:On Thursday, 13 August 2015 at 19:13:55 UTC, D_Learner wrote:Thanks so much for the advice, it works fine. Just experimented with the code . I had no idea about it. My mind had the some pre-occupation that compile-time execution is only achievable through templates. Had no idea about pure functions...awesone , code. Thanks again for the clear explanation.[...]I think you may have some fundamental misunderstandings regarding CTFE, templates, etc. Your code seems to be half-way between a template-based and a CTFE-based solution. The simple way to do compile-time computation in D is CTFE (Compile Time Function Evaluation). That is, you write a pure function that can be evaluated both at run-time and at compile-time. CTFE doesn't need template parameters. Here's some code that should do the same as yours and is compatible with CTFE: ---- import std.conv: to; import std.stdio; int[char] calculatebmBc(string pattern) pure { const int size = to!int(pattern.length); int[char] result; foreach(i; 0 .. size - 1) { result[pattern[i]] = to!int(size - i - 1); } return result; } void main() { auto bmBc = calculatebmBc("GCAGAGAG"); enum bmBcTable = calculatebmBc("GCAGAGAG"); } ---- The key is that calculatebmBc is pure, i.e. it doesn't read or write any module-level mutables. I touched some things here and here I didn't like that are not related to purity/CTFE. Adam D. Ruppe already mentioned an issue with associative arrays: This doesn't work: ---- static foo = calculatebmBc("GCAGAGAG"); ---- It's annoying, but if you need that you have to use some other data structure. See Adam's post.
Aug 14 2015