www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - CT aggregate computations

reply Enigma <Enigma dot.com> writes:
Is it possible to compute at compile time computations on a 
manifest constant that contains values(in a somewhat complex way, 
but that shouldn't matter)?

I am using foreach and it seems to be done dynamically as I can 
step through the code for each value and see them change. This 
tells me it is not done at compile time like it should be.

I might have something like


import std.meta, std.algorithm, std.stdio;
void main()
{
	enum X = [1,2,3,4,5];
	int y = 0;	
	foreach(x; X) // or foreach(x; aliasSeqOf!X), both iterate over 
y at run time according to the debugger.
	   y = max(x, y);
	
	writeln(y);
		
}

But I want it to be effectively the same as


import std.meta, std.algorithm, std.stdio;
void main()
{
	enum X = [1,2,3,4,5];
	int y = 5;	
	writeln(y);	
}

so y is computed at compile time. I'd rather not having to create 
some complex templates to handle it, which I think could be done 
using template recursion. I know of Map and such but will these 
compute completely at compile time or will be essentially be the 
same as the foreach loop?
Mar 30
next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
On Thursday, 30 March 2017 at 18:21:43 UTC, Enigma wrote:
 I am using foreach and it seems to be done dynamically as I can 
 step through the code for each value and see them change. This 
 tells me it is not done at compile time like it should be.
Remember two facts: 1) CTFE is never done unless it specifically must be done and 2) D does not have static foreach, it is just regular foreach And a third warning: * enum foo = [1,2,3]; makes foo work just like an array literal... which means it actually does a runtime allocation every time you reference it. Rarely what you actually want! The answer is simple though: write an ordinary function that does your calculation and pass it an ordinary array, but set it to a static immutable array to force CTFE. int getMax(int[] X) { int y = 0; foreach(x; X) y = max(x, y); return y; } void main() { enum y = getMax([1,2,3,4,5]); // safe for int static immutable y = getMax(...); // use that if return array } So you need to do a regular loop in a regular function, then assign the result of that regular function to enum or static.
Mar 30
prev sibling next sibling parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 03/30/2017 11:21 AM, Enigma wrote:
 Is it possible to compute at compile time computations on a manifest
 constant that contains values(in a somewhat complex way, but that
 shouldn't matter)?
You can do anything that you want as long as it's available at compile time. For example, you cannot interact with a user.
 I am using foreach and it seems to be done dynamically as I can step
 through the code for each value and see them change. This tells me it is
 not done at compile time like it should be.
D does not have an explicit way of requesting compile-time execution. It's done when it's needed at compile time: - enum values - static const values - Template arguments - Mixin code In order to prove yourself that something is computed at compile time, just use pragma(msg).
 import std.meta, std.algorithm, std.stdio;
 void main()
 {
     enum X = [1,2,3,4,5];
One big gotcha with enum arrays is that every place that you refer to X, a temporary array will be created dynamically. Only the manifest value of the array is computed at compile time. Try the following code and be surprised that it prints two different addresses: writeln(X.ptr); writeln(X.ptr); (This issue does not apply to strings.) So, what you want to do is to create an enum like the above, but use it only once at runtime to initialize another array, likely immutable, for your actual use. // This is what the program will actually use immutable int[] X; auto calculateArray() { return [1,2,3,4,5]; } // This is used only once to initialize X private enum X_ = calculateArray(); pragma(msg, "Known at compile time: ", X_); import std.algorithm: maxElement; enum y = maxElement(X_); shared static this() { X = X_; } void main() { pragma(msg, "Known at compile time: ", y); } Ali
Mar 30
prev sibling parent reply "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
On Thu, Mar 30, 2017 at 06:21:43PM +0000, Enigma via Digitalmars-d-learn wrote:
 Is it possible to compute at compile time computations on a manifest
 constant that contains values(in a somewhat complex way, but that
 shouldn't matter)?
Yes, see below.
 I am using foreach and it seems to be done dynamically as I can step
 through the code for each value and see them change. This tells me it
 is not done at compile time like it should be.
If you want something done at compile time, you have to ask for it. The usual way is to use something like `enum` that must be known at compile-time to force the compiler to run the computation through CTFE.
 I might have something like
 
 
 import std.meta, std.algorithm, std.stdio;
 void main()
 {
 	enum X = [1,2,3,4,5];
 	int y = 0;	
 	foreach(x; X) // or foreach(x; aliasSeqOf!X), both iterate over y at run
 time according to the debugger.
 	   y = max(x, y);
 	
 	writeln(y);
 		
 }
Here is how to do it: auto computeY(int[] data) { int y = 0; foreach (x; data) y = max(x,y); return y; } void main() { enum X = [1,2,3,4,5]; enum y = computeY(X); // N.B.: enum forces CTFE writeln(y); }
 But I want it to be effectively the same as
 
 
 import std.meta, std.algorithm, std.stdio;
 void main()
 {
 	enum X = [1,2,3,4,5];
 	int y = 5;	
 	writeln(y);	
 }
 
 so y is computed at compile time. I'd rather not having to create some
 complex templates to handle it, which I think could be done using
 template recursion.
[...] You don't need template recursion unless you're doing something at the AST level. For most computations you want done at "compile-time", you can just use CTFE. Again, I see the term "compile-time" is misleading people. You may want to read the following (it's still a draft, but what's there should help clear things up): http://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time T -- Caffeine underflow. Brain dumped.
Mar 30
parent drug <drug2004 bk.ru> writes:
30.03.2017 21:59, H. S. Teoh via Digitalmars-d-learn пишет:
 	http://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time
Really useful link, thank you very much!
Mar 30