> "I don't know what the language of the year 2000 will look like, but I know it will be called Fortran."
Prerequisites
- 1
- 10
- 16
- 32
Learning Objectives
- Describe the headline features Fortran 2023 added — conditional expressions, enumeration types, typeof/classof, degree-valued trig, and relaxed size limits — and say honestly which are usable in today's compilers.
- Explain, using the merge intrinsic as the contrast, what a conditional expression evaluates and why short-circuiting matters.
- Trace how a feature travels from an idea to the ISO standard through the J3 and WG5 committees, and name the roughly five-year revision cadence.
- Use the fortran-lang ecosystem — fpm, stdlib, the playground, and the interactive LFortran compiler — to try modern Fortran, including in a browser.
- Summarize, without overclaiming, where the language is heading: generics, better GPU support through do concurrent, and improving interoperability and tooling.
In This Chapter
Chapter 39: Fortran 2023 and Beyond — What's New and What's Coming
"I don't know what the language of the year 2000 will look like, but I know it will be called Fortran." — commonly attributed to Tony Hoare (C. A. R. Hoare)
Overview
For thirty-eight chapters we have taught Fortran as it is: a modern language, 2018 standard as our baseline, that you can install today and use to write fast, clean, parallel scientific code. This chapter does something different. It looks forward — at the standard that shipped in 2023, at the committee machinery that produced it and will produce the next one, and at the surprisingly energetic community that is rebuilding the language's tooling out in the open. If the running theme of this whole book has been that Fortran is not dead, this chapter is the proof of ongoing life: a language nobody was using would not be getting a new ISO standard, an interactive compiler, and a package manager all at once.
A word of honesty up front, because it governs everything here. Fortran 2023 — formally ISO/IEC 1539-1:2023 — is real and published. But a language standard is a document, not a compiler, and the distance between "the standard says you may write this" and "gfortran on your laptop will compile it today" can be years. Some 2023 features are already usable; several are not yet in the compiler you have; a few of the most exciting things in this chapter are proposed for the standard after 2023 and do not exist in any released compiler at all. We will keep those three categories rigorously separate. When this chapter says a feature is available, you should be able to compile it; when it says "coming," treat it as a preview, not a promise.
In this chapter, you will learn to:
- Name the headline additions of Fortran 2023 — conditional expressions, enumeration types,
typeofandclassof, degree-valued trigonometry, roomier source limits, and better C interoperability — and, for each, whether you can use it now or must wait for your compiler to catch up. - Explain what a conditional expression evaluates and why it is not merely nicer syntax for the
mergeintrinsic but a genuinely different (short-circuiting) operation. - Describe how Fortran evolves: the J3 and WG5 committees, the roughly five-year revision cadence, and the reason a fifty-year-old program still compiles under a brand-new standard.
- Reach for the fortran-lang ecosystem — fpm, stdlib, the browser playground, and the interactive LFortran compiler — to experiment with the language, including from a web browser with nothing installed.
- Talk honestly about where the language is going next: generics (the big one), better GPU support
through
do concurrent, and the steady maturing of open tooling.
Learning Paths
How to read this chapter by track. - 🔬 Scientist — §39.1 (the degree-trig and conditional-expression bits will tidy real code) and §39.3 (the playground and stdlib are immediately useful). Skim §39.2. - 📖 Standard — read straight through; §39.2 (the standards process) is the heart of the chapter for you, and §39.1 is your feature-by-feature tour. - 🔧 Legacy — §39.2 explains why your old code still compiles (backward compatibility is a committee value, not an accident), and §39.1's "supported where?" honesty applies double when you maintain code across many compilers. - ⚡ HPC — §39.4 is yours:
do concurrentwith reductions, GPU offload directions, and generics. Skim §39.1; read §39.3 for LFortran and Flang.
39.1 What Fortran 2023 Added
Every Fortran standard has a character. Fortran 90 was a revolution (free-form, arrays, modules). Fortran
2003 was almost as large (object orientation, C interoperability). Fortran 2008 gave us coarrays and
do concurrent. Against those, Fortran 2023 is a consolidation — a collection of useful, mostly small
refinements rather than a single sweeping change. That is not a criticism. A mature language should evolve
by careful addition, and a reader who has absorbed the previous thirty-eight chapters will find that
nothing here forces you to relearn anything. These are conveniences, safety improvements, and a few genuine
gap-fillers. Here are the ones worth your attention.
Conditional expressions
The headline syntactic addition is the conditional expression — a compact, inline way to choose between
two values based on a condition, right inside an expression, without an if block or a temporary variable.
- Definition (conditional expression). An expression of the form `( logical-condition ? value-if-true
- value-if-false )
that evaluates to one of two values depending on a scalar logical condition. The whole thing must be enclosed in parentheses. Crucially, **only the selected branch is evaluated** — the untaken value is never computed. Fortran 2023 also allows the same? :form as an *actual argument* in a procedure call (a "conditional argument"). This is Fortran's version of what C calls the ternary operator and what Python writes asa if cond else b`.
If you already program, you know this pattern. It replaces the common little dance of declaring a variable,
writing an if/else to set it, and using it once:
! The verbose way (works in every Fortran):
real(dp) :: larger
if (a > b) then
larger = a
else
larger = b
end if
Fortran already had a partial answer to this: the merge intrinsic, which you have met, chooses between two
values under a mask — merge(a, b, a > b) returns a where the mask is true and b where it is false.
So why add new syntax? Because merge and a conditional expression are not the same operation, and the
difference is the whole point.
💡 Intuition:
merge(a, b, mask)is an ordinary function call, and a function call evaluates all of its arguments before it runs. Somergecomputes bothaandb, then throws one away. A conditional expression( mask ? a : b )computes only the value it returns. When the discarded value is harmless, this is a wash. When it is expensive, or invalid, it matters enormously.
Here is the case that makes it concrete. Suppose you want a guarded division: use x/denom when denom is
nonzero, and fall back to zero otherwise.
! Looks safe, is not: merge evaluates BOTH arguments, so x/denom is
! computed even when denom == 0 (the very case you were guarding against).
y = merge( x/denom, 0.0_dp, denom /= 0.0_dp )
! Fortran 2023 — the conditional expression forms only the selected value,
! so x/denom is never computed when denom == 0. (Needs a 2023-capable
! compiler; see the honesty note below.)
y = ( denom /= 0.0_dp ? x/denom : 0.0_dp )
🐛 Find the Bug. A colleague writes
safe = merge(sqrt(v), 0.0_dp, v >= 0.0_dp)to "avoid taking the square root of a negative number." Why does this not do what they think, and what is the one-character family of changes (once their compiler supports 2023) that fixes it? Answer:mergestill evaluatessqrt(v)for negativev, raising a floating-point exception or returningNaNbeforemergeever chooses — the guard is useless. The conditional expression( v >= 0.0_dp ? sqrt(v) : 0.0_dp )evaluatessqrt(v)only whenv >= 0. Until then, the portable fix is an explicitif/else, which also short-circuits.🐍 Python Comparison: Python's
value = a if cond else bshort-circuits exactly the way Fortran 2023's conditional expression does — only the chosen side runs. If you have relied on that in Python to guard against errors (x/d if d else 0), you have relied on precisely the behaviormergelacks and the new conditional expression provides. The Fortran spelling just moves the condition to the front:( cond ? a : b ).⚠️ Common Pitfall — compiler support. As of this writing, conditional expressions are a new feature and support is landing unevenly across compilers. Do not assume the
? :form compiles on the gfortran you happen to have; older releases reject it outright. Everything you write with a conditional expression should have a portable fallback (anif/else, ormergewhen both branches are safe to evaluate) until you have confirmed your toolchain accepts it. This is the recurring discipline of the whole chapter: check, do not assume.
Enumeration types
The second addition fills a real gap. For decades, Fortran programmers have faked enumerations with named integer constants:
integer, parameter :: bc_dirichlet = 1, bc_neumann = 2, bc_periodic = 3
This works — you have seen it, and you will see it again in this chapter's project checkpoint — but it is
not type-safe. Nothing stops you from assigning bc_dirichlet to a variable expecting a color, comparing
a boundary-condition flag to a wavelength, or passing 47 where only 1, 2, or 3 make sense. The
values are just integers, and the compiler cannot help you.
Definition (enumeration type). A distinct data type whose values are a fixed, named set — its enumerators. A variable of an enumeration type may hold only one of those named values, and the compiler type-checks it, so mixing two unrelated enumerations, or assigning an arbitrary integer, is a compile-time error. Fortran 2023 introduces genuine enumeration types as a new kind of type, distinct from — and more type-safe than — the C-interoperable
enumthat Fortran 2003 already had.
Be careful here, because Fortran now has two enumeration-like facilities and they are different animals:
- Fortran 2003's
enum, bind(c)creates a set of named integer constants with a C-compatible kind. It exists for interoperability with Cenums. Its members are ordinary integers; it is not a distinct type and gives you no extra type safety. This one gfortran has supported for years:
fortran
enum, bind(c)
enumerator :: red = 1, green, blue ! green==2, blue==3 (integers)
end enum
- Fortran 2023's enumeration type is a true, distinct type. You declare the type and its enumerators, then declare variables of that type that can hold only those enumerators, and the compiler enforces it.
⚠️ Flagged — exact syntax and support. The precise spelling of a 2023 enumeration-type declaration is new enough, and compiler support thin enough, that this book will not hand you a snippet to copy as gospel. Conceptually you declare a named enumeration type with a list of enumerators and then variables of that type; consult your compiler's Fortran-2023 status page and the standard for the exact form before you depend on it. What matters pedagogically is the idea: a boundary-condition kind should be its own type whose only legal values are
dirichlet,neumann, andperiodic— not a bare integer that could silently be47. Until your compiler supports it, the portableinteger, parameteridiom (shown in this chapter'scode/example-02-boundary-enum.f90) is the honest stand-in, and it still compiles everywhere.
The payoff, once compilers catch up, is the same payoff modern Fortran has been delivering since Chapter 6's
intent and Chapter 8's module interfaces: the compiler catches your mistake before the program runs.
That is what a modern language does, and enumeration types are one more brick in the wall.
typeof and classof
The third addition is aimed at people who write library code — code that must work with a type it does not know in advance.
Definition (
typeof). A declaration type specifier,typeof(x), that declares an entity to have the same declared type and type parameters as an existing entityx, without you having to name that type explicitly. Its polymorphic companion,classof(x), declares an entity that is polymorphic over the declared type ofx(theclass(...)analogue). Both let you write code that adapts to whatever type it is given — a step toward the fuller generics facility discussed in §39.4.
The motivating problem is one you met in Chapter 10:
Fortran's OOP lets you be polymorphic over a class hierarchy, but if you want a temporary "of the same type
as this argument, whatever that turns out to be," you previously had to know the type's name. With typeof,
you can write, roughly, "give me a local variable of the same type as a," and the compiler fills in the
type. It is a small feature with an outsized role: it is one of the pieces the language needs on the road to
true generic programming.
⚠️ Flagged — support.
typeof/classofare, at the time of writing, not available in the gfortran most readers will have installed. Treat the description above as conceptual; verify against your compiler before use.
Trigonometry in degrees
Now a small feature that is actually usable today, and a pleasant one. Fortran 2023 standardizes the
degree-valued trigonometric intrinsics — sind, cosd, tand and their inverses asind, acosd,
atand, plus atan2d — which take and return angles in degrees instead of radians. If your data is in
degrees (latitudes, headings, phase angles, a hot-edge profile), you no longer sprinkle * pi / 180.0_dp
across your code and risk getting one of them wrong.
! Fortran 2023 degree-valued trig. Compile with a recent gfortran:
! gfortran -std=f2023 -Wall example-01-degrees-trig.f90 -o degrees
print '(a, f8.5)', 'sind(30) = ', sind(30.0_dp) ! -> 0.50000
print '(a, f8.5)', 'cosd(60) = ', cosd(60.0_dp) ! -> 0.50000
print '(a, f8.5)', 'tand(45) = ', tand(45.0_dp) ! -> 1.00000
$ gfortran -std=f2023 -Wall example-01-degrees-trig.f90 -o degrees && ./degrees
sind(30) = 0.50000
cosd(60) = 0.50000
tand(45) = 1.00000
⚡ Performance Note / accuracy. Beyond convenience,
sind(180.0_dp)can return exactly zero, whereassin(180.0_dp * pi / 180.0_dp)returns a tiny nonzero number becausepiis not representable and the multiply introduces rounding. Degree-based intrinsics can give cleaner results at the "nice" angles that show up constantly in geometry and boundary data. (The complete, compilable example, with the portablepi/180fallback beside it, iscode/example-01-degrees-trig.f90.)⚠️ Flagged — support. gfortran has offered
sind/cosd/tandas an extension for many releases, so this example is likely to compile even on a somewhat older gfortran — but that history is exactly why you should pin it down: compile with-std=f2023to request the standardized behavior, and if your compiler rejects the names, use the explicitpi/180conversion. Fortran 2023 also adds "half-revolution" variants (sinpi,cospi,tanpi, taking arguments in units of $\pi$ radians); their availability is newer, so verify before relying on them.
Roomier source: longer lines and names
Fortran 2023 relaxes several venerable size limits that occasionally pinched. Free-form source lines, long capped at 132 characters, may now be far longer — reported as up to 10,000 characters — and the limits on statement length and continuation were raised in step, so a long, generated, or deeply descriptive line no longer forces awkward continuations. Related limits (such as how long an identifier may be) were also loosened. The practical effect is mundane and welcome: machine-generated Fortran and richly named scientific code fit more comfortably. None of this changes how you write Fortran; it just removes old friction.
⚠️ Flagged — exact figures. The specific new maxima above are stated as reported and should be confirmed against the standard if a hard number matters to you (for instance, if you are writing a code generator). The direction — bigger limits — is certain; the exact ceilings are the kind of detail this book will not assert without your verifying it.
Better C interoperability
Finally, Fortran 2023 continues the long project — begun in Fortran 2003 and extended in every standard
since — of making the boundary with C smoother. The additions include better handling of C character
strings (helper procedures to convert between Fortran and C string conventions) and refinements to how
interoperable types and pointers behave, building on the iso_c_binding foundation you met in
Chapter 14. These are
specialist conveniences: if you glue Fortran to C for a living, they remove sharp edges; if you do not, you
can note that the bridge keeps getting sturdier and move on. As with everything in this section, confirm
which specific interop helpers your compiler has implemented before you build on them.
The honest scorecard
Here is the section in one table — and, because this chapter's whole discipline is honesty about support, a column for when you can actually use each feature. Treat the support column as a snapshot that will improve over time, not a fixed fact.
| Fortran 2023 feature | What it gives you | Usable today? |
|---|---|---|
Conditional expression ( c ? a : b ) |
Inline choice that evaluates only the taken branch | Landing unevenly; check your compiler, keep a fallback |
| Enumeration type | A distinct, type-checked set of named values | Thin support; use integer, parameter for now |
typeof / classof |
"Same type as x" without naming the type |
Generally not yet in common gfortran; conceptual for now |
Degree trig sind/cosd/tand |
Angles in degrees, cleaner nice-angle results | Yes on recent gfortran (long an extension); use -std=f2023 |
| Longer lines / names | Relaxed source size limits | Increasingly; harmless if unused |
| Better C interop | Smoother Fortran↔C strings and types | Partial; verify the specific helper |
🔄 Check Your Understanding. 1. Why is
merge(sqrt(v), 0.0_dp, v >= 0.0_dp)not a safe way to guard a square root? 2. What is the one structural difference between a Fortran 2003enum, bind(c)and a Fortran 2023 enumeration type? 3. You compile a program usingsindand it fails on a colleague's older compiler. Name two fixes.
Answers
1.mergeis a function, so it evaluates both value arguments —sqrt(v)runs even for negativev, producing aNaNor an exception beforemergechooses. It does not short-circuit. 2. The 2003enum, bind(c)produces named integer constants (no new type, no extra type safety, for C interop); the 2023 enumeration type is a distinct type whose variables the compiler checks. 3. (a) Compile with-std=f2023(or your compiler's flag) if it supports the standardized names; (b) replacesind(x)with the portablesin(x * pi / 180.0_dp).
39.2 How the Language Evolves: J3, WG5, and the Standards Process
Where does a feature like the conditional expression actually come from? Not from a company, and not from one designer. Fortran is an ISO standard, and it changes through a deliberate, public, committee-driven process that is worth understanding — because that process is the reason your fifty-year-old code still compiles and the reason new features arrive at all.
Definition (the standards process; J3 and WG5). Fortran is defined by an international standard maintained by a working group of the International Organization for Standardization: WG5 (formally ISO/IEC JTC1/SC22/WG5), which sets the overall direction, scope, and schedule of each revision. The detailed technical work — drafting exact wording, resolving the thousands of interactions between features — is done largely by J3, the US Fortran committee (an INCITS technical committee, historically called ANSI X3J3 and still universally known as "J3"). Anyone may propose a feature; proposals are written up as papers, discussed and voted on at committee meetings, and folded into a working draft that eventually becomes the published standard.
The mechanics, briefly, because you may one day want to influence them:
- An idea becomes a paper. Someone — a committee member, a compiler writer, a working scientist with a pain point — writes a short proposal describing a feature, its motivation, and proposed wording. Today much of this happens in the open: proposals and discussion live on the committee's public repositories and on the community's discussion forum, so you do not have to be an insider to float an idea.
- The committee debates it. J3 meets and processes papers, weighing usefulness against cost: implementation burden for compiler writers, interaction with existing features, and — always — backward compatibility. Many proposals are rejected or reshaped many times before they survive.
- It enters a working draft, then a formal draft. Accepted features accumulate in a working document. WG5 steers the revision through the ISO milestones — a Committee Draft, then a Draft International Standard put to national-body ballot — until it is published as the new edition of ISO/IEC 1539-1.
- Compilers implement it — on their own schedule. Publication is the start of availability, not the end. Each compiler team implements features when they can, which is why this chapter must talk about support rather than assume it.
The cadence is roughly one revision every five years. You saw the lineage in Chapter 1; here is the modern tail of it, the part this book lives in:
2003 Fortran 2003 OOP, C interoperability, procedure pointers
2010 Fortran 2008 coarrays, submodules, DO CONCURRENT
2018 Fortran 2018 more parallelism, better C interop <- our baseline
2023 Fortran 2023 conditional expressions, enumeration types, typeof
20xx the next one generics, and more (in development — see §39.4)
🚪 Threshold Concept. The same institution that lets you add a conditional expression in 2023 is the institution that guarantees your 1977 code still runs. Standardization is not bureaucracy getting in the way of progress — it is the mechanism of safe progress. Because a committee of competing vendors and users must agree on exactly what every construct means, the language can grow new features without shattering the trillions of lines of validated science already written in it. Evolution without breakage is the deal, and it is why a national lab is willing to bet a flagship code on Fortran for another thirty years. Once you see the standard as a contract rather than a rulebook, the conservatism of the process reads as a feature, not a flaw.
That conservatism is concrete. Fortran almost never removes anything. Features that have aged badly are
marked obsolescent (a formal warning that they may someday go), and only rarely are any actually
deleted; the fixed-form source and COMMON blocks you met in Part IV
are decades past their prime and still in the standard, because somewhere a working, validated program
depends on them. This is the same ethic we adopted in Part IV — legacy code is not a burden — expressed
at the level of the language's own governance.
📜 From History. The 1966 standard, mentioned back in Chapter 1, made FORTRAN the first programming language ever standardized by a national body — the act that made "does my program mean the same thing on your machine?" a question with a definite answer. The committee that did it was designated X3J3; through a reorganization of the US standards bodies the "X3" became "INCITS," and the group is still called J3 today. When you read that a feature was "voted in at a J3 meeting," you are watching the direct institutional descendant of the 1966 effort still doing the same job, nearly sixty years on. Standards are unglamorous, and they are the reason the science encoded in old Fortran has not evaporated.
The practical upshot for you: Fortran's future is not decided behind a closed door. If a feature would make your scientific work better, the path from "I wish Fortran could…" to "the standard now says it can" runs through public proposals and a committee that reads them. It is slow, but it is open — and a language whose users can shape its future is, once again, the opposite of dead.
🔄 Check Your Understanding. 1. What is the difference in role between WG5 and J3? 2. Why does the publication of Fortran 2023 not mean you can immediately use all its features? 3. What does it mean for a feature to be marked "obsolescent," and why does the committee prefer that to deletion?
Answers
1. WG5 (the ISO working group) sets overall direction, scope, and schedule; J3 (the US committee) does the detailed technical drafting and processes most feature papers. 2. A standard is a document; each compiler implements it on its own timeline, so availability lags publication — often by years, feature by feature. 3. "Obsolescent" is a formal warning that a feature is discouraged and may eventually be removed; the committee prefers it to outright deletion to avoid breaking the enormous body of working legacy code — backward compatibility is a core value.
39.3 The fortran-lang Renaissance
A standard is only half of a living language. The other half is tooling — compilers, package managers, libraries, editors, places to experiment — and for a long stretch Fortran's tooling was exactly the part that felt dated. That has changed, fast, and mostly since around 2020, driven by a community organized under the banner of fortran-lang.org. You met these tools by name in Chapter 16; here we place them in their proper context, as evidence of a language being actively rebuilt.
fpm, the Fortran Package Manager. The single most consequential thing to happen to everyday Fortran
ergonomics in decades. As Chapter 16 showed, fpm build and fpm run compile a project — working out
module dependency order automatically, the very bookkeeping you did by hand in
Chapter 8 — and a few lines of
fpm.toml pull in a dependency straight from a git repository. A language with a real package manager is a
language you can build an ecosystem on, and that is precisely what is happening.
stdlib, the community standard library. Fortran's intrinsics are excellent at arrays and arithmetic and silent about almost everything else — statistics, sorting, string helpers, special functions, common file formats. For decades every group reinvented these privately. stdlib is the collective answer: a community-built library (declared as an fpm dependency, not baked into the compiler) that supplies the "batteries" the language never included. Some of what stdlib proves out even feeds back into the standard — a library and a language co-evolving.
The playground. There is now a Fortran Playground in your web browser (hosted by fortran-lang): type Fortran into a page, press run, see the output, with nothing installed. For teaching, for settling a "what does this print?" argument, for trying a snippet from this book on a machine where you cannot install a compiler, it is a genuine gift — and it is powered by the last and most surprising member of this list.
Definition (LFortran). A modern, LLVM-based, open-source Fortran compiler with an unusual capability: besides compiling whole programs ahead of time, it can run Fortran interactively — one statement at a time, in a read-evaluate-print loop or a Jupyter notebook — the way Python or Julia have always worked but Fortran never could. It is what powers the browser playground. LFortran is still in active development: it can handle a growing subset of modern Fortran but is not yet a drop-in replacement for an established compiler on a large production code. Today it is best used to explore and teach; build your real code with a mature compiler.
Sit with how strange "interactive Fortran" is. For sixty-five years, using Fortran meant the edit–compile–
link–run cycle you learned in Chapter 2:
write a whole program, compile it, run the executable. The idea of typing print *, sind(30.0) at a prompt
and seeing 0.50000 appear immediately — no program, no compile step you think about — simply did not exist
for this language. LFortran makes it exist.
🐍 Python Comparison: The thing that makes Python feel approachable to beginners is largely its REPL and its notebooks — you type one line, you see one result, you learn by immediate feedback. LFortran is bringing that same tight loop to Fortran. This does not make Fortran a scripting language, and it should not; the compile-and-run model is why Fortran is fast. But an interactive front end for exploration, sitting in front of the same fast compiler for production, is the best of both — one more instance of the book's theme that Fortran and Python are better together, now borrowing Python's best teaching tool.
🔗 Connection. There is a second modern open compiler worth knowing: LLVM Flang (sometimes called
flang-new), the Fortran front end in the LLVM project, aimed at being a production-grade compiler alongside gfortran and the vendor compilers. Between gfortran (mature, GCC), LLVM Flang (maturing, LLVM), the vendor compilers (Intelifx, NVIDIAnvfortran), and LFortran (interactive, LLVM), Fortran in the mid-2020s has more actively developed compilers than it has had in a generation. Recall the honest test from Chapter 16: dead languages do not sprout new compilers.🧩 Try It Yourself. Open the Fortran Playground in your browser (search "fortran-lang playground") and paste in this chapter's degree-trig snippet, or the smallest program from any earlier chapter. Watch it compile and run with nothing installed on your machine. Then, if you can, install LFortran and try the same lines interactively at its prompt. You will have run Fortran two ways this language could not offer at all a few years ago — the clearest possible demonstration that the ecosystem, not just the standard, is alive. (Because these tools evolve quickly, treat any specific command or URL as something to confirm from the current fortran-lang site rather than memorize.)
Put the pieces together — a package manager, a standard library, a browser playground, an interactive compiler, multiple new production compilers — and the pattern is unmistakable. This is not the tooling of a language being maintained out of obligation. It is the tooling of a language people are choosing to invest in, building the conveniences that C and Python programmers have long taken for granted. Modern Fortran is a modern language, and in the 2020s that is finally becoming true of its tools as well as its syntax.
39.4 Where Fortran Is Heading
Now we cross the line from "shipped" to "coming," and the honesty rules tighten accordingly. Nothing in this section is something you can compile today and rely on across compilers. These are directions — features in active development, proposals with momentum, trends in the ecosystem. Read them as a well-informed forecast, and flag every one in your own mind as "not yet."
Generics — the big one. The largest known gap in the Fortran language is the absence of generics: the
ability to write an algorithm or a data structure once, parameterized over the type it operates on, and have
the compiler instantiate a type-safe version for each type you use. In most modern languages this is
routine — C++ templates, Java/Rust generics. In Fortran today, if you want a "stack of real(dp)" and a
"stack of integer," you either duplicate the code, resort to unlimited-polymorphic class(*) containers
that sacrifice type safety and speed, or reach for a preprocessor. The committee has been developing a
generics (templates) facility for years, and it is the headline feature targeted for the next revision
of the standard — the one informally called "Fortran 202Y" until it is finished and named.
Definition (generics). A planned facility for parametric polymorphism: writing a procedure or type once, parameterized over one or more types (and kinds), so the compiler can generate a specialized, type-checked version for each concrete type it is used with — no code duplication, no runtime dispatch, full compile-time safety. Fortran does not have this yet; it is in development for a future standard. The
typeof/classofof §39.1 are early pieces of the same puzzle.🔗 Connection. Generics are the natural complement to the object orientation of Chapter 10. OOP gives you polymorphism over a class hierarchy at run time (with the dispatch cost you learned to keep out of hot loops); generics give you polymorphism over any type at compile time, with no dispatch cost at all. Together they would let a scientific library be both flexible and fast — a genuinely important addition for the numerical code this book is about. But: not yet. Watch the committee, not your compiler, for this one.
Better GPU support, through the standard itself. You spent Chapter 35
offloading work to a GPU with OpenACC and CUDA Fortran — vendor-specific directives and extensions. The
strategic direction of the standard is to make ordinary Fortran offload to accelerators without any of
that, and the vehicle is do concurrent, the parallel loop from
Chapter 29. Some compilers (notably
NVIDIA's nvfortran) already compile a do concurrent loop to run on a GPU. Fortran 2023 pushes this along
by giving do concurrent a reduce locality specifier, so a parallel reduction — summing an array,
finding a maximum — can be expressed in pure standard Fortran:
! Fortran 2023: a reduction expressed in standard Fortran, no directives.
! (reduce locality is a 2023 addition; confirm your compiler supports it.)
total = 0.0_dp
do concurrent (i = 1:n) reduce(+:total)
total = total + a(i)
end do
⚡ Performance Note. The promise here is portable performance: one loop, written once in standard Fortran, that a capable compiler can run vectorized on a CPU or offloaded to a GPU, with no vendor-specific directive to maintain. That promise is not fully delivered — compiler support for GPU offload of
do concurrent, and for thereducespecifier, is uneven and evolving — but the direction is clear and it is the direction HPC Fortran is betting on. Recall the theme: performance is not accidental. The committee is deliberately routing high performance through the standard so you do not have to leave portable Fortran to get it.
Coarrays keep maturing. The native parallelism of Chapter 32
is still catching up in implementations — you saw that teams, though standardized, are only weakly
supported by gfortran today. Part of "where Fortran is heading" is simply the compilers finishing the job on
features the standard already describes: full teams, the full set of collectives, better performance. A
standardized feature is a promise; the coming years are partly about compilers keeping it.
Interop and tooling keep improving. Expect the C boundary to keep smoothing, the LLVM Flang and LFortran compilers to mature toward production use, stdlib to grow, and editor support through the language server to get better. None of this is glamorous, and all of it compounds: each increment makes Fortran a little more pleasant and a little more capable, year over year.
⚠️ Common Pitfall — reading the future honestly. It is tempting, in a chapter like this, to sell the roadmap as if it were done. Resist it, in your own thinking and when you describe Fortran to others. "Fortran will have generics and seamless GPU offload" is a forecast; "Fortran 2023 added conditional expressions and degree trig" is a fact. Keep the two apart. The credibility you build by saying "this part is proposed, not shipped" is worth more than the excitement you would borrow by blurring them — and it is the same discipline of honest claims that this whole book has practiced about benchmarks and citations.
Where is Fortran heading, then, in one sentence? Toward being a language that keeps its historic speed and its irreplaceable base of validated code, while steadily acquiring the type safety, the generality, the portable parallelism, and the tooling of a thoroughly modern language — slowly, publicly, and without breaking what already works. That is not the trajectory of a dead language. It is the trajectory of an old, essential one that has decided to keep growing.
Project Checkpoint
Thirty-eight chapters ago you chose a problem; over the book you built it into a modular, validated, optimized, parallel heat-equation solver, and in the Chapter 38 capstone you presented it as a paper. This chapter's checkpoint is deliberately light and explicitly optional: refresh one small piece of the solver with a Fortran 2023 feature, and try it in a place the language could not run a few years ago.
Recall the initial condition. Our square plate is held hot along one edge. Until now you have set that edge
to a uniform temperature. Let us make it a smooth half-sine bump instead — zero at the two corners, peak
in the middle — which is both physically reasonable (a localized heat source) and a natural fit for the new
degree-valued trig. Sweeping an angle from $0°$ to $180°$ across the edge and taking sind gives exactly
that shape:
! project-checkpoint.f90 (excerpt): a Fortran 2023 touch-up of the hot edge.
! Uses the degree intrinsic SIND -- no manual pi/180. OPTIONAL; needs a recent
! gfortran (-std=f2023). The portable fallback is one comment line below.
integer, parameter :: nx = 5
real(dp), parameter :: t_hot = 100.0_dp
real(dp) :: hot_edge(nx)
integer :: i
do i = 1, nx
! angle runs 0 -> 180 degrees across the edge; sind peaks (=1) at the centre
hot_edge(i) = t_hot * sind( 180.0_dp * real(i - 1, dp) / real(nx - 1, dp) )
! portable fallback (compiles anywhere):
! hot_edge(i) = t_hot * sin( 3.14159265358979_dp * real(i-1,dp)/real(nx-1,dp) )
end do
For nx = 5 the angles are $0°, 45°, 90°, 135°, 180°$, so by hand the edge becomes
[0.000, 70.711, 100.000, 70.711, 0.000] — symmetric, peaking at the centre cell, exactly the bump we
wanted. The full compilable program (which prints this profile) is code/project-checkpoint.f90, with its
hand-computed expected output.
You have two other equally valid ways to "refresh a snippet," if sind is not what your compiler supports:
- A conditional expression in the boundary logic — e.g.
t = ( on_hot_edge ? t_hot : t_cold )in place of anif/else— once your compiler accepts the? :form. - An enumeration type for the boundary-condition kind, replacing the
integer, parameter :: bc_dirichlet = 1, …idiom (seecode/example-02-boundary-enum.f90) with a type-checked set — once your compiler supports enumeration types.
The "try it somewhere new" half of the checkpoint: paste the hot-edge loop into the Fortran Playground
in your browser and run it, or run it interactively in LFortran. Confirm you see the half-sine profile
appear. This is the checkpoint's real point — not the physics, which you finished at the capstone, but the
experience of running your own solver's code through the new ecosystem. Note in your project's README.md
that this refresh is optional and 2023-dependent, and keep the portable version as the default so the solver
still builds for everyone. In Chapter 40 that same solver
becomes a portfolio piece — evidence, to an employer, of exactly the modern Fortran this chapter has been
describing.
Summary
Fortran 2023 is a real, published standard (ISO/IEC 1539-1:2023) that refines rather than reinvents, and the language around it — process, tooling, roadmap — is visibly alive.
| Topic | The short version |
|---|---|
| Conditional expression | ( cond ? a : b ); evaluates only the taken branch, unlike merge, which evaluates both. Support is landing unevenly — keep a fallback. |
| Enumeration type | A distinct, type-checked set of named values; different from (and safer than) F2003's enum, bind(c). Thin support; integer, parameter for now. |
typeof / classof |
"Same type as x" without naming it; a step toward generics. Mostly not yet available. |
| Degree trig | sind/cosd/tand (and inverses) take degrees; cleaner nice-angle results. Usable today on recent gfortran with -std=f2023. |
| Roomier source | Longer lines (reported up to 10,000 chars), longer names/statements. Harmless; exact figures worth verifying. |
| Standards process | WG5 (ISO) steers; J3 (US committee) drafts; ~5-year cadence; near-total backward compatibility — evolution without breakage. |
| fortran-lang | fpm (packages), stdlib (batteries), the playground (browser), LFortran (interactive!), LLVM Flang — a rebuilt ecosystem since ~2020. |
| Coming | Generics (headline of the next revision), GPU offload via do concurrent (with 2023's reduce), maturing interop and tooling — proposed, not shipped. |
The two things to remember. First: a conditional expression is not sugar for merge — it
short-circuits, evaluating only the branch it returns, which is what lets it guard against an invalid or
expensive computation that merge cannot. Second, and larger: Fortran evolves through an open, standardized
process whose defining trade is backward compatibility for careful, public growth — the same machinery
keeps your legacy code compiling and delivers new features, which is exactly why the language is neither
frozen nor dead. And always: separate what shipped (2023 facts) from what is coming (proposals), in your
code and in your claims.
Spaced Review
Revisiting Chapter 10 (Object-Oriented Fortran) and Chapter 32 (Coarrays) — the two features this chapter showed are still improving. Answer before checking.
-
In Chapter 10 you learned to default to
typeand opt intoclassonly where needed. What is the run-time cost ofclassthat makes the book say "keepclassout of the hot loop," and how does the generics facility of §39.4 offer a different way to be flexible without paying it?
Answer
A `class` (polymorphic) variable is dispatched at run time — the compiler cannot inline or vectorize through the dispatch, so in a tight per-cell loop it blocks the optimizer. Generics (compile-time parametric polymorphism) would let you write one flexible algorithm the compiler specializes per type *at compile time*, with no dispatch and full optimization — flexibility without the run-time cost. -
A Chapter 10 abstract type declares
procedure(iface), deferred :: solve. What doesdeferredguarantee, and how is that compile-time contract similar in spirit to what an enumeration type (§39.1) does for values?
Answer
`deferred` guarantees, at compile time, that every concrete type extending the abstract type provides a `solve` implementation matching the interface — a contract the compiler enforces. An enumeration type is the same idea for data: the compiler enforces that a variable holds only one of a fixed, named set of values. Both move errors from run time to compile time. -
In Chapter 32, what does the coindexed reference
a[q]mean, and why must a read ofa[q]be ordered against writes with something likesync all?
Answer
`a[q]` is image $q$'s copy of the coarray `a` (a "get" when read, a "put" when written), possibly a network message. Without synchronization, a read may race with a remote write — the program is undefined; `sync all` (a barrier) orders a write before it against a read after it. -
Chapter 32 noted that
teamsare standardized but only weakly supported by gfortran. Which distinction from this chapter (§39.1–39.4) does that illustrate, and why does it matter when you plan a parallel code?
Answer
The distinction between *what the standard specifies* and *what your compiler implements* — availability lags publication. It matters because you cannot assume a standardized parallel feature is usable everywhere; you must check each target compiler and keep a fallback, exactly as with the 2023 features in this chapter. -
Fortran 2023 gave
do concurrentareducespecifier (§39.4). Recallingco_sumfrom Chapter 32, what do the two have in common conceptually?
Answer
Both express a *reduction* — combining many values into one (a sum, a max) across parallel work — as a single standard-language construct rather than a hand-written loop with explicit synchronization. `co_sum` reduces across coarray images; `do concurrent … reduce(+:s)` reduces across the iterations of a parallel loop (targeting CPU vectorization or GPU offload).
What's Next
You now know where the language has been, where it is, and where it is going. One chapter remains, and it is about you. Chapter 40 asks the practical question that the whole book has been quietly building toward: given that you can now write modern, fast, parallel Fortran — and given that, as this chapter showed, the language is alive and evolving — where do you take that skill? Who employs Fortran programmers, what do they build, why are there more of those jobs than people to fill them, and how do you turn the solver you built across these forty chapters into evidence an employer can see? Let's talk about the career.