Compile-time calculation: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(36 intermediate revisions by 13 users not shown)
Line 13:
=={{header|360 Assembly}}==
First example with the assembler equivalence pseudo instruction (EQU):
<langsyntaxhighlight lang="360asm">COMPCALA CSECT
L R1,=A(FACT10) r1=10!
XDECO R1,PG
Line 19:
BR R14 exit
FACT10 EQU 10*9*8*7*6*5*4*3*2*1 factorial computation
PG DS CL12</langsyntaxhighlight>
{{out}} in the assembler listing ( 375F00 hexadecimal of 10!)
<pre>
Line 29:
</pre>
Second example with an assembler macro instruction:
<langsyntaxhighlight lang="360asm"> MACRO
&LAB FACT &REG,&N parameters
&F SETA 1 f=1
Line 50:
PG DS CL12
YREGS
END COMPCALB</langsyntaxhighlight>
{{out}} in the assembler listing
<pre>
Line 58:
</pre>
=={{header|6502 Assembly}}==
{{works with|ca65 targeting the C-64}}
 
The ca65 cross-assembler supports computing and storing double-word (32-bit) integer values; unfortunately most 86502-bitbased systems have no built-in support for manipulating such values. OnBut Commodorethe machines,assembler unlessalso yousupports writeconverting yourthem owndirectly arithmeticto routinesstrings, youwhich haveare toeasily useprinted floatingat pointruntime. insteadSo, ofhere's integersa forstraightforward numbersimplementation. thatAs large;written, unfortunatelyit theworks assemblerfor doesn'tany supportCommodore generating8-bits, floatingbut pointit constants.could Norbe isported thereto a ROMdifferent routine6502 tomachine convertjust aby 32-bitchanging integerthe toprint aloop float,to evenuse thoughthe thereappropriate isoutput oneroutine to gofor the othertarget waysystem.
 
<syntaxhighlight lang="6502">; Display the value of 10!, which is precomputed at assembly time
So in this solution the assembler computes the value of 10! and stores it as a 32-bit integer; the runtime code converts that to floating point using ROM routines, dealing with it 16 bits at a time.
; on any Commodore 8-bit.
 
.ifndef __CBM__
<lang 6502>; Display the value of 10!, which is precomputed at assembly time
.error "Target must be a Commodore system."
;
.endif
fac = $61 ; location of the floating point accumulator used by ROM routines
 
facsgn = fac+5 ; specific location of the sign byte
; zero-page work pointer
temp = $fb
 
; ROM routines used
chrout = $ffd2
putfac = $aabc ; print out the value in the FAC
givayf = $b391 ; convert 16-bit integer in AY to floating-point value in FAC
fmult = $ba28 ; multiply FAC by float in memory
fadd = $b867 ; add float in memory to FAC
movfm = $bbd4 ; copy FAC to memory
 
.code
; convert the upper half
ldy tenfactorial+2
lda tenfactorial+3
jsr givayf
 
lda #<tenfactorial
; and multiply by 65536
ldasta #<fp65536temp
ldylda #>fp65536tenfactorial
jsrsta fmulttemp+1
ldy #0
 
loop:
; stash it
ldxlda #<fac_copy(temp),y
ldybeq #>fac_copydone
jsr movfmchrout
iny
 
bne loop
; now convert the lower half
done:
ldy tenfactorial
lda tenfactorial+1
jsr givayf
 
; since it's the bottom half of a larger number
; it may have the high bit set, which will cause the above to
; treat it as negative. If that happened, correct by adding 65536.
lda facsgn
beq ok ; it's positive, so skip the correction
 
; it's negative, so add 65536
lda #<fp65536
ldy #>fp65536
jsr fadd
 
ok:
; FAC now has lower half; add our copy of upper half
lda #<fac_copy
ldy #>fac_copy
jsr fadd
 
; and print out the result
jsr putfac
rts
 
.data
 
; 65536 as a float for operations
fp65536: .byte 129+16,0,0,0,0,0
 
; the actual value to print
tenfactorial: .dwordbyte 13,"10! = ",.string(10*9*8*7*6*5*4*3*2*1),13,0</syntaxhighlight>
 
.bss
; a place to stash partial results whlie using the FAC for other operations
fac_copy: .res 6</lang>
 
{{Out}}
Here's what it looks like when run immediately upon booting a C-64:
<pre>
**** COMMODORE 64 BASIC V2 ****
Line 143 ⟶ 110:
READY.
RUN:
 
3628800
10! = 3628800
 
READY.</pre>
Line 150 ⟶ 118:
VASM allows you to define values using mathematical operators prior to assembly, but you can only do this with constants.
The following are all valid:
<langsyntaxhighlight lang="68000devpac">tenfactorial equ 10*9*8*7*6*5*4*3*2
 
MOVE.L #tenfactorial,D1 ;load the constant integer 10! into D1
LEA tenfactorial,A1 ;load into A1 the memory address 10! = 0x375F00
ADD.L #tenfactorial,D2 ;add 10! to whatever is stored in D2 and store the result in D2</langsyntaxhighlight>
 
=={{header|8086 Assembly}}==
Since 10! is bigger than 16 bits, I'll use 8! instead to demonstrate. Most assemblers only support the standard C operators for compile-time calculation, so we're going to need to multiply out the factorial manually.
<syntaxhighlight lang="asm">mov ax,8*7*6*5*4*3*2 ;8! equals 40,320 or 0x9D80
call Monitor ;unimplemented routine, displays the register contents to screen</syntaxhighlight>
{{out}}
<tt>0x9D80</tt>
 
