Compile-time function execution: Difference between revisions

Content deleted Content added
m cat
Improved many parts, cleaned up, splitted a paragraph, removed a redundant example, added a variant of the example
Line 1:
'''Compile time function execution''' is the ability of a [[compiler]], that would normally compile a function to machine code and execute it at run time, to execute the function at compile time. This is possible if the arguments to the function are known at compile time, and the function does not make any reference to or attempt to modify any global state (is a [[pure function]]). Even if the value of only some of the arguments are known, the compiler may still be able to perform some level of compile time function execution ([[partial evaluation]]), possibly producing more optimized code than if no arguments were known.
 
Even if the value of only some of the arguments are known, the compiler may still be able to perform some level of compile time function execution ([[partial evaluation]]), possibly producing more optimized code than if no arguments were known (currently there are no plans to implement such partial evaluation in any D compiler).
==Example 1==
 
==Example 1==
This example code is in the [[D programming language]]<ref>[http://www.digitalmars.com/d/1.0/function.html#interpretation D 1.0 language specification: Functions]</ref>:
 
<source lang="D">
int square(int x)
{
return x * x;
 
const int y = square(3); // y is set to 9 at compile time
</source>
 
==Example 2==
 
In [[C++]], [[template metaprogramming]] is often used to compute values at compile time, such as:
 
<source lang="CPP">
template <int N> struct Factorial {
enum {
struct Factorial
enum { value = N * Factorial<N - 1>::value };
{
};
enum { value = N * Factorial<N - 1>::value };
};
 
template <> struct Factorial<0> {
struct Factorial<0>
{
enum { value = 1 };
};
Line 33 ⟶ 20:
// Factorial<4>::value == 24
// Factorial<0>::value == 1
void foo() {
int yx = Factorial<0>::value; // == 10
{
int xy = Factorial<4>::value; // == 24
int y = Factorial<0>::value; // == 1
}
</source>
 
D templates can be used for the same purpose:
With compile time function evaluation, the code used to generate the factorial would be exactly the same as what one would write for run time evaluation (example is in D):
 
<source lang="D">
inttemplate factorialFactorial(int nN) {
static if (N == 0)
{
const int Factorial = 1;
else
const int Factorial = N * Factorial!(N - 1);
 
static const int y = factorialFactorial!(0); // == 0! == 1
const int x = Factorial!(4); // == 24
</source>
 
ThisBut with compile time function evaluation the code used to compute the factorial would be exactly the same as what one would write for run time evaluation (this example code is in the [[D programming language]]<ref>[http://www.digitalmars.com/d/1.0/function.html#interpretation D 1.0 language specification: Functions]</ref>):
 
<source lang="D">
int squarefactorial(int xn) {
if (n == 0)
return 1;
Line 50 ⟶ 49:
}
 
// computed at compile time
void foo()
const int y = factorial(0); // == 1
{
static const int x = factorial(4); // == (4 * 3 * 2 * 1) == 24
static const int y = factorial(0); // == 0! == 1
}
</source>
 
The use of static <code>const</code> tells the compiler that the initializer for the variables must be computed at compile time<ref>[http://www.digitalmars.com/d/1.0/attribute.html#const D 1.0 language specification: Attributes]</ref>.
 
== References ==