Is it possible to force CTFE?

2012-06-10 Thread Tommi

Three related questions:

1) Is there a way to force a function to be always executed at 
compile time (when it's possible to do so) no matter what context 
it's called in?


2) Is it possible to specialize a function based on whether or 
not the parameter that was passed in is a compile time constant?


3) Does any D compiler currently optimize out a conditional 
branch which _can_ be evaluated at compile time (but which isn't 
forced into CTFE)? Like:


int getValue(bool b)
{
return b ? 123 : 456;
}

//...
   auto value = getValue(true);


Re: Is it possible to force CTFE?

2012-06-10 Thread jerro
1) Is there a way to force a function to be always executed at 
compile time (when it's possible to do so) no matter what 
context it's called in?


No, but you could wrap it in a template to force it to always
execute at compile time. Of course it could then only be called
at compile time.

2) Is it possible to specialize a function based on whether or 
not the parameter that was passed in is a compile time constant?


No.

3) Does any D compiler currently optimize out a conditional 
branch which _can_ be evaluated at compile time (but which 
isn't forced into CTFE)? Like:


int getValue(bool b)
{
return b ? 123 : 456;
}

//...
   auto value = getValue(true);


DMD, LDC and GDC all do this when compiling with optimizations
turned on. They all compile these functions to exactly the
same code:

auto foo()
{
return getValue(true);
}

auto bar()
{
return 123;
}






Re: Is it possible to force CTFE?

2012-06-10 Thread Timon Gehr

On 06/10/2012 09:04 AM, Tommi wrote:

Three related questions:

1) Is there a way to force a function to be always executed at compile
time (when it's possible to do so) no matter what context it's called in?



No there is not. You could use a template that calls a private function 
at compile time instead. What is your use case?



2) Is it possible to specialize a function based on whether or not the
parameter that was passed in is a compile time constant?



This has been discussed before, but there is not.


1-2) could be introduced later when D gets AST macros.


3) Does any D compiler currently optimize out a conditional branch which
_can_ be evaluated at compile time (but which isn't forced into CTFE)?
Like:

int getValue(bool b)
{
 return b ? 123 : 456;
}

//...
auto value = getValue(true);


Yes, DMD/GDC/LDC should be able to do this to different extents.


Re: Is it possible to force CTFE?

2012-06-10 Thread Tommi

On Sunday, 10 June 2012 at 10:23:09 UTC, Timon Gehr wrote:
No there is not. You could use a template that calls a private 
function at compile time instead. What is your use case?


I was just thinking about a situation where a property 
accessor/mutator methods are not as simple as read/assign value, 
such as in this silly example:


struct Flipping123
{
private int m_number = 123;

@property bool isPositive()
{
return m_number >= 0;
}

@property void isPositive(bool b)
{
m_number = b ? 123 : -123;
}
}

//...
Flipping123 fl;
fl.isPositive = false; // I'd rather not have cond. branching 
in release mode


Re: Is it possible to force CTFE?

2012-09-27 Thread Tommi

On Sunday, 10 June 2012 at 10:16:23 UTC, jerro wrote:


No, but you could wrap it in a template to force it to always
execute at compile time.


So, I just realized, I could have just this one convenience 
template that I can use whenever I want to force an expression to 
be evaluated at compile-time. Like so:


template ct(alias expr)
{
 enum ct = expr;
}

int fun(int a, int b)
{
 return a + b;
}

//... and use it like:

ct!(fun(1, 2))

That's not *too* inconvenient. Although, best would be a function 
attribute that would force the compiler to apply ctfe 
aggressively whenever it can with calls to that function.


Re: Is it possible to force CTFE?

2012-09-27 Thread bearophile

Tommi:

2) Is it possible to specialize a function based on whether or 
not the parameter that was passed in is a compile time constant?


I am interested in this since some years. I think it's useful, 
but I don't know if it can be implemented. I don't remember 
people discussing about this much.


Bye,
bearophile


Re: Is it possible to force CTFE?

2012-09-27 Thread Jacob Carlborg

On 2012-09-27 15:01, bearophile wrote:

Tommi:


2) Is it possible to specialize a function based on whether or not the
parameter that was passed in is a compile time constant?


I am interested in this since some years. I think it's useful, but I
don't know if it can be implemented. I don't remember people discussing
about this much.


There's the if (__ctfe) hack. Also using only template parameters will 
force the function to be CTFE.


--
/Jacob Carlborg


Re: Is it possible to force CTFE?

2012-09-27 Thread bearophile

Jacob Carlborg:

I am interested in this since some years. I think it's useful, 
but I don't know if it can be implemented. I don't remember

people discussing about this much.


There's the if (__ctfe) hack. Also using only template 
parameters will force the function to be CTFE.


This is quite far from what I was discussing about here...

Bye,
bearophile


Re: Is it possible to force CTFE?

2012-09-28 Thread Tommi
One use case I can think of for specializing functions based on 
whether or not its arguments are compile-time evaluable:


// Big container that can't be accessed in constant time:
immutable cachedResults = init();

double getResult()
if (areCompileTimeConstants!() == false)
{
return cachedResults.at();
}

double getResult()
if (areCompileTimeConstants!() == true)
{
// Computing the result takes long time
...
return computedResult;
}

Point being that A) cachedResults takes so much memory we don't 
want to evaluate it at compile-time and bloat the executable, and 
B) accessing cachedResults takes some non-trivial time, so we 
don't want to do that at runtime if it can be done at 
compile-time. Don't know how common this kind of thing would be 
though.



But, that made me think...
In a perfect world, I think, the compiler would always evaluate 
all possible functions at compile-time, given that doing so would 
produce a smaller (or equal size) executable than what 
not-evaluating-at-compile-time would produce. For example 
(assuming the following initialization functions are compile-time 
evaluable):


// The following wouldn't be evaluated at compile time,
// because that function call (probably) wouldn't take
// as much space in the executable as million ints:

int[1_000_000] bigArray = initBigArray();

// The following would be always evaluated at compile time,
// because a single int value would take less space in the
// executable than the function call:

int myValue = initMyValue();

Although, to speed up test compilations, we'd need a compiler 
flag to disable this "aggressive" CTFE behaviour.


Re: Is it possible to force CTFE?

2012-09-28 Thread Tommi

On Friday, 28 September 2012 at 17:52:55 UTC, Tommi wrote:
In a perfect world, I think, the compiler would always evaluate 
all possible functions at compile-time, given that doing so 
would produce a smaller (or equal size) executable than what 
not-evaluating-at-compile-time would produce.



Or, a simpler rule (for both the compiler and the coder):
Have a compiler flag where you set a value (in bytes), and if a 
function returns a type that's size is not larger than the set 
value, the compiler would execute all calls to that function at 
compile-time (if possible).


Re: Is it possible to force CTFE?

2012-10-01 Thread Don Clugston

On 27/09/12 15:01, bearophile wrote:

Tommi:


2) Is it possible to specialize a function based on whether or not the
parameter that was passed in is a compile time constant?


I am interested in this since some years. I think it's useful, but I
don't know if it can be implemented. I don't remember people discussing
about this much.

Bye,
bearophile


It has been discussed very often, especially around the time that CTFE 
was first introduced. We never came up with a solution.