Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is difference between functional and imperative programming languages?

Here is the difference:

Imperative:

  • Start
  • Turn on your shoes size 9 1/2.
  • Make room in your pocket to keep an array[7] of keys.
  • Put the keys in the room for the keys in the pocket.
  • Enter garage.
  • Open garage.
  • Enter Car.

... and so on and on ...

  • Put the milk in the refrigerator.
  • Stop.

Declarative, whereof functional is a subcategory:

  • Milk is a healthy drink, unless you have problems digesting lactose.
  • Usually, one stores milk in a refrigerator.
  • A refrigerator is a box that keeps the things in it cool.
  • A store is a place where items are sold.
  • By "selling" we mean the exchange of things for money.
  • Also, the exchange of money for things is called "buying".

... and so on and on ...

  • Make sure we have milk in the refrigerator (when we need it - for lazy functional languages).

Summary: In imperative languages you tell the computer how to change bits, bytes and words in it's memory and in what order. In functional ones, we tell the computer what things, actions etc. are. For example, we say that the factorial of 0 is 1, and the factorial of every other natural number is the product of that number and the factorial of its predecessor. We don't say: To compute the factorial of n, reserve a memory region and store 1 there, then multiply the number in that memory region with the numbers 2 to n and store the result at the same place, and at the end, the memory region will contain the factorial.


Definition: An imperative language uses a sequence of statements to determine how to reach a certain goal. These statements are said to change the state of the program as each one is executed in turn.

Examples: Java is an imperative language. For example, a program can be created to add a series of numbers:

 int total = 0;
 int number1 = 5;
 int number2 = 10;
 int number3 = 15;
 total = number1 + number2 + number3; 

Each statement changes the state of the program, from assigning values to each variable to the final addition of those values. Using a sequence of five statements the program is explicitly told how to add the numbers 5, 10 and 15 together.

Functional languages: The functional programming paradigm was explicitly created to support a pure functional approach to problem solving. Functional programming is a form of declarative programming.

Advantages of Pure Functions: The primary reason to implement functional transformations as pure functions is that pure functions are composable: that is, self-contained and stateless. These characteristics bring a number of benefits, including the following: Increased readability and maintainability. This is because each function is designed to accomplish a specific task given its arguments. The function does not rely on any external state.

Easier reiterative development. Because the code is easier to refactor, changes to design are often easier to implement. For example, suppose you write a complicated transformation, and then realize that some code is repeated several times in the transformation. If you refactor through a pure method, you can call your pure method at will without worrying about side effects.

Easier testing and debugging. Because pure functions can more easily be tested in isolation, you can write test code that calls the pure function with typical values, valid edge cases, and invalid edge cases.

For OOP People or Imperative languages:

Object-oriented languages are good when you have a fixed set of operations on things and as your code evolves, you primarily add new things. This can be accomplished by adding new classes which implement existing methods and the existing classes are left alone.

Functional languages are good when you have a fixed set of things and as your code evolves, you primarily add new operations on existing things. This can be accomplished by adding new functions which compute with existing data types and the existing functions are left alone.

Cons:

It depends on the user requirements to choose the way of programming, so there is harm only when users don’t choose the proper way.

When evolution goes the wrong way, you have problems:

  • Adding a new operation to an object-oriented program may require editing many class definitions to add a new method
  • Adding a new kind of thing to a functional program may require editing many function definitions to add a new case.

Most modern languages are in varying degree both imperative and functional but to better understand functional programming, it will be best to take an example of pure functional language like Haskell in contrast of imperative code in not so functional language like java/C#. I believe it is always easy to explain by example, so below is one.

Functional programming: calculate factorial of n i.e n! i.e n x (n-1) x (n-2) x ...x 2 X 1

-- | Haskell comment goes like
-- | below 2 lines is code to calculate factorial and 3rd is it's execution  

factorial 0 = 1
factorial n = n * factorial (n - 1)
factorial 3

-- | for brevity let's call factorial as f; And x => y shows order execution left to right
-- | above executes as := f(3) as 3 x f(2) => f(2) as 2 x f(1) => f(1) as 1 x f(0) => f(0) as 1  
-- | 3 x (2 x (1 x (1)) = 6

Notice that Haskel allows function overloading to the level of argument value. Now below is example of imperative code in increasing degree of imperativeness:

//somewhat functional way
function factorial(n) {
  if(n < 1) {
     return 1;
  }
  return n * factorial(n-1);   
}
factorial(3);

//somewhat more imperative way
function imperativeFactor(n) {
  int f = 1;
  for(int i = 1; i <= n; i++) {
     f = f * i;
  }
  return f;
}

This read can be a good reference to understand that how imperative code focus more on how part, state of machine (i in for loop), order of execution, flow control.

The later example can be seen as java/C# lang code roughly and first part as limitation of the language itself in contrast of Haskell to overload the function by value (zero) and hence can be said it is not purist functional language, on the other hand you can say it support functional prog. to some extent.

Disclosure: none of the above code is tested/executed but hopefully should be good enough to convey the concept; also I would appreciate comments for any such correction :)


Functional Programming is a form of declarative programming, which describe the logic of computation and the order of execution is completely de-emphasized.

