Pascal’s triangle — also known as Khayyam’s triangle after the Persian mathematician and poet Omar Khayyam — arranges the binomial coefficients
| $$\binom{n}{k} = \frac{n!}{k!\,(n-k)!}$$ | (1) |
into a triangular grid. Each interior entry is the sum of the two entries above it. It is a lovely little object, and it turns out we can build the whole thing at compile time in modern Fortran, so that the running program does nothing but print a table of literals.
Here is the complete program:
! pascal.f90 -- prints Pascal's triangle
implicit none
integer, parameter :: nmax = 8
character(len=*), parameter :: fmt = '(9(I6,:,1X))' ! 9 = nmax + 1
integer, parameter :: pascal(0:nmax, 0:nmax) = reshape( &
[([( product([(i, integer :: i = n-k+1, n)]) &
/ product([(i, integer :: i = 1, k)]), &
integer :: k = 0, nmax)], integer :: n = 0, nmax)], [nmax+1, nmax+1])
write(*,fmt) pascal
endCompiling and running it with flang 22.1.8:
$ flang -pedantic pascal.f90 && ./a.out
1 0 0 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0
1 2 1 0 0 0 0 0 0
1 3 3 1 0 0 0 0 0
1 4 6 4 1 0 0 0 0
1 5 10 10 5 1 0 0 0
1 6 15 20 15 6 1 0 0
1 7 21 35 35 21 7 1 0
1 8 28 56 70 56 28 8 1How it works
The key observation is that pascal is a parameter — a named constant. Its
initializer must therefore be a constant expression, which means the compiler
evaluates every entry while it is compiling. At run time there is no arithmetic
left to do; the executable simply prints nine rows of pre-computed integers.
Don’t take my word for it — see for yourself on Compiler Explorer. The assembly contains no loops and no multiplications, just the finished table sitting in the data section as 81 integer literals (row by row, exactly as printed):
_QQroX9x9xi4X0:
.long 1
.long 0
.long 0
...
.long 28
.long 8
.long 1The initializer itself is just equation (1) in disguise: the first product
multiplies the integers from n-k+1 up to n, the second gives the factorial
of k, and their integer quotient is the binomial coefficient — the division
is always exact. Two edge cases fall out for free. For k = 0 both ranges are
empty, and the empty product is 1 — exactly the value we want. And for
k > n the first range runs through zero, so the numerator vanishes — those
are the zeros filling the upper half of the table. Finally, with k as the
innermost implied-do index the flat list comes out one triangle row after
another, which is precisely the storage order in which write prints the
reshaped array.
Why Fortran 2018?
The youngest ingredient is declaring the implied-do index inside the array
constructor — the integer :: i = ... and friends above. Fortran 2008
allowed this for do concurrent and forall; Fortran 2018 extended it to
array constructors and data statements (§5.18 of John Reid’s The New
Features of Fortran
2018).
As Steve Lionel explains on Fortran
Discourse,
the index is a construct-scope integer regardless — the real novelty is
stating its kind in place, so no integer :: i, k, n declarations clutter the
surrounding scope. On paper the feature is from 2018; in practice the state of
affairs is rather sad. Of the compilers I tried, gfortran 16.1, lfortran 0.59,
nvfortran 26.5, and NAG 7.2 all reject the program, and ifx 2025.3 compiles it
but prints a wrong table — leaving flang as the only compiler I know of that
gets it right.
A note on the format
The edit descriptor '(9(I6,:,1X))' prints nmax + 1 integers per line in
six-character fields, separated by a space; the colon (:) stops the format
once the data list is exhausted. The repeat count 9 is the one thing that
does not follow nmax automatically — change one and you must touch the
other, as there is no convenient way to splice an integer into a character
constant expression.
Further reading
Compile-time evaluation is still young territory in Fortran. A few more explorations of what is possible today:
- Some adventures with compile time evaluation, Mohd Furquan, FortranCon 2021
- Computing at compile time, Fortran Discourse, March 2022
- Compile Time Computing, Intel Fortran Compiler Forum, April 2024
And if you enjoy the triangle itself, it stars in one of my favourite Veritasium videos, The Discovery That Transformed Pi — highly recommended.