www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Why this code can't take advantage from CTFE?

reply Andrea Fontana <nospam example.com> writes:
This code:

import std.stdio;

int very_very_long_function(in int k)
{
         if (!__ctfe) writeln("Can't use ctfe!");
         return k/2;
}

void main()
{
         enum first = very_very_long_function(10);
         writeln("First is ", first);

         auto second = very_very_long_function(12);
         writeln("Second is ", second);

         auto third = first;
         third += 1;
         writeln("Third is ", third);
}

Why second init doesn't work with CTFE? It could be something 
like third, but with one less copy. What am I missing?
Feb 03 2016
next sibling parent anonymous <anonymous example.com> writes:
On 03.02.2016 16:34, Andrea Fontana wrote:
 void main()
 {
          enum first = very_very_long_function(10);
          writeln("First is ", first);

          auto second = very_very_long_function(12);
          writeln("Second is ", second);

          auto third = first;
          third += 1;
          writeln("Third is ", third);
 }

 Why second init doesn't work with CTFE? It could be something like
 third, but with one less copy. What am I missing?
The compiler doesn't try to apply CTFE everywhere, because it could take forever. So CTFE is only done when the programmer requests it by using a function in a static context. The compiler is still free to precompute the value at compile time, if it thinks that's a good idea, but that's just an optimization. And while it's evaluation of a function at compile time, it's not CTFE in the sense of __ctfe.
Feb 03 2016
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Wednesday, 3 February 2016 at 15:34:51 UTC, Andrea Fontana 
wrote:
         enum first = very_very_long_function(10);
         auto second = very_very_long_function(12);

 Why second init doesn't work with CTFE?
You never asked for CTFE. CTFE only happens when it *has* to - when you write code that specifically asks for or requires it. Ordinary variables don't require ctfe, so they don't get it.
Feb 03 2016
parent reply Messenger <dont shoot.me> writes:
On Wednesday, 3 February 2016 at 15:59:43 UTC, Adam D. Ruppe 
wrote:
 You never asked for CTFE.

 CTFE only happens when it *has* to - when you write code that 
 specifically asks for or requires it.
What is a good way to try to force it? Using enum? Then optionally copying the value once to avoid the "manifest constant" copy/paste behaviour, where applicable?
Feb 03 2016
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Wednesday, 3 February 2016 at 16:07:59 UTC, Messenger wrote:
 What is a good way to try to force it? Using enum? Then 
 optionally copying the value once to avoid the "manifest 
 constant" copy/paste behaviour, where applicable?
Yes, or static local variables are ctfe initialized too.
Feb 03 2016
parent reply Andrea Fontana <nospam example.com> writes:
On Wednesday, 3 February 2016 at 16:24:19 UTC, Adam D. Ruppe 
wrote:
 On Wednesday, 3 February 2016 at 16:07:59 UTC, Messenger wrote:
 What is a good way to try to force it? Using enum? Then 
 optionally copying the value once to avoid the "manifest 
 constant" copy/paste behaviour, where applicable?
Yes, or static local variables are ctfe initialized too.
But if I want a normal var, not static or enum? There's no way to force it?
Feb 03 2016
next sibling parent Messenger <dont shoot.me> writes:
On Wednesday, 3 February 2016 at 17:16:30 UTC, Andrea Fontana 
wrote:
 But if I want a normal var, not static or enum?
 There's no way to force it?
Just make a mutable copy of it, I think.
Feb 03 2016
prev sibling parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 2/3/16 12:16 PM, Andrea Fontana wrote:
 On Wednesday, 3 February 2016 at 16:24:19 UTC, Adam D. Ruppe wrote:
 On Wednesday, 3 February 2016 at 16:07:59 UTC, Messenger wrote:
 What is a good way to try to force it? Using enum? Then optionally
 copying the value once to avoid the "manifest constant" copy/paste
 behaviour, where applicable?
Yes, or static local variables are ctfe initialized too.
But if I want a normal var, not static or enum? There's no way to force it?
Hm... trick you could do is: auto myvar = AliasSeq!(someCTFEFunc())[0]; -Steve
Feb 03 2016
prev sibling parent reply Marc =?UTF-8?B?U2Now7x0eg==?= <schuetzm gmx.net> writes:
On Wednesday, 3 February 2016 at 16:07:59 UTC, Messenger wrote:
 What is a good way to try to force it? Using enum? Then 
 optionally copying the value once to avoid the "manifest 
 constant" copy/paste behaviour, where applicable?