=={{header|Ada}}==
Here's a hardcoded version:
<langsyntaxhighlight lang="ada">
with Ada.Text_Io;
procedure CompileTimeCalculation is
Line 166 ⟶ 141:
Ada.Text_Io.Put(Integer'Image(Factorial));
end CompileTimeCalculation;
</syntaxhighlight>
</lang>
And here's a recursive function version that prints the exact same thing.
<langsyntaxhighlight lang="ada">
with Ada.Text_Io;
procedure CompileTimeCalculation is
Line 184 ⟶ 159:
begin
Ada.Text_Io.Put(Integer'Image(Fact10));
end CompileTimeCalculation;</langsyntaxhighlight>
 
===Unbounded Compile-Time Calculation===
Line 190 ⟶ 165:
An interesting property of Ada is that such calculations at compile time are performed with mathematical (i.e., unbounded) integers for intermediate results. On a compiler with 32-bit integers (gcc), the following code prints the value of '20 choose 10' = 184756:
 
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO;
 
procedure Unbounded_Compile_Time_Calculation is
Line 201 ⟶ 176:
-- Ada.Text_IO.Put_Line -- would not compile
-- ("Factorial(20) =" & Integer'Image(A_11_15 * A_16_20 * F_10));
end Unbounded_Compile_Time_Calculation;</langsyntaxhighlight>
 
The same compiler refuses to compile the two two lines
 
<langsyntaxhighlight Adalang="ada"> Ada.Text_IO.Put_Line -- would not compile
("Factorial(20) =" & Integer'Image(A_11_15 * A_16_20 * F_10));</langsyntaxhighlight>
 
because the final result A_11_15 * A_16_20 * F_10 is a '''value not in range of type "Standard.Integer"''' -- the same intermediate value that was used above to compute '20 choose 10'.
Line 213 ⟶ 188:
The values of AppleScript 'property' variables are set when a script's compiled, although they can also be changed when the script's run. (If it's a top-level script run from a compiled file, the values of its properties when it finishes are saved back to the file and the properties will start off with those values next time it's run.) Property declarations are single lines, but the lines can be calls to handlers declared upscript from the properties themselves.
 
<langsyntaxhighlight lang="applescript">-- This handler must be declared somewhere above the relevant property declaration
-- so that the compiler knows about it when compiling the property.
on factorial(n)
Line 230 ⟶ 205:
on run
return compiledValue
end run</langsyntaxhighlight>
 
{{output}}
<syntaxhighlight lang ="applescript">3628800</langsyntaxhighlight>
 
=={{header|Arturo}}==
<syntaxhighlight lang="arturo">f10: 1*2*3*4*5*6*7*8*9*10 ; this is evaluated at compile time
 
; the generate bytecode is:
; [ :bytecode
; ================================
; DATA
; ================================
; 0: 3628800 :integer
; 1: f10 :label
 
; ================================
; CODE
; ================================
; push0
; store1
; end
; ]
 
print f10</syntaxhighlight>
 
{{out}}
 
<pre>3628800</pre>
 
=={{header|BASIC}}==
Most BASICs perform compile-time calculation on anything they can determine is a constant. This can either be done explicitly:
<langsyntaxhighlight lang="qbasic">CONST factorial10 = 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10</langsyntaxhighlight>
 
or implicitly:
 
<langsyntaxhighlight lang="qbasic">DIM factorial10 AS LONG
factorial10 = 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10</langsyntaxhighlight>
 
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|BASIC256}}==
<syntaxhighlight lang="basic">factorial = 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10
print "10! = "; factorial # 3628800</syntaxhighlight>
 
=={{header|C}}==
Line 250 ⟶ 254:
 
The Order macro library [[Order|implements a full virtual machine and high-level, functional programming language]] available to C programs at compile-time:
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <order/interpreter.h>
 
Line 259 ⟶ 263:
printf("10! = %d\n", ORDER_PP( 8to_lit( 8fac(10) ) ) );
return 0;
}</langsyntaxhighlight>
 
In this example, the <code>8fac</code> function computes the factorial by folding <code>8times</code> (the binary multiplication primitive) over a numeric range created by <code>8seq_iota</code> (which requires <code>8X</code> to be incremented, as it creates lists from L to R-1), a familiar way of computing this in functional languages. The result of the factorial calculation is an internal, "native" number which need to be converted to decimal by the <code>8to_lit</code> function.
Line 272 ⟶ 276:
===C (simpler version)===
This is a simple version, showing that 10! was computed at compile time:
<langsyntaxhighlight lang="c">#include <stdio.h>
const int val = 2*3*4*5*6*7*8*9*10;
int main(void) {
printf("10! = %d\n", val );
return 0;
}</langsyntaxhighlight>
 
{{out}}<pre>10! = 3628800</pre>
Line 319 ⟶ 323:
</pre>
 
=={{header|C sharp|C#}}==
'''Compiler:''' Roslyn C#, language version 7.3
 
The Roslyn compiler performs constant folding at compile-time and emits IL that contains the result.
 
<langsyntaxhighlight lang="csharp">using System;
 
public static class Program
Line 333 ⟶ 337:
Console.WriteLine(FACTORIAL_10);
}
}</langsyntaxhighlight>
 
{{out|Emitted IL|note=disassembled with ILSpy}}
 
<!--CIL assembly has a similar overall syntax to C#, so colorize it as such.-->
<langsyntaxhighlight lang="csharp">.class public auto ansi abstract sealed beforefieldinit Program
extends [System.Runtime]System.Object
{
Line 358 ⟶ 362:
} // end of method Program::Main
 
} // end of class Program</langsyntaxhighlight>
 
Note that the constant field is generated only when both it and the containing class are visible outside of the assembly.
Line 364 ⟶ 368:
Constant expressions that appear outside of constant declarations are also folded, so
 
<langsyntaxhighlight lang="csharp">using System;
 
static class Program
Line 372 ⟶ 376:
Console.WriteLine(10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1);
}
}</langsyntaxhighlight>
 
and
 
<langsyntaxhighlight lang="csharp">using System;
 
static class Program
Line 386 ⟶ 390:
Console.WriteLine(factorial);
}
}</langsyntaxhighlight>
 
produce the same IL, except without the field.
Line 392 ⟶ 396:
{{out|Emitted IL|note=disassembled with ILSpy}}
 
<langsyntaxhighlight lang="csharp">.class private auto ansi abstract sealed beforefieldinit Program
extends [System.Runtime]System.Object
{
Line 409 ⟶ 413:
} // end of method Program::Main
 
} // end of class Program</langsyntaxhighlight>
 
