Vous êtes sur la page 1sur 8

A comparison of programming techniques: contrasting

functional programming and imperative programming”

Contents
1. Abstract .......................................................................................................................................... 2
2. Introduction.................................................................................................................................... 2
2.1 Data Structure ....................................................................................................................... 3
2.2 Mutability and Side-effects .................................................................................................. 3
2.3 Ease of Implementation....................................................................................................... 4
2.4 Efficient and Readability ...................................................................................................... 6
3 Summary ....................................................................................................................................... 7
Reference .............................................................................................................................................. 8

1
1. Abstract
Building computer applications starts with creating abstractions that model problems or
solutions. To describe these abstractions into something that computers can understand and
execute, programming languages were introduced. Programming languages can be
categorized into different paradigms.

In this paper, Functional and Imperative programming paradigms are compared and
contrasted, using a variety of criteria, such as, data structures, mutability, side effects, ease
of implementation and efficiency.

2. Introduction
Developing software systems is about creating abstractions to model problems and
solutions, and then applying these abstractions to the task that needs to be done. In order to
do that, programming languages were developed out of common need for a basic set of
abstractions, such as data types. In principle, programmers specify what should be done and
how it should be done (Kristiansen, 2001). In imperative programming, the compiler would
follow programmer’s instructions to the letter to do something, because imperative
programming reflects the concept of computation that is built into the modern computer
hardware (Jones and Wadler, 1992). Imperative languages, such as C++ and Java specify
both what and how a problem should be approached by using sequences of statements that
change the state of program.

In contrast, functional programming, which is a subclass of declarative programming,


specifies only what should be done and the functional compiler figures out how it should be
done (Davie, 1992). A functional compiler would freely look at programmer’s instructions and
then decide to do something different at the low-level, but can achieve the same result.
Moreover, functional programming is easy to reason about, powerful and friendlier to
concurrency. Although functional programming is gaining popularity, it is somehow
impractical for developing large-scale software systems.

Consequently, you can consider that an imperative compiler is less sophisticated than a
functional one. Even though, functional programming is straightforward, using it to build
complete applications is very difficult. Additionally, functional programming limits what
programmers can do. For example, functional languages do not give programmers any
control over how program inputs are processed. As a result, programmers have no options
but to alleviate the impact of any defects or bugs in the underlying language and depend on
the providers of the functional languages to tackle the issues.

2
2.1 Data Structure
In imperative programming, programmers have many efficient data structures at their
disposal to solve any particular problem (Fokker, 2003). Unfortunately, functional
programmers do not have this advantage. Although some imperative data structures can be
easily adapted in functional languages, most cannot, because these data structures use
assignments to update variables, which are disallowed or at least discouraged in functional
languages. Assignments or destructive updates can be hazardous when misused, but
effective when used correctly. However, this discouragement of using assignments makes
designing and implementing efficient functional data structures more difficult than imperative
ones. Another major obstacle of designing efficient functional data structures is pattern
matching, which is one of the popular features in functional programming. The reason is that
pattern matching can be performing only on data structures whose representation is known
in advance. This leads many functional programmers to abandon developing advanced data
structures in favour of simple known ones such as lists.

Moreover, functional data structures are expected to be more flexible than their imperative
ones. Imperative data structures are ephemeral, meaning that after updating an imperative
data structure, the old version of the data structure will be replaced by the new data structure
and the old version will not be available anymore (Hartel, 1999). On the other hand,
functional data structures are persistent, as they preserve the previous version of data
structures when modified, i.e. when a functional data structure is updated, both the old and
new versions of the data structure will be available. Although functional data structures have
the same time complexity as imperative ones, they have higher space complexity as they
avoid overwriting the existing values in memory. However, functional data structures are
immutable, which means they are very thread-safe. In addition, immutable data structures
are quite simpler and have higher security as they disallow overwriting any parts of the data
that are shared.

2.2 Mutability and Side-effects


Generally, programming languages are designed for sequential execution on computers and
share abstractions for developing solutions that are aimed at these systems. Imperative
programming performs computations by using sequence of statements that manipulate data
to reach a certain goal. Additionally, imperative programs contain instructions to mutate
states. These instructions describe how to solve particular problems by describing in detail
the steps that are needed to find a solution. This allows programmers to modify the contents
of program variables using assignments and each assignment changes the state of the
program. In addition, these changes affect the global state of the computation of the

