Language migration from Fortran to Python

Fortran to Python Migration Guide

Move decades-old Fortran numerical code to Python without breaking the math that runs on top of it.

Why teams move off Fortran

Fortran has not lost its numerical strengths, it has lost its ecosystem gravity. The reasons to migrate are practical, not ideological.

CI / CD
Containers
REST / events

The Fortran talent pool is shrinking

Fewer engineers train in Fortran each year while most graduates learn Python. Retaining Fortran maintainers gets harder the longer a codebase sits untouched.

HAND REWRITE
ON FORGE

Python's scientific ecosystem now rivals Fortran's numerical strengths

NumPy, SciPy, and pandas give Python the array operations, linear algebra, and visualization that were once Fortran's exclusive territory.

BEHAVIOR PRESERVED

Build
Test
Scan
Deploy
✓ Policy✓ Comply✓ SecuritySign

Easier integration with modern ML and data pipelines

ML frameworks and data orchestration tools are Python-first. Keeping simulation logic in Fortran makes it harder to plug into the rest of the stack.

Intent approved
Architecture approved
PRD approved

Better tooling across the board

Python has mature debuggers, package managers, and testing frameworks that are more approachable than toolchains built around legacy Fortran projects.

Cross-platform portability

Python runs unmodified across platforms. Fortran codebases often carry compiler-specific extensions and build flags accumulated over decades.

Before
With Forge
W1
W2
W3
W4
W5
W6

Faster onboarding for new engineers and researchers

New hires and researchers are far likelier to know Python already, which shortens ramp-up and reduces bus-factor risk around a few specialists.

See your ForgeScore before you commit

Every import is scored across eight engineering-health dimensions before a Work Order is planned, so you know what you are dealing with up front.

Every Fortran-to-Python project on Forge starts the same way: your codebase is imported, scored with ForgeScore, and reconstructed into an approved specification before a single line of Python is generated.

8

ForgeScore dimensions

Every stage

Approval gates

6

Pipeline stages

What actually changes under the hood

The shift is more than syntax. Paradigms, data access, and runtime assumptions all move, and each one needs an explicit mapping.

01

1-based vs 0-based array indexing

Fortran indexes arrays from 1, Python and NumPy from 0. Every loop bound and slice must be re-derived, not simply decremented by one.

02

Column-major vs row-major memory layout

Fortran stores arrays column-major; NumPy defaults to row-major. Porting requires order='F' or deliberate transposition, or results can be silently wrong.

03

Static typing and fixed-size arrays vs dynamic typing

Fortran sizes arrays at compile time, which the compiler uses for checking. Python needs explicit shape and dtype management via NumPy to keep those guarantees.

04

COMMON blocks and modules vs Python module state

Fortran 77 shares state through COMMON blocks. Python has no equivalent, so shared state is reorganized into module variables, config objects, or classes.

How the migration actually worksFrom import to verified output, every step is scored, specified, and tracked.
Import Fortran
ForgeScore assessment
Approved specification
Work orders
Verified & shipped
Works in your editor
01Import FortranYour existing Fortran codebase is ingested as-is, including legacy Fortran 77 and modern Fortran 90+ sources. No prior documentation needed.
Import Fortran
02ForgeScore assessmentScored across 8 engineering-health dimensions before you commit to anything, including flags for indexing-sensitive array logic and COMMON block usage.
ForgeScore assessment
03Approved specificationNumerical logic and business rules are reconstructed from source into a spec your team reviews, before any Python code is generated.
Approved specification
04Work ordersThe spec becomes Build, Migrate, and Decommission work orders, scoped and sequenced so array-layout and indexing changes are handled deliberately, not line by line.
Work orders
05Verified & shippedEach Migrate work order is checked against the original Fortran behavior, within defined numerical tolerance, before it ships.
Verified & shipped
06Works in your editorWork orders connect into Claude Code, Cursor, Windsurf, and other AI code editors over MCP, so the governed spec travels with you instead of staying in a separate dashboard.
Works in your editor

What Forge actually produces

Every Fortran import is scored across 8 engineering-health dimensions, then broken into Build, Migrate, and Decommission work orders. Here is what that looks like for an array-indexing finding.

ForgeScore finding

Data Weight

54

How data is modeled, moved, and owned. Moderate score: fixed-point COMP-3 fields carry implicit precision rules that need explicit typing once they leave COBOL.

Medium severity finding

Migration work order

Migrate: SCALE_ARRAY

Migrate

Re-express the array routine as vectorized NumPy with 0-based indexing and explicit memory order. Includes verification against the original Fortran output, within defined numerical tolerance, before this work order is marked complete.

Common challenges

Fortran-to-Python migrations fail less on syntax and more on numerical behavior that shifts silently.

HAND REWRITE
ON FORGE

Off-by-one errors from indexing conventions

The 1-based to 0-based switch is the most common source of subtle bugs. Loop bounds, boundary conditions, and slices all need re-deriving and testing.

NEWauth.tsapi/routes.ts
LEGACYlegacy/core.jsutils/parser.js

Row-major vs column-major layout

Unhandled memory order produces wrong results when interfacing with binary files or external libraries, and degrades cache performance even when the math is right.

Before
With Forge
W1
W2
W3
W4
W5
W6

Performance loss without vectorization

A loop-for-loop translation runs far slower than compiled Fortran. Matching performance means vectorizing hot loops with NumPy or compiling them with Numba or Cython.

COBOLfixed-point decimal
C#float?

Floating-point behavior differences

Compiler optimizations and evaluation order in the original build can produce results differing in the last few bits, even when both are correct IEEE 754 arithmetic.

Frequently asked questions

How long does a typical Fortran to Python migration take?

Will the Python version produce bit-identical results to the original Fortran?

How do you verify the migrated code preserves the original behavior?

Does migrating from Fortran to Python require downtime?

Will the Python version be as fast as the original Fortran?