{{out}}
Line 416 ⟶ 420:
=={{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.
<langsyntaxhighlight lang="cpp">#include <iostream>
 
template<int i> struct Fac
Line 433 ⟶ 437:
std::cout << "10! = " << Fac<10>::result << "\n";
return 0;
}</langsyntaxhighlight>
 
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.
Line 440 ⟶ 444:
Alternative version, using constexpr in C++11:
 
<langsyntaxhighlight lang="cpp">#include <stdio.h>
 
constexpr int factorial(int n) {
Line 451 ⟶ 455:
printf("%d\n", f10);
return 0;
}</langsyntaxhighlight>
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:
<langsyntaxhighlight lang="asm">_main:
pushl %ebp
movl %esp, %ebp
Line 466 ⟶ 470:
movl $0, %eax
leave
ret</langsyntaxhighlight>
 
 
=={{header|C3}}==
C3 has semantic macros that use a different syntax from the regular runtime syntax.
 
<syntaxhighlight lang="c">macro int factorial($n)
{
$if ($n == 0):
return 1;
$else:
return $n * factorial($n - 1);
$endif;
}
 
extern fn void printf(char *fmt, ...);
 
fn void main()
{
int x = factorial(10);
printf("10! = %d\n", x);
}</syntaxhighlight>
 
{{out}}
<pre>10! = 3628800</pre>
 
=={{header|Clojure}}==
<langsyntaxhighlight lang="clojure">
(defn fac [n] (apply * (range 1 (inc n))))
(defmacro ct-factorial [n] (fac n))</langsyntaxhighlight>
 
=={{header|Common Lisp}}==
Line 477 ⟶ 505:
Assuming a definition from [[Factorial function#Common Lisp]], we first have to make a small adjustment so that the function is available at compile time. Common Lisp does not have a single image building and deployment model. For instance, Common Lisp implementations can support a "C like" model whereby a compiler is invoked as a separate process to handle individual files, which are then loaded to form an image (analogous to linking). A Lisp compiler will not make available to itself the functions in a source file which it happens to be compiling, unless told to do so:
 
<langsyntaxhighlight lang="lisp">(eval-when (:compile-toplevel :load-toplevel :execute)
(defun factorial ...))</langsyntaxhighlight>
 
With that, here are ways to do compile-time evaluation:
 
<langsyntaxhighlight lang="lisp">(defmacro ct-factorial (n)
(factorial n))
 
...
 
(print (ct-factorial 10))</langsyntaxhighlight>
 
The <code>factorial</code> function must be defined before any use of the <code>ct-factorial</code> macro is evaluated or compiled.
Line 493 ⟶ 521:
If the data resulting from the compile-time calculation is not necessarily a number or other [http://www.lispworks.com/documentation/HyperSpec/Body/03_abac.htm self-evaluating object], as it is in the factorial case, then the macro must quote it to avoid it being interpreted as code (a form):
 
<langsyntaxhighlight lang="lisp">(defmacro ct-factorial (n)
`(quote ,(factorial n)))
 
; or, equivalently,
(defmacro ct-factorial (n)
`',(factorial n))</langsyntaxhighlight>
 
It is also possible to have a value [http://www.lispworks.com/documentation/HyperSpec/Body/s_ld_tim.htm computed at ''load time''], when the code is loaded into the process, rather than at compile time; this is useful if the value to be computed contains objects that do not yet exist at compile time, or the value might vary due to properties which might be different while yet using the same compiled program (e.g. pathnames), but it is still constant for one execution of the program:
 
<langsyntaxhighlight lang="lisp">(print (load-time-value (factorial 10)))</langsyntaxhighlight>
 
Further it's also possible to have the value computed at read time using the read macro <code>#.</code> .
 
<langsyntaxhighlight lang="lisp">(print (#. (factorial 10)))</langsyntaxhighlight>
 
Lastly, Common Lisp has "compiler macros" which are user-defined handlers for function call optimization. A compiler macro is defined which has the same name as some user-defined function. When calls to that function are being compiled, they pass through the macro. The macro must analyze the arguments and rewrite the function call into something else, or return the original form.
 
<langsyntaxhighlight lang="lisp">(define-compiler-macro factorial (&whole form arg)
(if (constantp arg)
(factorial arg)
form))</langsyntaxhighlight>
 
Test with CLISP (taking advantage of its <code>!</code> function) showing how a factorial call with a constant argument of 10 ends up compiled to the constant 3268800, but a factorial call with the argument a is compiled to a variable access and function call:
Line 554 ⟶ 582:
=={{header|D}}==
The D compiler is able to run many functions at compile-time [http://dlang.org/function.html#interpretation Compile Time Function Execution (CTFE)]:
<langsyntaxhighlight lang="d">long fact(in long x) pure nothrow @nogc {
long result = 1;
foreach (immutable i; 2 .. x + 1)
Line 568 ⟶ 596:
 
printf("%ld\n", fact10);
}</langsyntaxhighlight>
 
The 32-bit asm generated by DMD shows the computation is done at compile-time:
<langsyntaxhighlight lang="asm">__Dmain
push EAX
mov EAX,offset FLAT:_DATA
Line 581 ⟶ 609:
xor EAX,EAX
pop ECX
ret</langsyntaxhighlight>
 
=={{header|Delphi}}==
Line 589 ⟶ 617:
In DWScript, constant expressions and referentially-transparent built-in functions, such as ''Factorial'', are evaluated at compile time.
 
<langsyntaxhighlight lang="delphi">const fact10 = Factorial(10);</langsyntaxhighlight>
 
=={{header|EchoLisp}}==
'''define-constant''' may be used to compute data, which in turn may be used in other define-constant, or in the final code.
<langsyntaxhighlight lang="scheme">
(define-constant DIX! (factorial 10))
(define-constant DIX!+1 (1+ DIX!))
Line 599 ⟶ 627:
(writeln DIX!+1)
3628801
</syntaxhighlight>
</lang>
 
=={{header|EDSAC order code}}==
Under David Wheeler's Initial Orders 2, the effect of compile-time calculation could be achieved on EDSAC by the use of "interludes" in the loading process. Code for an interlude was loaded into store, then loading was paused while the interlude was executed. When finished, the interlude passed control back to initial orders, and normal loading was resumed. Code that was used only by the interlude could then be overwritten. In this way once-only code was not left taking up storage space, which was in short supply on EDSAC.
 
Interludes could be used for calculation or for other purposes. E.g. the library subroutine M3 ran as an interlude; it printed a header on the teleprinter, and then M3 and the header text were overwritten.
 
Code for an interlude should not change locations in the initial orders. Also, if the multiplier register is used, its original value should be restored before exit from the interlude. The interlude in the demo program below is based on a shorter example in Wilkes, Wheeler & Gill, 1951 edn, p. 112.
<syntaxhighlight lang="edsac">
[Demo of calculating a constant in an interlude at load time.
EDSAC program, Initial Orders 2.]
 
[Arrange the storage]
T46K P56F [N parameter: library subroutine P7 to print integer]
T47K P100F [M parameter: main routine]
 
E25K TM GK [M parameter, main routine]
T#Z PF [clear 35-bit value at relative locations
0 & 1, including the middle ("sandwich") bit]
T2#Z PF [same for 2 & 3]
T4#Z PF [same for 4 & 5]
TZ [resume normal loading at relative location 0]
[Storage for interlude, must be at even address]
[0] PD PF [35-bit factorial, initially integer 1]
[2] PD PF [35-bit factor 1..10, initially integer 1]
[4] PF K4096F [to save multiplier register (MR), initially floating point -1]
[6] PD [17-bit integer 1]
[7] P5F [17-bit integer 10 (or number whose factorial is required)]
[8] PF [dump for clearing acc]
[Executable code for interlude; here with acc = 0]
[9] N4#@ [acc := MR, by subtracting (-1 * MR)]
T4#@ [save MR over interlude]
[11] T8@ [start of loop: clear acc]
A2@ [acc := factor]
A6@ [add 1]
T2@ [update factor, clear acc]
H2#@ [MR := factor, extended to 35 bits]
V#@ [times 35-bit product, result in acc]
L1024F L1024F L256F [integer scaling: shift 34 left]
T#@ [update product]
A2@ [acc := factor just used]
S7@ [is it 10 yet?]
G11@ [if not, loop back]
H4#@ [restore MR before exit from interlude]
E25F [pass control back to initial orders]
[At this point the interlude has been loaded but not executed.
The next control combination starts execution.]
E9Z [pass control to relative location 9 above]
PF [value in accumulator when control is passed: here = 0]
[After the interlude, loading resumes here.]
T2Z [resume normal loading at relative location 2,
overwriting the above interlude except the factorial]
[Teleprinter characters]
[2] #F [set figures mode]
[3] @F [carriage return]
[4] &F [line feed]
[Enter here with acc = 0]
[5] O2@ [set teleprinter to figures]
A#@ [acc := factorial, as calculated in the interlude]
TD [pass to print subroutine]
[8] A8@ GN [call print subroutine]
O3@ O4@ [print CR, LF]
O2@ [dummy character to flush teleprinter buffer]
ZF [stop]
 
E25K TN [N parameter]
[Library subroutine P7, prints 35-bit strictly positive integer in 0D.]
[10 characters, right justified, padded left with spaces.]
[Even address; 35 storage locations; working position 4D.]
GKA3FT26@H28#@NDYFLDT4DS27@TFH8@S8@T1FV4DAFG31@SFLDUFOFFFSF
L4FT4DA1FA27@G11@XFT28#ZPFT27ZP1024FP610D@524D!FO30@SFL8FE22@
 
E25K TM GK [M parameter again]
E5Z [define entry point]
PF [acc = 0 on entry]
</syntaxhighlight>
{{out}}
<pre>
3628800
</pre>
 
=={{header|Erlang}}==
Line 607 ⟶ 714:
Technically, this calculation happens at parse-time, before any compilation takes place. Calculating factorial at compile-time is not useful in Factor.
 
<langsyntaxhighlight lang="factor">: factorial ( n -- n! ) [1,b] product ;
 
CONSTANT: 10-factorial $[ 10 factorial ]</langsyntaxhighlight>
 
=={{header|Forth}}==
During a word definition, you can drop out of the compilation state with '''[''' and go back in with ''']'''. (This is where the naming conventions for '''[CHAR]''' and '''[']''' come from.) There are several flavors of '''LITERAL''' for compiling the result into the word.
 
<langsyntaxhighlight lang="forth">: fac ( n -- n! ) 1 swap 1+ 2 max 2 ?do i * loop ;
 
: main ." 10! = " [ 10 fac ] literal . ;
Line 620 ⟶ 727:
see main
: main
.\" 10! = " 3628800 . ; ok</langsyntaxhighlight>
 
Outside of a word definition, it's fuzzy. If the following code is itself followed by a test and output, and is run in a script, then the construction of the '''bignum''' array (and the perhaps native-code compilation of '''more''') happens at runtime. If the following code is followed by a command that creates an executable, the array will not be rebuilt on each run.
 
<langsyntaxhighlight lang="forth">
: more ( "digits" -- ) \ store "1234" as 1 c, 2 c, 3 c, 4 c,
parse-word bounds ?do
Line 633 ⟶ 740:
more 73167176531330624919225119674426574742355349194934
more 96983520312774506326239578318016984801869478851843
...</langsyntaxhighlight>
 
=={{header|Fortran}}==
In Fortran, parameters can be defined where the value is computed at compile time:
<langsyntaxhighlight lang="fortran"> program test
 
implicit none
Line 645 ⟶ 752:
 
end program test
</syntaxhighlight>
</lang>
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang="freebasic">' FB 1.05.0 Win64
 
' Calculations can be done in a Const declaration at compile time
Line 655 ⟶ 762:
Const factorial As Integer = 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10
Print factorial ' 3628800
Sleep</langsyntaxhighlight>
 
=={{header|Go}}==
Constant expressions are evaluated at compile time. A constant expression though, is pretty simple and can't have much more than literals, operators, and a special thing called iota. There is no way to loop in a constant expression and so the expanded expression below is about the simplest way of completing this task.
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 665 ⟶ 772:
func main() {
fmt.Println(2*3*4*5*6*7*8*9*10)
}</langsyntaxhighlight>
 
=={{header|Haskell}}==
Line 671 ⟶ 778:
With Template Haskell, it is quite easy to do compile time embedding. The functions used at compile-time need to be already compiled. Therefore, you generally need two modules.
 
<langsyntaxhighlight lang="haskell">module Factorial where
import Language.Haskell.TH.Syntax
 
Line 677 ⟶ 784:
 
factQ :: Integer -> Q Exp
factQ = lift . fact</langsyntaxhighlight>
 
<langsyntaxhighlight lang="haskell">{-# LANGUAGE TemplateHaskell #-}
import Factorial
 
main = print $(factQ 10)</langsyntaxhighlight>
 
Note: Doing <code>$([|fact 10|])</code> is the same than doing <code>fact 10</code>. <code>[|something|]</code> returns the abstract syntax tree of <code>something</code>. Thus <code>[|fact 10|]</code> returns the AST of the call to the <code>fact</code> function with 10 as argument. <code>$(something)</code> waits for an AST from a call to <code>something</code>.
Line 692 ⟶ 799:
Thus, a program which prints 10 factorial:
 
<langsyntaxhighlight Jlang="j">pf10=: smoutput bind (!10)</langsyntaxhighlight>
 
When the definition of pf10 is examined, it contains the value 3628800. J has several ways of representing tacit programs. Here all five of them are presented for this program (the last two happen to look identical for this trivial case):
 
<langsyntaxhighlight Jlang="j"> 9!:3]1 2 4 5 6
 
pf10
Line 721 ⟶ 828:
└─ " ──────┴─ _
smoutput@(3628800"_)
smoutput@(3628800"_)</langsyntaxhighlight>
 
Finally, when this program is run, it displays this number:
 
<langsyntaxhighlight Jlang="j"> pf10 ''
3628800</langsyntaxhighlight>
 
Note: Currently, the mediawiki implementation is corrupting the above display due to a cascading sequence of bad design decisions and mis-interpreted specifications on the part of someone "contributing" to that implementation. To work around this issue, and see the original display, you can currently use either the "Edit" or "View Source" option, depending on whether you are logged in to rosettacode with an account that has edit rights here. (Please don't actually save changes though.) If you are using View Source, you might want to do that in a new tab (so you also stay here with this view) and use your browser's search capability to quickly scroll to this location in the source view.
 
=={{header|Java}}==
<pre>
The Java compiler is able to calculate expressions that contain constant variables
and certain operators during code compilation.
As defined in the Java language specification,
the following operators and expressions may be used for constant expressions:
 
Unary operators: +, -, ~, !
Multiplicative operators: *, /, %
Additive operators: +, –
Shift operators: <<, >>, >>>
Relational operators: <, <=, >, >=
Equality operators: ==, !=
Bitwise and logical operators: &, ^, |
Conditional-and and the conditional-or operator: &&, ||
Ternary conditional operator: ?:
Parenthesized expressions whose contained expression is a constant expression
Simple names that refer to constant variables
</pre>
<syntaxhighlight lang="java">
 
public final class CompileTimeCalculation {
 
public static void main(String[] aArgs) {
System.out.println(tenFactorial);
}
private static int tenFactorial = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1;
 
}
</syntaxhighlight>
{{ out }}
<pre>
3628800
</pre>
 
=={{header|Julia}}==
Julia includes a powerful macro feature that can perform arbitrary code transformations at compile-time (or technically at parse-time), and can also execute arbitrary Julia code. For example, the following macro computes the factorial of <code>n</code> (a literal constant) and returns the value (e.g. to inline it in the resulting source code)
<langsyntaxhighlight lang="julia">macro fact(n)
factorial(n)
end</langsyntaxhighlight>
If we now use this in a function, e.g.
<langsyntaxhighlight lang="julia">foo() = @fact 10</langsyntaxhighlight>
then the value of 10! = 3628800 is computed at parse-time and is inlined in the compiled function <code>foo</code>, as can be verified by inspecting the assembly code via the built-in function <code>code_native(foo, ())</code>.
 
=={{header|Kotlin}}==
Compile time calculations are possible in Kotlin using the 'const' modifier provided one sticks to literals or other constants when specifying the calculation to be performed:
<langsyntaxhighlight lang="scala">// version 1.0.6
const val TEN_FACTORIAL = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2
 
fun main(args: Array<String>) {
println("10! = $TEN_FACTORIAL")
}</langsyntaxhighlight>
 
{{out}}
Line 755 ⟶ 899:
=={{header|Lingo}}==
As an interpreted language with the interpreter always being present, Lingo has no clear separation of compile-time and runtime. Whenever you change the code of a script at runtime, it's immediately (re)compiled to bytecode (in memory). You can also create new scripts at runtime:
<langsyntaxhighlight lang="lingo">-- create new (movie) script at runtime
m = new(#script)
 
Line 762 ⟶ 906:
 
put fac10()
-- 3628800</langsyntaxhighlight>
 
=={{header|Lua}}==
Lua's compiler will attempt to fold constant expressions, which appears to be enough to satisfy this specific task's requirements:
<langsyntaxhighlight lang="lua">local factorial = 10*9*8*7*6*5*4*3*2*1
print(factorial)</langsyntaxhighlight>
{{out}}<pre>3628800</pre>
Proof via disassembly (Lua 5.3 used - the lookup of global "print" may vary a bit among 5.x versions, but not significant):
Line 786 ⟶ 930:
This example uses m4 as a front end to [[AWK]]. m4 calculates factorial of 10, where AWK program calls macro.
 
<langsyntaxhighlight lang="m4">define(`factorial',
`ifelse($1, 0, 1, `eval($1 * factorial(eval($1 - 1)))')')dnl
dnl
BEGIN {
print "10! is factorial(10)"
}</langsyntaxhighlight>
 
One runs <code>m4 program.m4 > program.awk</code> to make this valid AWK program.
 
<langsyntaxhighlight lang="awk">BEGIN {
print "10! is 3628800"
}</langsyntaxhighlight>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
Mathematica is not a compiled language, you can construct compiled functions in Mathematica by the build-in function "Compile". Constants are calculated at "compile-time".
<syntaxhighlight lang="text">f = Compile[{}, 10!]</langsyntaxhighlight>
{{Out}}
<pre>CompiledFunction[{},3628800,-CompiledCode-]</pre>
<syntaxhighlight lang="text">f[]</langsyntaxhighlight>
{{Out}}
<pre>3628800</pre>
 
=={{header|MIPS Assembly}}==
While most assemblers support compile-time expressions, factorial is typically not one of them. However, you can multiply out the factorial manually. It's not feasible for larger factorials but it's better than nothing.
<syntaxhighlight lang="mips">li t0,10*9*8*7*6*5*4*3*2 ;= 10! = 0x375F00
jal monitor ;display all registers to the screen
nop</syntaxhighlight>
{{out}}
<pre>t0:00375F00</pre>
 
=={{header|Nim}}==
Nim can evaluate procedures at compile-time, this can be forced by calling a procedure with a const keyword like so:
 
<langsyntaxhighlight Nimlang="nim">proc fact(x: int): int =
result = 1
for i in 2..x:
Line 817 ⟶ 969:
 
const fact10 = fact(10)
echo(fact10)</langsyntaxhighlight>
 
We can see that this is evaluated at compile-time by looking at the generated C code:
 
<langsyntaxhighlight Clang="c">...
STRING_LITERAL(TMP122, "3628800", 7);
...</langsyntaxhighlight>
 
The Nim compiler can also be told to try to evaluate procedures at compile-time even for variables by using the --implicitStatic:on command line switch.
Line 830 ⟶ 982:
=={{header|Oberon-2}}==
Works with oo2c Version 2
<langsyntaxhighlight lang="oberon2">
MODULE CompileTime;
IMPORT
Line 839 ⟶ 991:
Out.String("10! =");Out.LongInt(tenfac,0);Out.Ln
END CompileTime.
</syntaxhighlight>
</lang>
 
=={{header|Objeck}}==
Objeck will fold constants at compiler time as long as the -s2 or -s3 compiler switches are enabled.
 
<langsyntaxhighlight lang="objeck">
bundle Default {
class CompileTime {
Line 852 ⟶ 1,004:
}
}
</syntaxhighlight>
</lang>
 
=={{header|OCaml}}==
Line 858 ⟶ 1,010:
OCaml does not calculate operations that involve functions calls, as for example factorial 10, but OCaml does calculate simple mathematical operations at compile-time, for example in the code below <code>(24 * 60 * 60)</code> will be replaced by its result <code>86400</code>.
 
<langsyntaxhighlight lang="ocaml">let days_to_seconds n =
let conv = 24 * 60 * 60 in
(n * conv)
;;</langsyntaxhighlight>
 
It is easy to verify this using the argument <code>-S</code> to keep the intermediate assembly file:
Line 870 ⟶ 1,022:
If you wish to verify this property in your own projects, you have to know that integer values most often have their OCaml internal representation in the assembly, which for an integer <code>x</code> its OCaml internal representation will be <code>(((x) << 1) + 1)</code>. So for example if we modify the previous code for:
 
<langsyntaxhighlight lang="ocaml">let conv = 24 * 60 * 60
 
let days_to_seconds n =
(n * conv)
;;</langsyntaxhighlight>
 
# (24 * 60 * 60) lsl 1 + 1 ;;
Line 885 ⟶ 1,037:
However, with the introduction of [https://github.com/ocaml-flambda/flambda-backend Flambda] (an alternative intermediate language, inliner, and optimiser), OCaml compilers which equip this backend have a limited ability to reduce pure and annotated function calls to constants:
 
<langsyntaxhighlight lang="ocaml">let fact10 =
let rec factorial n =
if n = 1 then n else n * factorial (n-1)
Line 893 ⟶ 1,045:
(* The unrolled annotation is what allows flambda to keep reducing the call
* Beware that the number of unrollings must be greater than or equal to the
* number of iterations (recursive calls) for this to compile down to a constant. *)</langsyntaxhighlight>
 
The assembler output (cleaned up and demangled a little) shows exactly what's expected, stored as data
Line 912 ⟶ 1,064:
You can do any calculation you want before or after, create constants, ...
 
<langsyntaxhighlight Oforthlang="oforth">10 seq reduce(#*) Constant new: FACT10
: newFunction FACT10 . ;</langsyntaxhighlight>
 
You can also calculate all factorials for 1 to 20 before defining fact method :
<langsyntaxhighlight Oforthlang="oforth">20 seq map(#[ seq reduce(#*) ]) Constant new: ALLFACTS
: fact(n) n ifZero: [ 1 ] else: [ ALLFACTS at(n) ] ;
 
ALLFACTS println</langsyntaxhighlight>
 
{{out}}
Line 933 ⟶ 1,085:
To dimension a static array, the macro Pling10 is resolved at compile time. The overall compile time (ready to execute) was around 23 milliseconds.
 
<langsyntaxhighlight lang="oxygenbasic">
'LIBRARY CALLS
'=============
Line 986 ⟶ 1,138:
o2_exec 'Run the program
end if
</syntaxhighlight>
</lang>
 
=={{header|Oz}}==
<langsyntaxhighlight lang="oz">functor
import
System Application
Line 1,000 ⟶ 1,152:
{System.showInfo "10! = "#Fac10}
{Application.exit 0}
end</langsyntaxhighlight>
 
Code in the <code>prepare</code> section of a functor is executed at compile time. External modules that are used in this code must be imported with a <code>require</code> statement (not shown in this example). Such external functors must have been compiled before the current functor is compiled (<code>ozmake</code> will automatically take care of this).
Line 1,011 ⟶ 1,163:
as the values can be resolved.
 
<langsyntaxhighlight lang="pascal">
program in out;
 
Line 1,023 ⟶ 1,175:
 
end;
</syntaxhighlight>
</lang>
 
=={{header|Perl}}==
Line 1,029 ⟶ 1,181:
There are few limits on code you can put in <code>BEGIN</code> blocks, which are executed at compile-time. Unfortunately, you can't in general save the compiled form of a program to run later. Instead, <code>perl</code> recompiles your program every time you run it.
 
<langsyntaxhighlight lang="perl">my $tenfactorial;
print "$tenfactorial\n";
 
BEGIN
{$tenfactorial = 1;
$tenfactorial *= $_ foreach 1 .. 10;}</langsyntaxhighlight>
 
Note however that all constant folding is done at compile time, so this actually does the factorial at compile time.
 
<langsyntaxhighlight lang="perl">my $tenfactorial = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2;</langsyntaxhighlight>
 
=={{header|Phix}}==
The Phix compiler uses constant folding/propagation, so running p -d on the following snippet
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>integer a,b
<span style="color: #004080;">integer</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span>
a = 10*9*8*7*6*5*4*3*2*1
<span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">10</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span><span style="color: #0000FF;">*</span><span style="color: #000000;">8</span><span style="color: #0000FF;">*</span><span style="color: #000000;">7</span><span style="color: #0000FF;">*</span><span style="color: #000000;">6</span><span style="color: #0000FF;">*</span><span style="color: #000000;">5</span><span style="color: #0000FF;">*</span><span style="color: #000000;">4</span><span style="color: #0000FF;">*</span><span style="color: #000000;">3</span><span style="color: #0000FF;">*</span><span style="color: #000000;">2</span><span style="color: #0000FF;">*</span><span style="color: #000000;">1</span>
b = factorial(10)
<span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">factorial</span><span style="color: #0000FF;">(</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span>
?{a,b}</lang>
<span style="color: #0000FF;">?{</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">}</span>
<!--</syntaxhighlight>-->
produces a listing file containing
<pre>
Line 1,067 ⟶ 1,221:
runs, arbitrary expressions can be executed with the backqoute and tilde
operators ([http://software-lab.de/doc/ref.html#macro-io read macros]).
<langsyntaxhighlight PicoLisplang="picolisp">(de fact (N)
(apply * (range 1 N)) )
 
(de foo ()
(prinl "The value of fact(10) is " `(fact 10)) )</langsyntaxhighlight>
Output:
<pre>: (pp 'foo) # Pretty-print the function
Line 1,083 ⟶ 1,237:
 
=={{header|PL/I}}==
<syntaxhighlight lang="pl/i">
<lang PL/I>
/* Factorials using the pre-processor. */
test: procedure options (main);
Line 1,110 ⟶ 1,264:
 
end test;
</syntaxhighlight>
</lang>
 
Output from the pre-processor:
 
<syntaxhighlight lang="text">
/* Factorials using the pre-processor. */
test: procedure options (main);
Line 1,123 ⟶ 1,277:
put skip list ('factorial 6 is ', y);
end test;
</syntaxhighlight>
</lang>
 
Execution results:
 
<syntaxhighlight lang="text">
factorial 4 is 24
factorial 6 is 720
</syntaxhighlight>
</lang>
 
=={{header|PowerShell}}==
<syntaxhighlight lang="powershell">
<lang PowerShell>
function fact([BigInt]$n){
if($n -ge ([BigInt]::Zero)) {
Line 1,148 ⟶ 1,302:
"$((Measure-Command {$fact = fact 10}).TotalSeconds) Seconds"
$fact
</syntaxhighlight>
</lang>
<b>Output:</b>
<pre>
Line 1,159 ⟶ 1,313:
 
goal_expansion/2 will change the goal in the code at compile time to be something else, in the case the constant number.
<langsyntaxhighlight Prologlang="prolog">% Taken from RosettaCode Factorial page for Prolog
fact(X, 1) :- X<2.
fact(X, F) :- Y is X-1, fact(Y,Z), F is Z*X.
Line 1,167 ⟶ 1,321:
test :-
F = factorial_of(10),
format('!10 = ~p~n', F).</langsyntaxhighlight>
{{out}}
<pre>
Line 1,182 ⟶ 1,336:
=={{header|PureBasic}}==
PureBasic will do most calculation during compiling, e.g.
<langsyntaxhighlight PureBasiclang="purebasic">a=1*2*3*4*5*6*7*8*9*10</langsyntaxhighlight>
could on a x86 be complied to
<pre>MOV dword [v_a],3628800</pre>
Line 1,190 ⟶ 1,344:
To compute and print 10! during compilation:
 
<langsyntaxhighlight Quackerylang="quackery">[ 1 10 times [ i 1+ * ] echo ] now!</langsyntaxhighlight>
 
To compute 10! during compilation and print the result at runtime:
 
<langsyntaxhighlight Quackerylang="quackery">[ 1 10 times [ i 1+ * ] ] constant echo</langsyntaxhighlight>
 
Any Quackery code can be executed during compilation, but the programmer must bear in mind that the compiler uses the stack, so executed code should have no overall stack effect in the case of <code>now!</code>, or leave a single item on the stack to be compiled in the case of <code>constant</code>.
Line 1,202 ⟶ 1,356:
Racket, like most Lisp descendants, allows arbitrary code to be executed at compile-time.
 
<langsyntaxhighlight lang="racket">
#lang racket
 
Line 1,224 ⟶ 1,378:
;; use the macro defined above
(fact10)
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
(formerly Perl 6)
 
<syntaxhighlight lang="raku" perl6line>constant $tenfact = [*] 2..10;
say $tenfact;</langsyntaxhighlight>
 
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 inas the surroundingan expression at run time:
 
<syntaxhighlight lang="raku" perl6line> say( BEGIN [*] 2..10);</langsyntaxhighlight>
 
=={{header|REXX}}==
Line 1,260 ⟶ 1,414:
 
Since REXX is an interpreted language &nbsp; (as are other languages entered for this Rosetta Code task), &nbsp; run time is compile time.
<langsyntaxhighlight lang="rexx">/*REXX program computes 10! (ten factorial) during REXX's equivalent of "compile─time". */
 
say '10! =' !(10)
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
!: procedure; !=1; do j=2 to arg(1); !=!*j; end /*j*/; return !</langsyntaxhighlight>
'''output'''
<pre>
Line 1,272 ⟶ 1,426:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
a = 10*9*8*7*6*5*4*3*2*1
b = factorial(10)
Line 1,279 ⟶ 1,433:
 
func factorial nr if nr = 1 return 1 else return nr * factorial(nr-1) ok
</syntaxhighlight>
</lang>
 
=={{header|Run BASIC}}==
{{works with|Just BASIC}}
{{works with|Liberty BASIC}}
<syntaxhighlight lang="vb">factorial = 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10
print "10! = "; factorial ' 3628800</syntaxhighlight>
 
=={{header|Rust}}==
The Rust compiler can automatically do optimizations in the code to calculate the factorial.
 
<langsyntaxhighlight lang="rust">fn factorial(n: i64) -> i64 {
let mut total = 1;
for i in 1..n+1 {
Line 1,294 ⟶ 1,454:
fn main() {
println!("Factorial of 10 is {}.", factorial(10));
}</langsyntaxhighlight>
 
If we compile this with <code>rustc factorial.rs -O --emit asm</code> and inspect the outputted assembly, we can see <code>movq $3628800, (%rsp)</code>. This means the result of 3628800 was calculated in compile-time rather than run-time.
 
=={{header|Scala}}==
 
<lang Scala>object Main extends {
Scala 3 supports proper compile time evaluation
 
<syntaxhighlight lang="scala">
transparent inline def factorial(inline n: Int): Int =
inline n match
case 0 => 1
case _ => n * factorial(n - 1)
 
inline val factorial10/*: 3628800*/ = factorial(10)
</syntaxhighlight>
 
Alternative version that works with Scala 2:
 
<syntaxhighlight lang="scala">object Main extends {
val tenFactorial = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2
 
Line 1,305 ⟶ 1,479:
 
println(s"10! = $tenFactorial", tenFac)
}</langsyntaxhighlight>
As it can been seen in the always heavily optimized run-time code the calculations are already computed for the field constant and function method.
<pre>
Line 1,343 ⟶ 1,517:
The ! operator is predefined, so no user defined function is necessary.
 
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
 
const proc: main is func
Line 1,350 ⟶ 1,524:
begin
writeln(factorial);
end func;</langsyntaxhighlight>
 
=={{header|Sidef}}==
The compile-time evaluation is limited at a constant expression, which cannot refer at any other user-defined data, such as variables or functions.
<langsyntaxhighlight lang="ruby">define n = (10!);
say n;</langsyntaxhighlight>
 
or:
<langsyntaxhighlight lang="ruby">define n = (func(n){ n > 0 ? __FUNC__(n-1)*n : 1 }(10));
say n;</langsyntaxhighlight>
 
=={{header|Tcl}}==
Line 1,365 ⟶ 1,539:
 
{{works with|Tcl|8.5}}
<langsyntaxhighlight lang="tcl">proc makeFacExpr n {
set exp 1
for {set i 2} {$i <= $n} {incr i} {
Line 1,372 ⟶ 1,546:
return "expr \{$exp\}"
}
eval [makeFacExpr 10]</langsyntaxhighlight>
How to show that the results were compiled? Like this:
<langsyntaxhighlight lang="tcl">% tcl::unsupported::disassemble script [makeFacExpr 10]
ByteCode 0x0x4de10, refCt 1, epoch 3, interp 0x0x31c10 (epoch 3)
Source "expr {1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10}"
Line 1,383 ⟶ 1,557:
(0) push1 0 # "3628800"
(2) done
</syntaxhighlight>
</lang>
As you can see, that expression was transformed into just a push of the results (and an instruction to mark the end of the bytecode segment).
 
=={{header|TXR}}==
 
In TXR Lisp, the standard <code>macro-time</code> macro evaluates an expression at macro-expansion time, and replaces it by its result, which is then treated as a literal (because the macro inserts `quote` around it, if required).
 
Such a macro is easy to implement in Common Lisp and similar dialects. The [https://www.nongnu.org/txr/txr-manpage.html#N-0131B069 documentation] provides a reference implementation which is easily ported.
 
Example: provide a function <code>buildinfo</code> in the compiled program which returns the build machine name, and time and date of the compilation. A global variable which provides this value could similarly be defined:
 
<syntaxhighlight lang="txrlisp">
(defun buildinfo ()
(macro-time
`Built by @{(uname).nodename} on @(time-string-local (time) "%c")`))
</syntaxhighlight>
 
If we compile and disassemble the function, we see it just contains a canned literal:
 
<pre>
3> (compile 'buildinfo)
#<vm fun: 0 param>
4> (disassemble *3)
data:
0: buildinfo
1: "Built by sun-go on Sat Oct 1 20:01:25 2022"
syms:
code:
0: 8C000005 close t2 0 2 5 0 0 nil
1: 00000002
2: 00000000
3: 00000002
4: 10000401 end d1
5: 10000002 end t2
instruction count:
3
entry point:
4
#<vm fun: 0 param>
</pre>
 
=={{header|Ursala}}==
Any user-defined or library function callable at run time can also be called at compile time
and evaluated with no unusual ceremony involved.
<langsyntaxhighlight Ursalalang="ursala">#import nat
 
x = factorial 10
Line 1,395 ⟶ 1,607:
#executable&
 
comcal = ! (%nP x)--<''></langsyntaxhighlight>
some notes:
* <code>x</code> is declared as a constant equal to ten factorial using the <code>factorial</code> function imported from the <code>nat</code> library.
Line 1,423 ⟶ 1,635:
The Roslyn compiler performs constant folding at compile-time and emits IL that contains the result.
 
<langsyntaxhighlight lang="vbnet">Module Program
Const FACTORIAL_10 = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1
 
Line 1,429 ⟶ 1,641:
Console.WriteLine(FACTORIAL_10)
End Sub
End Module</langsyntaxhighlight>
 
{{out|Emitted IL|note=disassembled with ILSpy}}
 
<!--CIL assembly has a similar overall syntax to C#, so colorize it as such.-->
<langsyntaxhighlight lang="csharp">.class private auto ansi sealed Program
extends [System.Runtime]System.Object
{
Line 1,460 ⟶ 1,672:
} // end of method Program::Main
 
} // end of class Program</langsyntaxhighlight>
 
Constant expressions that appear outside of constant declarations are also folded, so
 
<langsyntaxhighlight lang="vbnet">Module Program
Sub Main()
Console.WriteLine(10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1)
End Sub
End Module</langsyntaxhighlight>
 
and
 
<langsyntaxhighlight lang="vbnet">Module Program
Sub Main()
Dim factorial As Integer
Line 1,478 ⟶ 1,690:
Console.WriteLine(factorial)
End Sub
End Module</langsyntaxhighlight>
 
produce the same IL, albeit without the constant field that other assemblies can reference.
 
{{out|Emitted IL|note=disassembled with ILSpy}}
<langsyntaxhighlight lang="csharp">.class private auto ansi sealed Program
extends [System.Runtime]System.Object
{
Line 1,506 ⟶ 1,718:
} // end of method Program::Main
 
} // end of class Program</langsyntaxhighlight>
 
{{out}}
Line 1,516 ⟶ 1,728:
Also Wren has no notion of constants - at compile time or otherwise - and is thoroughly object-oriented. Even literals such as ''123'' and ''true'' are technically instances of the immutable built-in classes Num and Bool.
 
There is little public information on the workings of the bytecode compiler other than that it is single pass and stack based. However, from what I havegather said above, I'd be surprised ifthat it does anyno calculationscompile andtime thecalculations likelihoodat isall thatand the factorial calculation in the program below is therefore done at runtineruntime.
 
Not that it makes much difference in practice as the compiler which is written in C is so quick (at least with scripts of moderate length and on modern hardware) that the compile and runtime stages are indistinguishable to the user.
<langsyntaxhighlight ecmascriptlang="wren">var factorial10 = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2
 
System.print(factorial10)</langsyntaxhighlight>
 
{{out}}
Line 1,530 ⟶ 1,742:
=={{header|XLISP}}==
Macros can be used to evaluate expressions at compile time:
<langsyntaxhighlight lang="lisp">(defmacro f10-at-compile-time () (* 2 3 4 5 6 7 8 9 10))</langsyntaxhighlight>
If the expression is <i>quoted</i>, however, it is <i>not</i> evaluated—it is inserted 'as is', and will be evaluated at run time:
<langsyntaxhighlight lang="lisp">(defmacro f10-at-run-time () '(* 2 3 4 5 6 7 8 9 10))</langsyntaxhighlight>
To show what is going on, first start a REPL and define little functions that just invoke each macro:
<langsyntaxhighlight lang="lisp">[1] (defun test-f10-ct () (f10-at-compile-time))
 
TEST-F10-CT
[2] (defun test-f10-rt () (f10-at-run-time))
 
TEST-F10-RT</langsyntaxhighlight>
Then use <tt>DECOMPILE</tt> to examine the bytecode generated for each function. First, the one where the calculation was performed at compile time:
<pre>[3] (decompile test-f10-ct)
Line 1,575 ⟶ 1,787:
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="xpl0">code IntOut=11;
IntOut(0, 10*9*8*7*6*5*4*3*2);
</syntaxhighlight>
</lang>
Generates this 80386 assembly code:
<pre>
Line 1,586 ⟶ 1,798:
RET
</pre>
 
=={{header|Yabasic}}==
<syntaxhighlight lang="basic">factorial = 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10
print "10! = ", factorial // 3628800</syntaxhighlight>
 
=={{header|Z80 Assembly}}==
{{trans|8086 Assembly}}
Since 10! is bigger than 16 bits, I'll use 8! instead to demonstrate. Most assemblers only support the standard C operators for compile-time calculation, so we're going to need to multiply out the factorial manually.
<syntaxhighlight lang="z80">ld hl,8*7*6*5*4*3*2 ;8! equals 40,320 or 0x9D80
call Monitor ;unimplemented routine, displays the register contents to screen</syntaxhighlight>
{{out}}
<tt>0x9D80</tt>
 
=={{header|zkl}}==
zkl has two ways to do compile time calculations: a variant of C's macros and "parse time" calculations (since the compiler is written in zkl, the parser just recurses).
File foo.zkl:
<langsyntaxhighlight lang="zkl">const { [1..10].reduce('*).println(" parse time") }
 
#fcn fact(N) { [1..N].reduce('*).println(" tokenize time"); ""}
Line 1,596 ⟶ 1,820:
#tokenize fact(10)
 
println("compiled program running.");</langsyntaxhighlight>
Run the program: zkl foo:
{{out}}
Line 1,608 ⟶ 1,832:
=={{header|Zig}}==
Zig provides arbitrary CTFE with limitations in IO, memoization and forbidding closures for compilation efficiency.
<langsyntaxhighlight lang="zig">const std = @import("std");
fn factorial(n: u64) u64 {
var total: u64 = 1;
Line 1,621 ⟶ 1,845:
const res = comptime factorial(10); // arbitrary Compile Time Function Evaluation
std.debug.print("res: {d}", .{res}); // output only at runtime
}</langsyntaxhighlight>
Output:
<pre>3628800</pre>
9,479

edits