For the past couple of months I have been looking into different aspects of functional programming and learning languages like F# and Haskell.While discussing about this with my friends ( particularly to those who are developers without much academic inclination) I find it sometimes a bit difficult to explain the essence of functional programming as many are not much aware of the basic driver behind the design of the imperative languages.After going through couple of papers and articles I found the paper by John Backus titled “Can Programming Be Liberated from the von Neumann Style? A Functional Style and Its Algebra of Programs“ captures what I was looking for but in a rather complex fashion.In this post I will try to explain the basic issues with imperative languages and essence of functional languages in a simpler fashion.
To start with let’s go back to the basics and ask the question- What is a Von Neumann Computer?This is the model based on which all the modern digital computers are designed.In it’s simplest form this comprises of a Central Processing Unit (CPU) ,a storage and a pipe connecting the two.The main purpose of the processing unit is to alter the data in the storage by exchanging information through the pipe.Backus has named this pipe as the von Neumann bottleneck.He has also mentioned in that
Not only is this tube a literal bottleneck for the data traffic of a problem, but, more importantly, it is an intellectual bottleneck that has kept us tied to wordat-a-time thinking instead of encouraging us to think in terms of the larger conceptual units of the task at hand.
Now why Backus refers to this as an intellectual bottleneck?This is because the most of the imperative languages are designed and modeled on the way a von Neumann machine operates.The similarity can be drawn as
- Variables correspond to the computer’s storage cells
- Control statements correspond to its jump and test instructions
- Assignment statements correspond to its fetching, storing, and arithmetic.
So we are trying to design a language based on how the machine executing it is designed.This where the intellectual bottleneck is.
In the imperative languages
- Developer’s have to take care of variables and thus think about memory locations.However in high level modern programming languages these details are hidden from the programmer.
- The iterative blocks and control statements makes the programs less readable and complex.
- The functions have Side Effects.When a function apart from returning a value makes another observable change in the system it is referred to as the Side Effect.This can happen due to shared/global state variables, IO handling, exception.The imperative languages does not provide any mechanism to control the side effects.
- The use of shared state and other side effects makes the imperative languages a bad choice for parallel/concurrent programming.For concurrent execution we have to think about deadlocks/race conditions etc. in case of an imperative language.
A pure functional language on the other hand
- Has functions as first class citizens and every computation is treated as a function.
- Does not make use of variables and assignments as an imperative language.Every variable is immutable.
- There are no iterative blocks all repetitive tasks are done using recursion.
- As there is no state and mutable data
- functional language is said to have no side effects but in stricter terms I should say controlled side effects.
- functional languages maintain Referential Transparency.i.e. a function whenever called using same argument returns the same result
- functional language is a better candidate for concurrent programming
For those are not familiar with functional languages will find the features of functional languages difficult to appreciate at this point.In the next couple of posts I will elaborate on this features irrespective of any language.