3
program, therefore such changes have side effects. These side effects make imperative
programs not readable, for example, the returned result from a function depends on what
happened during the execution of other functions. Moreover, these side effects make
imperative programs not reusable as every function depends on the program’s global
environment. Furthermore, because of these side effects the correctness of imperative
programs is almost impossible.

Conversely, functional programs evaluate expressions, which can have values of any type,
including functions and large data structures. This simplicity of functional computations helps
in developing programs that separate concerns, reuse code and provide comprehensible
interface between programs (Fischer, Kiselyov, and Shan, 2011). In functional programming,
all classes are immutable, whose instances cannot be modified. Such classes and objects
can only be in one state, all of the data contained in each instance is provided when it is
created and cannot be modified across threads. By using immutable data structures,
programmers can eliminate the hard to detect bugs. Additionally, immutable classes are
easier to design and less prone to error and are more secure.

Furthermore, pure functional programming has no side effects, because functional programs
evaluate expressions rather than execute commands. Every function in functional
programming is defined by an expression and each expression is formed by applying
function to other expressions. Additionally, every expression has a value and a computation
evaluates the value of an expression. In functional programming, variables represent
constant values, instead of memory locations and functional programming discourages the
modification of variable values.

2.3 Ease of Implementation


Functional and imperative programming languages are mainly differentiated by the control
over program execution and the management of computer memory. Imperative
programming is closer to the computer architecture and the execution of imperative
programs modifies the content of the computer memory state. Additionally, the order in
which commands are executed is very important (Westbrook, Stump and Wehrman, 2005).

Moreover, because imperative programs manipulate pointers and references to values, the
memory that is needed to store these values must be allocated and de-allocated explicitly.
This can make imperative programming to have more control over programs’ execution and
the memory representation of data. However, this also can lead to errors such as memory
leaks, which can affect the performance of applications and the operating system they are
running on. In addition, as imperative languages are closer to the actual machine

4
representation, code written in imperative languages can be more efficient but prone to
runtime errors.

In contrast, the main purpose of designing functional programming languages is to imitate


mathematical functions, when solving problems. This way of solving problems is very
different from approaches used with imperative languages. Functional programs evaluate
and compute expressions, rather than executing commands. Most importantly, the order in
which these evaluations and computations occur does not matter. In functional
programming, programmers do not need to know the physical representation of functions
and data structures they use. Additionally, sharing and allocating of data are not managed
by the programmer, but rather, functional languages implicitly manage the sharing of data,
allocation and de-allocation of memory by using garbage collectors. This is to ensure that
the values, which currently is manipulating exist in the memory (Wadler, 1998).

Furthermore, functional programming is a form of declarative programming. In declarative


programming, the task to find a solution is up to the language implementation. Programmers
have the tools to abstract the details of implementation and focus on details of the problems,
to separate the process of stating a problem from the process of solving it.

Functional languages use functions in mathematical sense, meaning that a mathematical


function always produces the same result when given the same input. One of the essential
features of mathematical functions is that the evaluation order of expressions does not
matter. In functional programming functions are treats as first-class citizens. This means,
functions can be passed as arguments to other functions, assign them to variables or return
them as values from other functions. Additionally, the evaluation order of functional functions
is controlled by recursion, instead of their sequencing order and iterative repetitions that are
common to the imperative programming languages. In functional programming, the result of
a functional call depends only on the values of its arguments.

Functions in imperative programming are subroutines that return values. Moreover,


imperative functions have access to variables other than their arguments and the result of
such functions depend on that variable, and the values of such variables can be changed
after the function call. This means that the function call itself cannot determine the result it
returns.

Finally, imperative languages implements iterations through loops, but can also implement
recursion. In principle, iterations through loops use destructive updates, which make
programs to have side effects. On the other hand, a functional program cannot be iterative

5
because the value of the condition of the loop never differs. Functional languages uses
recursion or explicit calls to other functions i.e. map, to carry out iterative process.

2.4 Efficient and Readability

Bird and Wadler (2014) argue that the use of functional languages allow for greater
extensibility, agility and offer more productive ways of developing software systems, mainly
due to functional programs to be only 12 percent as large as imperative ones. Even though,
this is true in certain problem areas, for other problem areas, functional solutions are 30
percent as large as imperative ones to the similar problems. Nevertheless, the size of a
program code alone is not a good way to determine its efficiency and productivity, as not all
lines of code have same complexity or take the same amount of time to produce. Actually,
because imperative languages utilize variables, imperative programs have many simple lines
of code for initializing or changing variables.