Problem: I want to change this creature from a horse to a giraffe.

  • Lengthen neck
  • Lengthen legs
  • Apply spots
  • Give the creature a black tongue
  • Remove horse tail

Each item can be run in any order to produce the same result.

Imperative Programming is procedural. State and order is important.

Problem: I want to park my car.

  1. Note the initial state of the garage door
  2. Stop car in driveway
  3. If the garage door is closed, open garage door, remember new state; otherwise continue
  4. Pull car into garage
  5. Close garage door

Each step must be done in order to arrive at desired result. Pulling into the garage while the garage door is closed would result in a broken garage door.


Functional programming is "programming with functions," where a function has some expected mathematical properties, including referential transparency. From these properties, further properties flow, in particular familiar reasoning steps enabled by substitutability that lead to mathematical proofs (i.e. justifying confidence in a result).

It follows that a functional program is merely an expression.

You can easily see the contrast between the two styles by noting the places in an imperative program where an expression is no longer referentially transparent (and therefore is not built with functions and values, and cannot itself be part of a function). The two most obvious places are: mutation (e.g. variables) other side-effects non-local control flow (e.g. exceptions)

On this framework of programs-as-expressions which are composed of functions and values, is built an entire practical paradigm of languages, concepts, "functional patterns", combinators, and various type systems and evaluation algorithms.

By the most extreme definition, almost any language—even C or Java—can be called functional, but usually people reserve the term for languages with specifically relevant abstractions (such as closures, immutable values, and syntactic aids like pattern matching). As far as use of functional programming is concerned it involves use of functins and builds code without any side effects . used to write proofs


Imperative programming style was practiced in web development from 2005 all the way to 2013.

With imperative programming, we wrote out code that listed exactly what our application should do, step by step.

The functional programming style produces abstraction through clever ways of combining functions.

There is mention of declarative programming in the answers and regarding that I will say that declarative programming lists out some rules that we are to follow. We then provide what we refer to as some initial state to our application and we let those rules kind of define how the application behaves.

Now, these quick descriptions probably don’t make a lot of sense, so lets walk through the differences between imperative and declarative programming by walking through an analogy.

Imagine that we are not building software, but instead we bake pies for a living. Perhaps we are bad bakers and don’t know how to bake a delicious pie the way we should.

So our boss gives us a list of directions, what we know as a recipe.

The recipe will tell us how to make a pie. One recipe is written in an imperative style like so:

  1. Mix 1 cup of flour
  2. Add 1 egg
  3. Add 1 cup of sugar
  4. Pour the mixture into a pan
  5. Put the pan in the oven for 30 minutes and 350 degrees F.

The declarative recipe would do the following:

1 cup of flour, 1 egg, 1 cup of sugar - initial State

Rules

  1. If everything mixed, place in pan.
  2. If everything unmixed, place in bowl.
  3. If everything in pan, place in oven.

So imperative approaches are characterized by step by step approaches. You start with step one and go to step 2 and so on.

You eventually end up with some end product. So making this pie, we take these ingredients mix them, put it in a pan and in the oven and you got your end product.

In a declarative world, its different.In the declarative recipe we would separate our recipe into two separate parts, start with one part that lists the initial state of the recipe, like the variables. So our variables here are the quantities of our ingredients and their type.

We take the initial state or initial ingredients and apply some rules to them.

So we take the initial state and pass them through these rules over and over again until we get a ready to eat rhubarb strawberry pie or whatever.

So in a declarative approach, we have to know how to properly structure these rules.

So the rules we might want to examine our ingredients or state, if mixed, put them in a pan.

With our initial state, that doesn’t match because we haven’t yet mixed our ingredients.

So rule 2 says, if they not mixed then mix them in a bowl. Okay yeah this rule applies.

Now we have a bowl of mixed ingredients as our state.

Now we apply that new state to our rules again.

So rule 1 says if ingredients are mixed place them in a pan, okay yeah now rule 1 does apply, lets do it.

Now we have this new state where the ingredients are mixed and in a pan. Rule 1 is no longer relevant, rule 2 does not apply.

Rule 3 says if the ingredients are in a pan, place them in the oven, great that rule is what applies to this new state, lets do it.

And we end up with a delicious hot apple pie or whatever.

Now, if you are like me, you may be thinking, why are we not still doing imperative programming. This makes sense.

Well, for simple flows yes, but most web applications have more complex flows that cannot be properly captured by imperative programming design.

In a declarative approach, we may have some initial ingredients or initial state like textInput=“”, a single variable.

Maybe text input starts off as an empty string.

We take this initial state and apply it to a set of rules defined in your application.

  1. If a user enters text, update text input. Well, right now that doesn’t apply.

  2. If template is rendered, calculate the widget.

  3. If textInput is updated, re render the template.

Well, none of this applies so the program will just wait around for an event to happen.

So at some point a user updates the text input and then we might apply rule number 1.

We may update that to “abcd”

So we just updated our text and textInput updates, rule number 2 does not apply, rule number 3 says if text input is update, which just occurred, then re render the template and then we go back to rule 2 thats says if template is rendered, calculate the widget, okay lets calculate the widget.

In general, as programmers, we want to strive for more declarative programming designs.

Imperative seems more clear and obvious, but a declarative approach scales very nicely for larger applications.