C-like languages (C, C++, Java) can do many things, but over the decades nothing much has changed with the inadequacies of some of their control structures. Fortran on the other hand, has evolved. Here are some things that just make implementing some algorithms easier. (Yes there are work arounds in C, but they are not as elegant).
Exiting from a nested loop
In C-like languages exiting from a deeply nested loop isn’t exactly trivial (without the use of goto
, so don’t even go there). A break
statement in C will only exits the loop the break
resides in. If the break appears inside a nested loop, the break only leaves the loop it is in. There is no single break statement in C that will break out of more than one level of nesting. It is possible to add an extra condition, for example in C:
exitloop = 0
for (i=1; i<=10 && !exitloop; i=i+1)
for (j=1; j<=10 && !exitloop; j=j+1)
for (k=1; k<=10 && !exitloop; k=k+1)
if (x[i][j][k] == 0)
exitloop = 1;
Fortran however allows loops to be named, so exiting nested loops is as simple as naming the loop to be exited.
loop1</strong>: do i = 1, 10
loop2: do j = 1, 10
loop3: do k = 1, 10
if (x(i,j,k) == 0) exit loop1
end do loop3
end do loop2
end do loop1
Ranges in a case statement
C doesn’t do ranges in switch
… okay so some compilers, like gnu C offer it as an extension, but it’s not part of the spec. Fortran allows it as part of the standard.
integer :: temp_c
! Fujita Scale for wind velocity (mph)
select case (windS)
case (40:72)
write (*,*) 'F0 : light-weak'
case (73:112)
write (*,*) 'F1 : moderate-weak'
case (113:157)
write (*,*) 'F2 : significant-strong'
case (158:206)
write (*,*) 'F3 : severe-strong'
case (207:260)
write (*,*) 'F4 : devastating-violent'
end select
Array slicing
If you deal with arrays, you know how important it is to have array slicing in a language – because it makes manipulating arrays super easy. Why write loops when you don’t have to? Here are two array declarations in Fortran.
integer, dimension(100) :: vec
integer, dimension(1:6,1:6) :: arr2d
Here are some things you can do:
print *, size(vec) ! print the size of the array
print *, vec(40:50) ! print elements 40 to 50
print *, vec(40:50:2)! print elements 40 to 50, step size 2, ie. 40,42,...
add2d = 1 ! set all elements of the array to the value 1
arr2d(3:4,3:4) = 2 ! set elements in row 3 and 4, col 3 and 4 to value 2
write (*,*) arr2d ! print out the whole array (a bit messy)
Arrays in 2D can be messy when printed using the single statement above. It is possible to use a single loop, and slicing to make things look nicer. The loop controls the row, and the columns are all included using the “:” symbol.
do i = 1,size(arr2d,1)
write(*,'(6i4)') arr2d(i,:)
end do
There is no array slicing mechanism in C.
Arrays with any indices you want
Fortran by default indexes arrays at 1. But, you are not restricted to that, you can specify the index range of any array. Some examples are shown below:
integer, dimension(100) :: v ! indices-> 1..100
integer, dimension(0..99) :: w ! indices-> 0..99
real, dimension(-5:5) :: z ! indices-> -5,-4,...0,...4,5
real, dimension(3,4) :: a ! indices-> x: 1..3 and y: 1..4
real, dimension(-1:1,4) :: a ! indices-> x: -1,0,1 and y: 1..4
Makes it much easier to bend a language to an algorithm, rather than the other way around.
No dangling else
Regardless of what people say, dangling else
does cause problems in languages like C. The fact that all Fortran control structures are terminated puts a stop to that. There is also no need for { and } or similar to signify the begin and end of a control block.
Few if any dangerous things
Fortran is cool because it is easy to learn, hard to make catastrophic errors with, and for numerical computation there is likely no faster language. Sure, it may lack some of the low-level features of C, but not every language has to be so close to the system.
> hard to make catastrophic errors with
LOL. This reminded me of the time I changed 1 to be 0 in a Fortran program. That was tough to debug…
Two minor things. Second paragraph has exist instead of exit. “C will only exist the loop”
The “strong” HTML tag in the first Fortran listing isn’t rendering.
Otherwise interesting article. I haven’t used Fortran since the 80’s, but it’s nice to point out that just because it’s old it isn’t useless. We used to sell it with the some of the HP computers we sold back then,
A good post. The only quibble I have is the usual “goto is bad”.
Using goto in C to break a loop is equivalent to using a labelled break in Java – it’s just a matter of placing the label in the right spot.
I fact, I would argue that in C, goto is superior to your suggestion of a break variable, (or even using a function for each loop level) because:
1. you don’t have to remember to include the break variable in every nested loop.
2. you may not want to break out of the whole loop, maybe you just want to break out to the top loop.
The only difference is that goto is unstructured, and the loop labels are not, i.e. they can’t really be misused.
I have no real problem with goto per se, except that some people use it as an “easy solution”, and others because they have developed poor programming skills. To those people, I would plonk a 300 line legacy Fortran program in their laps containing 50 arithmetic ifs, and have them go at it to decipher it. I have never been a fan of goto, but that’s personal preference, just like indexing arrays starting at 1.
I do also get tired of “goto is bad” it’s just a tool, used properly it’s a great tool, used badly is just like any other tool used badly and there is consequences. when Dijkstra coined the term it was before C and code was a procedural spaghetti mess, and I can see his point for the time but things have changed a lot since then.
Maybe, if it wasn’t for the fact that some people still don’t understand how to use it properly. Everyone is entitled to their opinions. Considering that Apple had the famous “SSL security flaw” in 2014, I wonder how much other crappy code is out there. it actually wasn’t Dijkstra who titled his article, it was the editor. Dijkstra cared more about writing proper code than kicking goto explicitly.
Hi.
I think in C# limitations are less than C/C++/Java:
EXITING FROM A NESTED LOOP
https://dotnetfiddle.net/NKo48x
RANGES IN A CASE STATEMENT
https://dotnetfiddle.net/cMjje4
ARRAY SLICING
C# has some syntax limitation about multi-dimentional array initializers
https://dotnetfiddle.net/c4a54M
ARRAYS WITH ANY INDICES YOU WANT
in C# array’s index starts from 0, but there is Dictionary that support all type of entries with any values
https://dotnetfiddle.net/Q1qmCf
Maybe. I mean Swift fixes some of the C issues. Of course the biggest problem with C# is that it’s from Microsoft 😀
You left out one of the most important Fortran advantages: array operations, e g, C=A+B, where A, B and C are arrays. I would also add use of modules, although modern C++ has almost equivalents.
I would argue the one of the most important things that Fortran does better than C is not entangling arrays with pointers as C does. The fact that an array name in Fortran is not a pointer not only enables such things as whole array operations, it also also allows Fortran compilers to safely optimize code.
Absolutely! I haven’t used Fortran “in anger” since the 1980s (all C++ and Python for decades now), but I still use it for hobby purposes on emulated historic mainframes and I remember being shocked when I first encountered C in the early 80s by how primitive the array handling was. As an implementation language for Unix like operating systems, C is pretty much perfect. But for at least some applications programming (e.g. numerical analysis), not so much. Contrary to endless pronouncements of computer science professors in the 80s, Fortran-77 was both useful and usable. I’ve no doubt that’s still true of modern Fortran (but even more so).
Loved this post! I am currently using f2py to revive some of my “old” Fortran codes. I am making use of the index renaming to start all arrays at 0 and keep it “compatible” with my python interface.
Why don’t you just revive them in Modern Fortran (F2018)!?!
This article just makes me want to learn Fortran even more.
Is it me, or the Fortran code just feels better compare to C? As in shorter and more readable?
It is more readable. I think the evolution of Fortran is one of learning, and improving. There is no dependence on pointers as in C.
I mean, who wants to know about memory when you want to read in a simple integer?