template forceCTFE(alias expr) { alias forceCTFE = expr; } auto value = forceCTFE!(some_expression());
Feb 03 2016
parent reply Andrea Fontana <nospam example.com> writes:
On Wednesday, 3 February 2016 at 17:49:39 UTC, Marc Schütz wrote:
 On Wednesday, 3 February 2016 at 16:07:59 UTC, Messenger wrote:
 What is a good way to try to force it? Using enum? Then 
 optionally copying the value once to avoid the "manifest 
 constant" copy/paste behaviour, where applicable?
template forceCTFE(alias expr) { alias forceCTFE = expr; } auto value = forceCTFE!(some_expression());
Interesting :) Thank you!
Feb 03 2016
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 02/03/2016 11:39 PM, Andrea Fontana wrote:
 On Wednesday, 3 February 2016 at 17:49:39 UTC, Marc Schütz wrote:
 On Wednesday, 3 February 2016 at 16:07:59 UTC, Messenger wrote:
 What is a good way to try to force it? Using enum? Then optionally
 copying the value once to avoid the "manifest constant" copy/paste
 behaviour, where applicable?
template forceCTFE(alias expr) { alias forceCTFE = expr; } auto value = forceCTFE!(some_expression());
Interesting :) Thank you!
I would use enum forceCTFE(alias expr)=expr; though. With alias it won't force compile-time evaluation of expressions that can be interpreted as symbols.
Feb 03 2016
parent reply Andrea Fontana <nospam example.com> writes:
On Wednesday, 3 February 2016 at 22:45:47 UTC, Timon Gehr wrote:
 I would use enum forceCTFE(alias expr)=expr; though. With alias 
 it won't force compile-time evaluation of expressions that can 
 be interpreted as symbols.
I've a code that build a JSON object using a wrapper over std.json. This code: ---- enum forceCTFE(alias expr)=expr; auto j = forceCTFE!( JSOB ( "hello", JSOB("world", 3), "arr", JSAB("hello", JSOB("world", 1)) ) ); j.put("/hello/world", "!"); j.put("/hello/blah", 42); // Here j == {"arr":["hello",{"world":1}],"hello":{"blah":42,"world":"!"}} ---- shows a 10% performance gain over this: ---- auto j = JSOB ( "hello", JSOB("world", 3), "arr", JSAB("hello", JSOB("world", 1)) ); j.put("/hello/world", "!"); j.put("/hello/blah", 42); ---- (inside a loop). And it's just a small json in this case. That's pretty good IMHO :)
Feb 05 2016
parent reply Luis <luis.panadero gmail.com> writes:
On Friday, 5 February 2016 at 09:36:37 UTC, Andrea Fontana wrote:
 On Wednesday, 3 February 2016 at 22:45:47 UTC, Timon Gehr wrote:
 I would use enum forceCTFE(alias expr)=expr; though. With 
 alias it won't force compile-time evaluation of expressions 
 that can be interpreted as symbols.
I've a code that build a JSON object using a wrapper over std.json. This code: ---- enum forceCTFE(alias expr)=expr; auto j = forceCTFE!( JSOB ( "hello", JSOB("world", 3), "arr", JSAB("hello", JSOB("world", 1)) ) ); j.put("/hello/world", "!"); j.put("/hello/blah", 42); // Here j == {"arr":["hello",{"world":1}],"hello":{"blah":42,"world":"!"}}
Reading/parsing a JSON or a XML using std.json / std.xml could be done on CTFE ?
Feb 05 2016
parent Andrea Fontana <nospam example.com> writes:
On Friday, 5 February 2016 at 09:49:38 UTC, Luis wrote:
 Reading/parsing a JSON or a XML using std.json / std.xml could 
 be done on CTFE ?
parseJSON() from std.json doesn't work with CTFE. But I can build objects with with my code that works over std.json. So if you convert (with mixins) { "hello" : "world" } to JSOB("hello", "world) You can parse it ar compile time. :)
Feb 05 2016