Compile-time calculation: Difference between revisions

Content added Content deleted
(Added Prolog)
(Rename Perl 6 -> Raku, alphabetize, minor clean-up)
Line 122: Line 122:


In both cases, the identifier <code>factorial10</code> is given the value 3628800 without any runtime calculations, although in many (or perhaps most) BASICs the first one is handled similarly to C's <code>#define</code>: if it isn't used elsewhere in the code, it doesn't appear at all in the final executable.
In both cases, the identifier <code>factorial10</code> is given the value 3628800 without any runtime calculations, although in many (or perhaps most) BASICs the first one is handled similarly to C's <code>#define</code>: if it isn't used elsewhere in the code, it doesn't appear at all in the final executable.



=={{header|C}}==
=={{header|C}}==
Line 196: Line 195:
.def printf; .scl 2; .type 32; .endef
.def printf; .scl 2; .type 32; .endef
</pre>
</pre>

=={{header|C++}}==
This is called [[wp:Template metaprogramming|Template metaprogramming]]. In fact, templates in C++ are Turing-complete, making deciding whether a program will compile undecidable.
<lang cpp>#include <iostream>

template<int i> struct Fac
{
static const int result = i * Fac<i-1>::result;
};

template<> struct Fac<1>
{
static const int result = 1;
};


int main()
{
std::cout << "10! = " << Fac<10>::result << "\n";
return 0;
}</lang>

Compile-time calculations in C++ look quite different from normal code. We can only use templates, type definitions and a subset of integer arithmetic. It is not possible to use iteration. C++ compile-time programs are similar to programs in pure functional programming languages, albeit with a peculiar syntax.

{{works with|C++11}}
Alternative version, using constexpr in C++11:

<lang cpp>#include <stdio.h>

constexpr int factorial(int n) {
return n ? (n * factorial(n - 1)) : 1;
}

constexpr int f10 = factorial(10);

int main() {
printf("%d\n", f10);
return 0;
}</lang>
Output:
<pre>3628800</pre>
The asm produced by G++ 4.6.0 32 bit (-std=c++0x -S), shows the computation is done at compile-time:
<lang asm>_main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $16, %esp
call ___main
movl $3628800, 4(%esp)
movl $LC0, (%esp)
call _printf
movl $0, %eax
leave
ret</lang>


=={{header|C sharp}}==
=={{header|C sharp}}==
Line 345: Line 290:
{{out}}
{{out}}
<pre>3628800</pre>
<pre>3628800</pre>

=={{header|C++}}==
This is called [[wp:Template metaprogramming|Template metaprogramming]]. In fact, templates in C++ are Turing-complete, making deciding whether a program will compile undecidable.
<lang cpp>#include <iostream>

template<int i> struct Fac
{
static const int result = i * Fac<i-1>::result;
};

template<> struct Fac<1>
{
static const int result = 1;
};


int main()
{
std::cout << "10! = " << Fac<10>::result << "\n";
return 0;
}</lang>

Compile-time calculations in C++ look quite different from normal code. We can only use templates, type definitions and a subset of integer arithmetic. It is not possible to use iteration. C++ compile-time programs are similar to programs in pure functional programming languages, albeit with a peculiar syntax.

{{works with|C++11}}
Alternative version, using constexpr in C++11:

<lang cpp>#include <stdio.h>

constexpr int factorial(int n) {
return n ? (n * factorial(n - 1)) : 1;
}

constexpr int f10 = factorial(10);

int main() {
printf("%d\n", f10);
return 0;
}</lang>
Output:
<pre>3628800</pre>
The asm produced by G++ 4.6.0 32 bit (-std=c++0x -S), shows the computation is done at compile-time:
<lang asm>_main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $16, %esp
call ___main
movl $3628800, 4(%esp)
movl $LC0, (%esp)
call _printf
movl $0, %eax
leave
ret</lang>


=={{header|Clojure}}==
=={{header|Clojure}}==
Line 742: Line 741:
grep 172801 sec.s
grep 172801 sec.s
movl $<span style="color:red">172801</span>, camlSec
movl $<span style="color:red">172801</span>, camlSec



=={{header|Oforth}}==
=={{header|Oforth}}==
Line 876: Line 874:


<lang perl>my $tenfactorial = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2;</lang>
<lang perl>my $tenfactorial = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2;</lang>


=={{header|Perl 6}}==

<lang perl6>constant $tenfact = [*] 2..10;
say $tenfact;</lang>

Like Perl 5, we also have a BEGIN block, but it also works to introduce a blockless statement,
the value of which will be stored up to be used in the surrounding expression at run time:

<lang perl6> say(BEGIN [*] 2..10);</lang>


=={{header|Phix}}==
=={{header|Phix}}==
Line 1,061: Line 1,048:
(fact10)
(fact10)
</lang>
</lang>

=={{header|Raku}}==
(formerly Perl 6)

<lang perl6>constant $tenfact = [*] 2..10;
say $tenfact;</lang>

Like Perl 5, we also have a BEGIN block, but it also works to introduce a blockless statement,
the value of which will be stored up to be used in the surrounding expression at run time:

<lang perl6> say(BEGIN [*] 2..10);</lang>


=={{header|REXX}}==
=={{header|REXX}}==
Line 1,105: Line 1,103:
func factorial nr if nr = 1 return 1 else return nr * factorial(nr-1) ok
func factorial nr if nr = 1 return 1 else return nr * factorial(nr-1) ok
</lang>
</lang>

=={{header|Rust}}==
=={{header|Rust}}==
The Rust compiler can automatically do optimizations in the code to calculate the factorial.
The Rust compiler can automatically do optimizations in the code to calculate the factorial.
Line 1,161: Line 1,160:
20: dup
20: dup
21: new #40 // class java/lang/StringBuilder</pre>
21: new #40 // class java/lang/StringBuilder</pre>

=={{header|Seed7}}==
=={{header|Seed7}}==