What characterizes imperative and functional programming?

Asked

Viewed 7,772 times

31

What characterizes the imperative and functional programming and what are the differences between them in relation to each other?

I cannot understand these two paradigms.

Note:

If you can cite examples of them, preferably in Javascript.

2 answers

18


The imperative paradigm is the one that expresses the code by commands to the computer. Another striking feature is the state mutation (changing the values of objects). It works like a cake recipe.

Has more information on the imperative in another question.

The functional paradigm usually express the code mainly through functions and avoids state mutation. You say how you want the cake and it will be made, so it tends to be more expressive.

Javascript

Taking advantage of the previous question from AP, If I had to choose only one paradigm for the JS, it would be imperative. In fact this is the main paradigm of all the major languages of the market. All the time people are changing state of the available objects and keep ordering the computer to execute instructions. At specific points the expression and organization of the code can be done differently. It is important to say that the JS has a few elements that characterize the functional paradigm (this has been increasing over time).

When we are controlling flow in code (if, switch, while, for, throw and even simple function calls) we are programming imperatively.

When we prefer to use a recursive function to repeat execution instead of a for or while we are applying a more functional style.

In fact pure functional languages can only express repetition in this way. Just as decisions are made through Pattern matching which is similar to the switch, but much more sophisticated allowing the use of various forms, and always results in something, unlike the switch which determines what to execute.

Confusion between paradigms

It is a mistake to call a language functional just because it has a function. Essentially all languages have functions. The way it is used, among other features, is that it will determine whether it is functional. And it gives me the creeps when the person thinks that functional language is the one that has functions, and procedural is the one that has procedures. Every imperative language I know is procedural, even those that use functions. The function in the functional paradigm is expressed in a more mathematical sense.

JS can be functional

Javascript has first class functions (anonymous function, closure). That is, functions can be treated as data, and so can be stored in variables, passed as arguments to other functions. Functions can be recursive. The language stops there in the functional paradigm. The rest that characterizes a functional language can only be applied indirectly and by convention, this includes pure functions (without side effects), high-order functions, lazy assessment or partial, referential transparency, etc..

Some libraries and frameworks, like jQuery for example, adopt a functional programming post. When you use a function forEach() instead of a for is adopting the most functional style, although internally the execution of the function is all imperative.

So you can adopt the functional style, but you will never program fully functionally in JS.

Which to use?

As most people have difficulties with mathematical abstractions and concepts, it is usually easier to understand the codes in an imperative way, which is closer than concretely executed by the computer. It is no coincidence that it is easier to create imperative languages.

Of course, if the programmer only has to consume functional elements ready, it is easy to use. Just like OOP, consuming is easy, creating structures to be consumed in the right way is not so easy.

Just like OOP, the functional paradigm is a way to abstract some things, express the intention better, what is desired to do, and less the how to do.

Another reason people prefer the imperative* is that being closer than the computer will run is easier to achieve the best performance, or at least predict the time more easily (for everything has exceptions).

Forcing the more functional style without knowing well what you are doing does not seem like a good idea, especially when you are doing it by fashion. If it is to adopt a paradigm, it is because it is very accustomed to it and it will solve a problem better.

There are several small problems in JS that are solved like this and it is customary to have this style in libraries, examples, or even in the default API of browsers or other hosts.

It can give the impression of the functional paradigm to be easier, after all just say what you want and magically everything runs without worrying about the details. That’s great, until you need something a little different, until things don’t happen exactly the way you expect them to in every situation.

Examples

Imperative

function join(array) {
    var text = "";
    for (var i = 0; i < array.length; i++) {
        text += array[i];
    }
    return text;
}

Functional (Ecmascript 5)

function join(array, i, text) {
    var i = typeof(i) !== "undefined" ?  i : 0;
    var text = typeof(text) !== "undefined" ?  text : "";
    return (i == array.length) ? text : join(array, i + 1, text + array[i]);
}

Functional (Ecmascript 6)

function join([ head = '', ...tail ], text = '') {
    return tail.length === 0 ? (text + head) : join(tail, text + head);
}

foreach()

Array.prototype.forEach = function(callback) {
    for (var i = 0; i < this.length; i++) {
        callback(this[i], i, this);
    }
}

Then you can wear it instead of making the bow in the hand. This can be considered an abuse, especially if it doesn’t bring a clear advantage. There are several disadvantages.

I put in the Github for future reference.

Completion

