Functional is not Procedural
I’ve recently seen some confusion about the terms functional and procedural in the software development community. Let me spend a moment trying to clear things up for (both of) my readers.
First of all, just because a programming language has functions, that does not mean it is functional. In fact, its confusing name has nothing to do with functions. The history of the term function, as used in the computation world, hails back to the 1930’s when Alonzo Church created Lambda Calculus to be able to use and define mathematical algorithms on paper. Later, when computers arrived on the scene, programmers adopted the term function to describe a chunk of code that could be re-used by other chunks of code. Functions, in this context, have been adopted by every programming language I know of, including assembly language. Functions are commonly referred to as “routines”, “subroutines”, or “procedures”. Some might even argue that a “method” is pragmatically identical to a function.
Here’s where the confusion begins.
This is hard to explain rigorously, but here goes anyway.
Some languages, like C, tend to encourage computer programmers to make use of functions. Programs written in these languages tend to consist of a set of functions, and a “main” function that kicks everything off. Such a language is often referred to as “procedural”, but really the term “procedural” refers to a style of programming, and does not really describe a language, per se. It is often used incorrectly as an antonym to the concept of “object oriented”.
Other languages, like Scheme and Haskell, tend to encourage computer programmers to write code with functions that avoid internal state changes and produce no side effects when called. For example, these language discourage global variables, and particularly the calling of functions that would mutate global variables (that would be a side effect).
To sum up.
Procedural programming languages can be functional or not. Functional programming languages can be procedural or not.
Here’s a table:
Language | Functional | Procedural |
---|---|---|
C | No | Yes |
Haskell | Yes | Yes |
Python | Can be | Can be |
C++ | No | Can be (if you write it like C) |
Java | No | Usually not |
OCaml | Yes | Yes |
If you take nothing else away from this article, take this: The C programming language is not a functional language. It’s not bad, it’s just not functional.
Has one comment to “Functional is not Procedural”
I think the difference is easier to understand by looking at code written in the different styles. Here is an implementation of factorial written in a procedural style:
int procedural_factorial(int n)
{
int fact = 1;
while (n > 1)
{
fact *= n;
n–;
}
return fact;
}
Here is another implementation of factorial written in a functional style:
int functional_factorial(const int n)
{
if (n <= 1)
{
return 1;
}
else
{
return n * functional_factorial(n-1);
}
}
Notice that the in the functional style the value of a variable is *never* mutated. In functional programming you don't mutate variables (all variables could be declared as constants) you just create new variables with new values. Also notice that the functional style uses recursion. Recursion is scary for C/C++ programmers because you're always worried about blowing your stack, in functional programming languages you can write recursive functions that don't grow the stack. At first glance it seems impossible to write any "real" programs if you're not allowed to mutate variables, but you can. You just have to develop a new way of thinking and solving problems.