Program Structure
Hello, World
program Hello;
begin
writeln('Hello, World!');
end. program hello
implicit none
print *, "Hello, World!"
end program hello Both languages wrap the whole program in a single named block: Pascal's
program Name; begin ... end. and Fortran's program name ... end program name. Fortran additionally requires implicit none as the very first statement in idiomatic modern code — without it, Fortran silently infers a variable's type from its first letter (a historical quirk Pascal never had, since Pascal has always required every variable to be declared).Comments
program Comments;
var
total: Integer; { This is a trailing comment }
begin
{ This is a full-line comment }
total := 10;
writeln(total);
end. program comments_demo
implicit none
! This is a full-line comment
integer :: total ! This is a trailing comment
total = 10
print *, total
end program comments_demo Pascal comments use curly braces
{ ... } (or (* ... *)); Fortran comments start with ! and run to the end of the line. Both languages' comment styles are considerably more modern than their 1950s/1970s-era predecessors' fixed-column punch-card comment conventions.Data Types
Integer and Real — nearly identical vocabulary
program TypesDemo;
var
count: Integer;
price: Real;
begin
count := 42;
price := 19.99;
writeln(count);
writeln(price:0:2);
end. program types_demo
implicit none
integer :: count
real :: price
count = 42
price = 19.99
print *, count
print *, price
end program types_demo Both languages use nearly the same names for their basic numeric types — Pascal's
Integer/Real and Fortran's integer/real — a genuinely close vocabulary match, unlike most other language pairs on this site.implicit none: Fortran opts in to what Pascal always had
program AlwaysStrict;
var
total: Integer;
begin
{ Pascal has never had implicit typing at all — every variable
must always be declared before use, with no pragma needed to
enforce it: }
total := 10;
writeln(total);
end. program strict_demo
implicit none
! Without "implicit none", a variable starting with I-N would
! default to INTEGER and everything else to REAL, with no
! declaration required at all — a historical Fortran quirk
! Pascal has never had:
integer :: total
total = 10
print *, total
end program strict_demo Fortran's
implicit none statement opts a program IN to mandatory variable declarations — without it, an undeclared variable's type is inferred from its first letter (I through N default to integer, everything else to real), a historical carryover from Fortran's earliest versions. Pascal has never had implicit typing at all; every variable has always required an explicit declaration, with no pragma needed to enforce what is simply the only way Pascal works.Variables & Constants
const versus the PARAMETER attribute
program ConstDemo;
const
Pi = 3.14159265358979;
var
radius, area: Real;
begin
radius := 5.0;
area := Pi * radius * radius;
writeln(area:0:2);
end. program parameter_demo
implicit none
real, parameter :: pi = 3.14159265358979
real :: radius, area
radius = 5.0
area = pi * radius * radius
print *, area
end program parameter_demo Pascal's
const block declares compile-time constants separately, before var. Fortran attaches the parameter attribute directly to a variable declaration (real, parameter :: pi = ...), folding the "this never changes" property into the type declaration itself rather than a separate section.Arithmetic
Arithmetic operators — a direct match
program ArithmeticDemo;
var
balance: Integer;
begin
balance := 100;
balance := balance + 50;
balance := balance - 20;
writeln(balance);
end. program arithmetic_demo
implicit none
integer :: balance
balance = 100
balance = balance + 50
balance = balance - 20
print *, balance
end program arithmetic_demo Both languages use the same ordinary infix arithmetic operators. The only visible difference is the assignment operator itself: Pascal's
:= versus Fortran's bare = — Fortran has no separate equality-test symbol conflict to avoid, since == is reserved for logical comparison inside conditions instead.Integer division: div/mod versus / and mod
program DivModDemo;
var
quotient, remainder: Integer;
begin
quotient := 17 div 5;
remainder := 17 mod 5;
writeln(quotient, ' ', remainder);
end. program div_mod_demo
implicit none
integer :: quotient, remainder
quotient = 17 / 5
remainder = mod(17, 5)
print *, quotient, remainder
end program div_mod_demo Pascal uses the dedicated keyword
div for integer division and mod as an infix operator. Fortran overloads the ordinary / operator for integer division when both operands are integers (truncating automatically), and spells remainder as the function call mod(a, b) rather than an infix operator.Dynamic Strings vs. Fixed-Width Fields
String concatenation: + versus //
program ConcatDemo;
var
firstName, lastName, fullName: string;
begin
firstName := 'Alice';
lastName := 'Smith';
fullName := firstName + ' ' + lastName;
writeln(fullName);
end. program concat_demo
implicit none
character(len=20) :: first_name, last_name
character(len=41) :: full_name
first_name = "Alice"
last_name = "Smith"
full_name = trim(first_name) // " " // trim(last_name)
print *, trim(full_name)
end program concat_demo Pascal reuses the ordinary
+ arithmetic operator for string concatenation — the compiler infers its meaning from the operand types. Fortran uses the dedicated // operator instead, and needs an explicit trim() call to strip trailing padding first, since a Fortran character(len=n) field is always exactly its declared width.A role reversal: Pascal is the more dynamic string type here
program DynamicStringDemo;
var
greeting: string;
begin
greeting := 'Hello';
writeln('Length: ', Length(greeting));
greeting := greeting + ', World! And more!';
writeln('New length: ', Length(greeting));
end. program fixed_width_demo
implicit none
character(len=20) :: greeting
greeting = "Hello"
print *, "Length:", len_trim(greeting)
! Growing "greeting" beyond its declared len=20 would silently
! TRUNCATE the extra characters — there is no dynamic resizing:
greeting = greeting(1:len_trim(greeting)) // ", World! And more!"
print *, "New length:", len_trim(greeting)
end program fixed_width_demo This is an unusual role reversal for a Pascal programmer: Pascal's
string is a dynamically-sized, managed type that grows and shrinks automatically, needing no declared maximum size at all. Fortran's character(len=n) is a genuinely fixed-width field — n is chosen once at declaration, and any content beyond it is silently TRUNCATED rather than growing the field, closer to how a C string buffer with a hardcoded size behaves than to Pascal's own string type.Length: one function versus two
program LengthDemo;
var
greeting: string;
begin
greeting := 'Hello';
writeln('Length: ', Length(greeting));
end. program len_trim_demo
implicit none
character(len=20) :: greeting
greeting = "Hello"
print *, "Declared width:", len(greeting)
print *, "Trimmed length:", len_trim(greeting)
end program len_trim_demo Pascal needs only one length function,
Length, because a dynamic string has no padding to distinguish from its content — its length is always exactly the number of characters it currently holds. Fortran needs two: len() returns the declared field WIDTH (always 20 here, regardless of content), while len_trim() returns the length ignoring trailing padding — a distinction that only exists because of Fortran's fixed-width fields.Whole-Array Operations: a New Capability
Array declaration with explicit bounds — a close match
program ArrayDeclarationDemo;
var
scores: array[1..5] of Integer;
begin
scores[1] := 85;
scores[2] := 92;
scores[5] := 78;
writeln(scores[1]);
writeln(scores[5]);
end. program array_declaration_demo
implicit none
integer :: scores(1:5)
scores(1) = 85
scores(2) = 92
scores(5) = 78
print *, scores(1)
print *, scores(5)
end program array_declaration_demo Both languages let the programmer choose arbitrary array bounds rather than being locked to 0-based indexing: Pascal's
array[1..5] and Fortran's scores(1:5) both declare a 5-element array indexed 1 through 5 — either language could just as easily use [0..4] or (0:4) instead.⚠ Whole-array arithmetic: a genuinely new capability
program ElementLoopDemo;
var
prices: array[1..3] of Double;
i: Integer;
begin
prices[1] := 10.0;
prices[2] := 20.0;
prices[3] := 30.0;
for i := 1 to 3 do
prices[i] := prices[i] * 0.9;
for i := 1 to 3 do
write(prices[i]:0:2, ' ');
writeln;
end. program whole_array_demo
implicit none
real :: prices(3)
prices = [10.0, 20.0, 30.0]
prices = prices * 0.9 ! scale every element at once
print *, prices
end program whole_array_demo This is the headline structural difference between these two otherwise-similar languages, and a genuinely new capability for a Pascal programmer. Fortran treats an array as a value you can operate on directly:
prices = prices * 0.9 multiplies every element in a single statement, with no loop at all. Pascal has no whole-array operators whatsoever — scaling every element always requires an explicit for loop written out by hand, even though the two languages agree on almost everything else about arrays (bounds, declaration style, 1-based-by-choice indexing).SUM intrinsic versus manual accumulation
program ArraySumDemo;
var
numbers: array[1..5] of Integer;
i, total: Integer;
begin
numbers[1] := 10; numbers[2] := 20; numbers[3] := 30;
numbers[4] := 40; numbers[5] := 50;
total := 0;
for i := 1 to 5 do
total := total + numbers[i];
writeln('Total: ', total);
end. program array_sum_demo
implicit none
integer :: numbers(5), total
numbers = [10, 20, 30, 40, 50]
total = sum(numbers)
print *, "Total:", total
end program array_sum_demo Fortran's
sum() intrinsic totals an entire array in a single call. Pascal has no equivalent built-in for a plain static array — the standard idiom is a for loop that adds each element into an accumulator initialized to zero, one more consequence of Pascal's lack of whole-array operations.Control Flow
If / Else
program IfElseDemo;
var
score: Integer;
begin
score := 85;
if score >= 90 then
writeln('A')
else if score >= 80 then
writeln('B')
else
writeln('Below B');
end. program if_else_demo
implicit none
integer :: score
score = 85
if (score >= 90) then
print *, "A"
else if (score >= 80) then
print *, "B"
else
print *, "Below B"
end if
end program if_else_demo Both languages structure
if/else if/else nearly identically. Fortran requires parentheses around the condition and an explicit end if closing statement; Pascal uses then with no parentheses and needs begin...end only when a branch has more than one statement.case becomes SELECT CASE
program CaseDemo;
var
dayNumber: Integer;
begin
dayNumber := 3;
case dayNumber of
1: writeln('Monday');
2: writeln('Tuesday');
3: writeln('Wednesday');
else writeln('Unknown');
end;
end. program select_case_demo
implicit none
integer :: day_number
day_number = 3
select case (day_number)
case (1)
print *, "Monday"
case (2)
print *, "Tuesday"
case (3)
print *, "Wednesday"
case default
print *, "Unknown"
end select
end program select_case_demo Pascal's
case...of and Fortran's select case are close structural cousins, both matching a discrete value against a chain of alternatives with a catch-all (Pascal's else, Fortran's case default). Fortran additionally supports matching a contiguous range in one case (case (1:5)), something Pascal expresses instead with a comma-separated list of individual values.Loops
for becomes do
program ForLoop;
var
counter: Integer;
begin
for counter := 1 to 5 do
writeln(counter);
end. program do_loop_demo
implicit none
integer :: counter
do counter = 1, 5
print *, counter
end do
end program do_loop_demo Pascal's
for counter := 1 to 5 do and Fortran's do counter = 1, 5 are close structural cousins — both iterate a counter over an inclusive range with a step of 1 by default. Fortran's do loop additionally accepts an explicit third step value (do i = 10, 1, -1), where Pascal needs the separate downto keyword just for stepping backward by exactly 1, with no other step size available at all.While loop — nearly identical
program WhileLoop;
var
count: Integer;
begin
count := 0;
while count < 5 do
begin
writeln(count);
count := count + 1;
end;
end. program while_loop_demo
implicit none
integer :: count
count = 0
do while (count < 5)
print *, count
count = count + 1
end do
end program while_loop_demo Pascal's
while condition do and Fortran's do while (condition) are nearly the same construct with the keyword order swapped — both continue looping WHILE the condition holds, unlike COBOL's inverted PERFORM UNTIL phrasing.const/var/out vs. intent — a Near-Exact Mapping
const parameter versus intent(in) — a near-exact mapping
program ConstParamDemo;
function CircleArea(radius: Real): Real;
const
Pi = 3.14159265358979;
begin
CircleArea := Pi * radius * radius;
end;
begin
writeln(CircleArea(5.0):0:2);
end. program intent_in_demo
implicit none
print *, circle_area(5.0)
contains
function circle_area(radius) result(area)
real, intent(in) :: radius
real, parameter :: pi = 3.14159265358979
real :: area
area = pi * radius * radius
end function circle_area
end program intent_in_demo Pascal's plain value parameters (no
var modifier, as used here for radius) and Fortran's intent(in) both tell the compiler the parameter is read-only for the duration of the call, and both are checked at compile time — this is one of the closest one-to-one mappings between the two languages' feature sets on the entire site.var parameter versus intent(inout) — completing the correspondence
program VarParamDemo;
procedure Swap(var firstValue, secondValue: Integer);
var
tempValue: Integer;
begin
tempValue := firstValue;
firstValue := secondValue;
secondValue := tempValue;
end;
var
firstNumber, secondNumber: Integer;
begin
firstNumber := 1;
secondNumber := 2;
Swap(firstNumber, secondNumber);
writeln(firstNumber, ' ', secondNumber);
end. program intent_inout_demo
implicit none
integer :: first_number, second_number
first_number = 1
second_number = 2
call swap(first_number, second_number)
print *, first_number, second_number
contains
subroutine swap(first_value, second_value)
integer, intent(inout) :: first_value, second_value
integer :: temp_value
temp_value = first_value
first_value = second_value
second_value = temp_value
end subroutine swap
end program intent_inout_demo Pascal's
var parameter modifier and Fortran's intent(inout) both pass the caller's actual variable by reference, letting the procedure both read and modify it in place — another near-exact mapping. Fortran additionally has a write-only intent(out) mode matching a Pascal out parameter, completing the correspondence across all three modes both languages share.Functions
Result versus an explicit result() clause
program SquareDemo;
function Square(n: Integer): Integer;
begin
Square := n * n;
end;
begin
writeln(Square(7));
end. program square_demo
implicit none
print *, square(7)
contains
function square(n) result(squared)
integer, intent(in) :: n
integer :: squared
squared = n * n
end function square
end program square_demo Free Pascal assigns the return value with
FunctionName := value — a special built-in variable sharing the function's own name. Fortran's result(squared) clause names a completely separate variable to hold the return value, avoiding any naming collision between the function and its own result — a small but genuine ergonomic difference.Records vs. Derived Types
Record versus derived type — a close match
program RecordDemo;
type
TPoint = record
X: Real;
Y: Real;
end;
var
point: TPoint;
begin
point.X := 3.0;
point.Y := 4.0;
writeln(point.X:0:1, ', ', point.Y:0:1);
end. program derived_type_demo
implicit none
type :: point_type
real :: x
real :: y
end type point_type
type(point_type) :: point
point%x = 3.0
point%y = 4.0
print *, point%x, point%y
end program derived_type_demo Pascal's
record and Fortran's derived type are a close structural match — both group named, typed fields under one named type. The field-access syntax differs slightly: Pascal's dot (point.X) versus Fortran's percent sign (point%x), a Fortran-specific choice made because . was already used for logical operators like .true./.and. in older Fortran.A Numerical Toolkit Pascal Lacks
MAXVAL/MINVAL: no Pascal equivalent for a plain array
program MaxMinDemo;
var
numbers: array[1..5] of Integer;
i, highest, lowest: Integer;
begin
numbers[1] := 30; numbers[2] := 10; numbers[3] := 50;
numbers[4] := 20; numbers[5] := 40;
highest := numbers[1];
lowest := numbers[1];
for i := 2 to 5 do
begin
if numbers[i] > highest then highest := numbers[i];
if numbers[i] < lowest then lowest := numbers[i];
end;
writeln(highest, ' ', lowest);
end. program maxval_minval_demo
implicit none
integer :: numbers(5)
numbers = [30, 10, 50, 20, 40]
print *, maxval(numbers), minval(numbers)
end program maxval_minval_demo Fortran's
maxval()/minval() intrinsics find the largest/smallest element of an entire array in one call each. Pascal has no built-in equivalent for a plain static array — finding either requires a hand-written loop tracking a running highest/lowest value, one more example of the numerical-array toolkit Fortran ships that Pascal simply does not have.WHERE: conditional whole-array assignment with no Pascal parallel
program ConditionalLoopDemo;
var
values: array[1..5] of Real;
i: Integer;
begin
values[1] := -3.0; values[2] := 5.0; values[3] := -1.0;
values[4] := 8.0; values[5] := -2.0;
for i := 1 to 5 do
if values[i] < 0 then
values[i] := 0.0;
for i := 1 to 5 do
write(values[i]:0:1, ' ');
writeln;
end. program where_demo
implicit none
real :: values(5)
values = [-3.0, 5.0, -1.0, 8.0, -2.0]
where (values < 0)
values = 0.0
end where
print *, values
end program where_demo Fortran's
where construct applies a condition and an assignment to every array element that matches, all in one statement, with no explicit loop or index variable at all — a genuinely new capability with no Pascal equivalent whatsoever, since Pascal always needs an explicit indexed loop to inspect and conditionally modify individual elements.Gotchas for Pascal Developers
Array literal syntax: [ ] in both, but for different collections
program ArrayInitDemo;
var
numbers: array[1..3] of Integer;
begin
{ Pascal has no bare array-literal assignment syntax at all in
an executable statement — each element must be assigned
individually: }
numbers[1] := 1;
numbers[2] := 2;
numbers[3] := 3;
writeln(numbers[1], ' ', numbers[2], ' ', numbers[3]);
end. program array_constructor_demo
implicit none
integer :: numbers(3)
numbers = [1, 2, 3]
print *, numbers
end program array_constructor_demo Fortran's
[1, 2, 3] "array constructor" syntax builds and assigns a whole array in a single executable statement. Free Pascal has no equivalent for an ordinary executable assignment — a parenthesised literal like (1, 2, 3) is only valid inside a const initialiser, never in an executable := statement, so each element must be assigned individually as shown.Both are 1-based only by convention, not by language rule
program ZeroBasedDemo;
var
numbers: array[0..4] of Integer;
begin
numbers[0] := 100;
writeln(numbers[0]);
end. program zero_based_demo
implicit none
integer :: numbers(0:4)
numbers(0) = 100
print *, numbers(0)
end program zero_based_demo A common misconception is that Fortran arrays are always 1-indexed. Both Pascal and Fortran default their examples in this comparison to 1-based indexing purely as a style convention shared with mathematical notation — both languages equally support explicit 0-based (or any other) bounds, as shown here with
[0..4]/(0:4). Neither language enforces one convention over the other the way, say, C or Python effectively does with universal 0-indexing.