Moreover, another way to compare these two programming paradigms is their execution
efficiency. Generally, interpreted functional programs are much slower than compiled
imperative ones. However, nowadays most functional languages have their own compilers
so their execution speed is not that much slower than the imperative ones. However, it can
be argued that because functional programs are considerably smaller than imperative ones,
they should run much faster than the imperative programs. Nonetheless, this is not the case,
because the functional lazy evaluation has a negative impact on execution efficiency. The
major downside of lazy evaluation is that it makes very difficult to predict memory usage. For
example, two expressions may achieve the same result but they may need different amount
of memory.

Another execution efficiency difference between the two programming paradigms, which
gives imperative languages an advantage, is that they were designed to run efficiently on
von Neumann architecture, whereas, functional languages are designed based on
mathematical functions. However, functional languages have a greater advantage in
readability. The reason is that every function is designed to achieve a particular task given
its argument, whereas, imperative programs, the details of tackling with variables makes
very difficult to understand the logic of the program.

Finally, it is difficult to design and use concurrent execution in imperative languages, and
sometimes it is very complicated process. Because, in imperative programming, the
programmer needs to make separate concurrent parts of the program and then synchronize
their execution. On the other hand, functional languages divide programs into independent
functions, which have no side effects and their operations do not dependent on any global
variables. Consequently, this makes functional programs easier to be executed concurrently

6
and because functions in functional languages preserve immutability, they do not need to be
synchronized.

3 Summary

Most hardware architecture of modern computers is imperative and designed to execute


machine code, which is written in the imperative style. Thus, the state of the programs that
run on the von Neumann architecture is defined by the contents of the memory. Imperative
languages follow the same concept but use variables, assignments and complex statements.
In imperative programming, each step is an instruction, and the memory holds the state. To
manipulate states, imperative languages use assignments to perform operations on values
located in memory and the result is stored in the memory for later use. This allows
Imperative programs to access and modify global variables, which makes imperative
programs very difficult to reason about and understand.

Alternatively, functional programs are much easier to reason about and prove that they are
correct, because their dependence on any data structure is explicit. Additionally, functional
languages use simple expressive expressions and emphasis the evaluation of expressions.
Each expression is evaluated independently, which makes functional languages to have no
side effects, which means that independent sub-expressions can be evaluated in any order
or parallel. Moreover, features such as higher-order functions and the lack of side effects
support creating very efficient and reusable programs. Programs can only interact through
their visible interfaces. Therefore, all phases of program development (i.e. prototyping,
debugging and testing) are made less complex.

7
Reference
Bird, R. Walder, P. (1988) Introduction to Functional Programming. Prentice Hall
International.

Chitil, Olaf. (2000) ‘Functional Programming’, Journal of Functional Programming, pp. 14-20.

Davie, T. (1992) An introduction to functional programming systems using Haskell. New


York, NY: Cambridge University Press.

Douence, R. Tabareau, N. (2014) Lazier Imperative Programming. Project-Teams Ascola.

Fischer, S., Kiselyov, O. Shan, C. (2011) ‘Purely functional lazy nondeterministic


programming’, Journal of Functional Programming, 21(4-5), pp. 413–465.

Fokker, J. (2003) Imperative Programming. Department of Information and Computer


Science. Utrecht University.

Gyori, A. Franklin, L. Dig, D. (2004) Cross the Gap from Imperative to Functional
Programming through Refactoring. Oracle, Czech Republic.

Hartel, P. (1999) ‘Purely functional data structures’, Science of Computer Programming,


34(1), pp. 250-300.

Hughes, John. (1989) Why Functional Programming Matters. Computer Journal, 32(2):98–
107.

Jones, S. Walder, P. (1992) Imperative Functional Programming. Dept of Computer Science,


University of Glasgow.

Kristiansen, L. (2001) ‘The implicit computational complexity of imperative programming


languages’, BRICS Report Series, 8(46).

OKASAKI, C. (2001) ‘Special issue on Algorithmic aspects of functional programming


languages’, Journal of Functional Programming.

Van Roy, P. (1990) Can Logic Programming Execute as Fast as Imperative Programming.

Westbrook, E. Stump, A. Wehrman, I. (2005) A Language-based Approach to Functionally


Correct Imperative Programming. Dept of Computer Science and Engineering. Washington
University.

Vous aimerez peut-être aussi