I understand that some languages combine elements for many different paradigms in programming. I'm told that Fortran is an example of a Functional language, however I'm just a little confused as to whether or not it is purely functional, as it seems to mostly be used for mathematical functions, however I also read that it is possible to apply object oriented programming to Fortran as well, so is it some sort of a hybrid?
"I'm just a little confused as to whether or not it is purely functional, as it seems to mostly be used for mathematical functions"
This seems to be a misconception about the meaning of the term "purely functional", and possibly also a misconception about the meaning of the term "mathematical function".
A mathematical function is a mapping between inputs and outputs:
In mathematics, a function is a relation between sets that associates to every element of a first set exactly one element of the second set.
In the context of programming languages, the input to a function is its arguments, and the output is its return value, so e.g. a function like
def greeting(name):
return 'Hello, ' + name
in Python is considered a mathematical function, whereas a function like
def print_square(x):
print(x ** 2)
return None
is not considered a mathematical function. Note here that whether or not the computation is mathematical in nature is not relevant to whether it is a function in the mathematical sense; print_square
does some arithmetic, which is more like mathematics than what greeting
does. But greeting
is a mathematical function and print_square
is not.
greeting
is a mathematical function because it is a mapping from the set of strings to the set of strings, and the function can be described by what inputs are associated with what outputs. It would take infinitely many lines to write out the mapping in full, but the mapping is like:
'Alice' → 'Hello, Alice'
'Bob' → 'Hello, Bob'
'Charles' → 'Hello, Charles'
'####' → 'Hello, ####'
'' → 'Hello, '
...
Every element in the first set (i.e. the set of all strings) is associated with exactly one element in the second set, so greeting
meets the definition of a mathematical function.
In contrast, print_square
is not a mathematical function in the sense that it cannot be described by a mapping from inputs to outputs:
12 → None
4 → None
...
These mappings (from the set of integers to the set {None}
) do not properly define what print_square
does, which is that it computes the square of the input and prints it to the console.
To avoid any confusion with "functions that do something mathematical", it is better to use the computing term "pure function":
... a pure function is a computational analogue of a mathematical function.
So to address your comment that Fortran "seems to mostly be used for mathematical functions", Fortran is mostly used for doing mathematical computations, but this is not what "mathematical function" means.
A purely functional programming language is one where all computation is done by pure functions:
In computer science, purely functional programming usually designates a programming paradigm ... that treats all computation as the evaluation of mathematical functions. Purely functional programming may also be defined by forbidding changing-state and mutable data.
Note that it is not sufficient for a programming language to allow you to write pure functions; this definition says all computation has to be done by pure functions for the language to qualify as purely functional.
Is Fortran a purely functional language? No, it is not. Subroutines in Fortran can do things other than return values according to a mapping between input and output; and computations in Fortran can be done with state changes and mutable data. One example is sufficient: this one comes from Rosetta Code.
subroutine hs(number, length, seqArray)
integer, intent(in) :: number
integer, intent(out) :: length
integer, optional, intent(inout) :: seqArray(:)
integer :: n
n = number
length = 1
if(present(seqArray)) seqArray(1) = n
do while(n /= 1)
if(mod(n,2) == 0) then
n = n / 2
else
n = n * 3 + 1
end if
length = length + 1
if(present(seqArray)) seqArray(length) = n
end do
end subroutine
The variable n
is clearly mutable, as its state is changed within a loop. Also, the array seqArray
is mutable, it is both an input and an output to the subroutine, and the subroutine changes the array's state. So this subroutine does not define a pure function, and it uses "changing-state and mutable data", which is forbidden by the definition of a purely functional language.
So the subroutine hs
does not define a "mathematical function", even though the computation it performs is mathematical in nature.
... a programming paradigm that uses statements that change a program's state. ... an imperative program consists of commands for the computer to perform.
The Fortran subroutine shown above meets both of these definitions: it uses statements or commands that change the program's state, which the computer performs. So Fortran is an imperative programming language.
Note that unlike Wikipedia's definition for "purely functional", a language can be imperative even if it doesn't do all computation in this way. So although it's possible to write pure functions in Fortran which don't work by changing the program's state, Fortran is imperative; just perhaps not "purely imperative".
"That would mean that fortran only describes the 'how' to do something and not 'what' it's trying to do?"
It's often said that an imperative program is one which says "how" a computation should be done, whereas a declarative program only says "what" should be done. Even Wikipedia says so:
Imperative programming focuses on describing how a program operates.
The term is often used in contrast to declarative programming, which focuses on what the program should accomplish without specifying how the program should achieve the result.
So is the Fortran code describing "how" the program should do something, or "what" it should accomplish?
A statement like n = n / 2
is a command telling the computer to do something; there is a program state before the computer performs the command, and a different program state afterwards. The statement n = n / 2
also tells the computer "how" to perform the command: divide the current value of n
by 2, and store the result in the variable n
. So according to the "how"/"what" distinction, Fortran is imperative, not declarative.
But you might argue: n = n / 2
says "what" we want to achieve; a new program state where n
holds its value from the old state, divided by 2. And you would be right, it does say that, at least to a human reading it.
What this shows is that the "how"/"what" distinction is too vague to be used as a definition to decide whether a language is imperative or declarative. It is meant as a loosely-described contrast between those paradigms, not as a definition of either paradigm. To decide whether a language is imperative or purely functional, or in any other paradigm, you should refer to a serviceable definition of that paradigm.