You have to choose between having full control of what you’re doing and having better abstractions of what you’re supposed to do.

If you want to know a more functional language, I suggest Ocaml. It has all functional concepts, but is not so far from other languages.

Related questions:

*It may seem that object orientation is the preferred paradigm. If you ask people the majority will follow the fashion and say they prefer it, but programming imperatively most of the time. And it’s worse, it’s so serious the lack of knowledge that many say they do OOP and their codes are 100% imperative, because that’s what she knows how to do, but she doesn’t want to be out of fashion, so she says she does.

  • I think your answer has many links... but it was a good answer :)

  • 6

    There it is your discretion to click on them or not. If you had not, then you would not have the option. Internet without links is not internet :) Thank you.

  • A functional footprint with ES6: https://jsfiddle.net/h6z3xgqr/1

  • @Gabrielkatakura Legal, you can put in the answer?

15

Paradigm Imperative

In imperative programming you take full control of what is running in the program and dictate through commands, step by step, what should be done.

In this paradigm, you usually work by changing directly the state of the objects or data structures that are part of the algorithm

In the example below, I made a very simple algorithm that selects all products from a list that are cheaper than 3 Reais:

function selecionarTudoAbaixoDeTresReaisImperativo(produtos) {
  var produtosSelecionados = [];
  for (var i = 0; i < produtos.length; i++) {
    if (produtos[i].preco < 3.00) {
      produtosSelecionados.push(produtos[i].nome);
    }
  }
  return produtosSelecionados;
}

Note that the algorithm sequesters a sequence of steps that iterates over the list of products and goes conditionally adding the items in the list of selected products.

Functional paradigm

In functional programming the idea is to do what you want based on the execution of operations - or functions - in objects.

In this paradigm one usually does not change the state of objects, but each function executed on an object returns a new object with the result of the operation performed.

The same previous example in the functional paradigm:

function selecionarTudoAbaixoDeTresReaisFuncional(produtos) {
  var itemMenorQueTres = function(item) { return item.preco < 3.00; };
  var pegarSomenteNome = function(item) { return item.nome };
  return produtos.filter(itemMenorQueTres).map(pegarSomenteNome);
}

Note that at no time do we explicitly change an object. However, we perform two functional operations in the list produtos:

  1. We filter items with filter according to the criterion implemented in the function itemMenorQueTres. This generates a new list.
  2. We map the filtered objects and returned after the filter using the function map, which turns the list of products into a list of product names. Actually "transform" means creating a new list in a new format.

Results

The two code snippets are equivalent from a computational point of view, in the sense that for each input, they produce the same output.

We can test them as follows:

var frutas = [
    { nome: "Laranja", preco: 3.99 },
    { nome: "Melancia", preco: 2.99 },
    { nome: "Banana", preco: 1.99 }
];
console.log(selecionarTudoAbaixoDeTresReaisImperativo(frutas));
console.log(selecionarTudoAbaixoDeTresReaisFuncional(frutas));

Both will print the list ["Melancia", "Banana"] on the console.

See the code working here.

Considerations

The imperative programming provides more control and is closer to the machine language, the final machine only understands direct commands. The performance of paradigm languages is usually better, for the same type of language, because it can be more easily translated into something closer to machine language.

However, having total control also means making more mistakes or being more likely to do it without realizing it. The fact that imperative languages often give preference to working with mutable objects is a major barrier to processing multithreading.

Functional programming attempts to solve several of these problems and tends to generate a more modular program, which works natively with parallelism, sometimes easier to read, in addition to incurring fewer gross errors such as infinite and similar loops, since you do not explicitly execute the loop. For example:

return produtos.filter(itemMenorQueTres).map(pegarSomenteNome);

This is much easier to understand than the imperative version, with a.

The great disadvantage of functional programming is that it can be difficult to understand for those who are not properly trained in the concepts.

In other words: it is not as natural to humans as the list of commands in the imperative paradigm.

Which is better?

It is important to understand that there is not really a consensus on which of the paradigms is better.

Many people claim that, like any tool, they each have applications in different areas. However, proponents of each paradigm always have some argument to say that their favorite paradigm can also solve other types of problems at least reasonably.

Recently there was a discussion involving hundreds of people in the company where I work, due to a bug very difficult to discover in a piece of purely functional code. The incident raised a red flag for some on the complexity problem of some functional implementations.

Conclusion: we have to know the two paradigms and use the one that seems to make the most sense in each case. If it starts to stink, just change.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.