0% found this document useful (0 votes)
35 views

PPL UNIT-5

Functional programming languages focus on symbolic computation and list processing, emphasizing 'what to solve' rather than 'how to solve'. Key concepts include pure functions, recursion, and immutability, with languages like Haskell and Lisp supporting these paradigms. Advantages include bug-free code and efficient parallel programming, while disadvantages involve potential readability issues and performance concerns.

Uploaded by

upender
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
35 views

PPL UNIT-5

Functional programming languages focus on symbolic computation and list processing, emphasizing 'what to solve' rather than 'how to solve'. Key concepts include pure functions, recursion, and immutability, with languages like Haskell and Lisp supporting these paradigms. Advantages include bug-free code and efficient parallel programming, while disadvantages involve potential readability issues and performance concerns.

Uploaded by

upender
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 21

UNIT-5

PART-1
5.1.1 FUNCTIONAL PROGRAMMING LANGUAGES (FPL)
INTRODUCTION
Functional programming languages are specially designed to handle
symbolic computation and list processing applications. Functional
programming is based on mathematical functions.
Functional programming is a programming language in which we try to
bind everything in pure mathematical functions style. It is a declarative
type of programming style.
Its main focus is on “what to solve” in contrast to an imperative style
where the main focus is “how to solve”.
Functional Programming is based on Lambda Calculus:
Lambda calculus is framework developed by Alonzo Church to study
computations with functions. It can be called as the smallest programming
language of the world. It gives the definition of what is computable.
Anything that can be computed by lambda calculus is computable. It is
equivalent to Turing machine in its ability to compute. It provides a
theoretical framework for describing functions and their evaluation. It
forms the basis of almost all current functional programming languages.
Fact: Alan Turing was a student of Alonzo Church who created Turing
machine which laid the foundation of imperative programming style.
Programming Languages that support functional
programming: Haskell, JavaScript, Scala, Erlang, Lisp, ML, Clojure,
OCaml, Common Lisp, Racket.
Concepts of functional programming:
 Pure functions
 Recursion
 Referential transparency
 Functions are First-Class and can be Higher-Order
 Variables are Immutable
Pure functions:
These functions have two main properties.
 First, they always produce the same output for same arguments
irrespective of anything else.
 Secondly, they have no side-effects i.e. they do modify any
argument or global variables or output something.
Later property is called immutability. The pure functions only result is the
value it returns. They are deterministic. Programs done using functional
programming are easy to debug because pure functions have no side
effect or hidden I/O. Pure functions also make it easier to write

1
parallel/concurrent applications. When the code is written in this style, a
smart compiler can do many things – it can parallelize the instructions,
wait to evaluate results when need them, and memorize the results since
the results never change as long as the input doesn’t change.
example of the pure function:
sum(x, y) // sum is function taking x and y as
arguments
return x + y // sum is returning sum of x and y without
changing them
Recursion:
There are no “for” or “while” loop in functional languages. Iteration in
functional languages is implemented through recursion. Recursive
functions repeatedly call themselves, until it reaches the base case.
example of the recursive function:
fib(n)
if (n <= 1)
return 1;
else
return fib(n - 1) + fib(n - 2);
Referential transparency:
In functional programs variables once defined do not change their value
throughout the program. Functional programs do not have assignment
statements. If we have to store some value, we define new variables
instead. This eliminates any chances of side effects because any variable
can be replaced with its actual value at any point of execution. State of
any variable is constant at any instant.
example:
x = x + 1 // this changes the value assigned to the variable x. So
the expression is not referentially transparent.
Functions are First-Class and can be Higher-Order:
First-class functions are treated as first-class variable. The first class
variables can be passed to functions as parameter, can be returned from
functions or stored in data structures. Higher order functions are the
functions that take other functions as arguments and they can also return
functions.
example:
show_output(f) // fun show_output is declared taking argument f, which
are another fun
f(); // calling passed function
print_gfg() // declaring another function
print("hello gfg");
show_output(print_gfg) // passing function in another function

2
Variables are Immutable:
In functional programming, we can’t modify a variable after it’s been
initialized. We can create new variables – but we can’t modify existing
variables, and this really helps to maintain state throughout the runtime
of a program. Once we create a variable and set its value, we can have
full confidence knowing that the value of that variable will never change.

Characteristics of functional programming languages


The following are Characteristics of functional programming languages,
1. Functional programming languages are designed on the concept of
mathematical functions that use conditional expressions and
recursion to perform computation.
2. Functional programming supports higher-order functions and lazy
evaluation features.
3. Functional programming languages don’t support flow Controls like
loop statements and conditional statements like If-Else and Switch
Statements. They directly use the functions and functional calls.
4. Like OOP, functional programming languages support popular
concepts such as Abstraction, Encapsulation, Inheritance, and
Polymorphism.

Advantages of functional programming languages


Functional programming offers the following advantages −
1. Bugs-Free Code − Functional programming does not support state,
so there are no side-effect results and we can write error-free codes.
2. Efficient Parallel Programming − Functional programming languages
have NO Mutable state, so there are no state-change issues. One
can program "Functions" to work parallel as "instructions". Such
codes support easy reusability and testability.
3. Efficiency − Functional programs consist of independent units that
can run concurrently. As a result, such programs are more efficient.
4. Supports Nested Functions − Functional programming supports
Nested Functions.
5. Lazy Evaluation − Functional programming supports Lazy Functional
Constructs like Lazy Lists, Lazy Maps, etc.
Disadvantages of functional programming languages:
1. Sometimes writing pure functions can reduce the readability of
code.
2. Writing programs in recursive style instead of using loops can be bit
intimidating.
3. Writing pure functions are easy but combining them with rest of
application and I/O operations is the difficult task.
4. Immutable values and recursion can lead to decrease in
performance.

3
Applications:
1. It is used in mathematical computations.
2. It is needed where concurrency or parallelism is required.
3. The main domain of functional programming language is Artificial
Intelligence. This knowledge is used for building expert systems,
knowledge representation, machine learning, natural language
processing, modelling speech ad vision.

5.1.2 MATHEMATICAL FUNCTIONS


 A mathematical function is a mapping of members of one set, called
the domain set, to another set, called the range set. A function
definition specifies the domain and range sets, either explicitly or
implicitly, along with the mapping.
 The mapping is described by an expression or, in some cases, by a
table. A function yields an element of the range set.
 One of the fundamental characteristics of mathematical functions is
that the evaluation order of their mapping expressions is controlled
by recursion and conditional expressions, rather than by the
sequencing and iterative repetition that are common to the
imperative programming languages.
 Another important characteristic of mathematical functions is that
because they have no side effects and cannot depend on any
external values, they always map a particular element of the
domain to the same element of the range.
 A mathematical function maps its parameter(s) to a value (or
values), rather than specifying a sequence of operations on values
in memory to produce a value.
Simple Functions:
 Function definitions are often written as a function name, followed
by a list of parameters in parentheses, followed by the mapping
expression. For example,
cube(x) K x * x * x, where x is a real number
 In this definition, the domain and range sets are the real numbers.
The symbol K is used to mean “is defined as.” The parameter x can
represent any member of the domain set, but it is fixed to represent
one specific element during evaluation.

4
 Function applications are specified by pairing the function name
with a particular element of the domain set. Every occurrence of a
parameter is bound to a value from the domain set and is a
constant during evaluation. For example, consider the following
evaluation of cube(x): cube (2.0) = 2.0 * 2.0 * 2.0 = 8
 The parameter x is bound to 2.0 during the evaluation and there are
no unbound parameters. Furthermore, x is a constant (its value
cannot be changed) during the evaluation.
 A lambda expression specifies the parameters and the mapping
of a function. The lambda expression is the function itself, which is
nameless. For example, consider the following lambda expression:
(x)x * x * x
 Church defined a formal computation model (a formal system for
function definition, function application, and recursion) using
lambda expressions. This is called lambda calculus. Lambda
calculus can be either typed or untyped.
 Application of the example lambda expression is denoted as in the
following example:
((x)x * x * x)(2) which results in the value 8.
 Lambda expressions, like other function definitions, can have more
than one parameter.
Functional Forms:
A higher-order function, or functional form, is one that either takes
one or more functions as parameters or yields a function as its result, or
both. Two common mathematical functional forms provided by the
schema are:
1. function composition is a functional form that takes two functions
as parameters and yields a function whose value is the first actual
parameter function applied to the result of the second actual
parameter function. For example -Function composition is written as
an expression, using ° as an operator, as in h K f g.
For example, if
f(x) K x + 2
g(x) K 3 * x
then h is defined as
h(x) K f(g(x)), or h(x) K (3 * x) + 2
2. Apply-to-all is a functional form that takes a single function as a
parameter and yields a list of values obtained by applying the given
function to each element of a list of parameters. As an example of
the use of map, suppose we want all of the elements of a list cubed.
Consider the following example:
Let h(x) K x * x

5
Then (h, (2, 3, 4)) yields (4, 9, 16)
We can accomplish this with the following –
(map (LAMBDA (num) ( num num num)) '(2 3 5))
This call returns (8 27 125).

5.1.3 FUNDAMENTALS OF FUNCTIONAL PROGRAMMING LANGUAGES


 The objective of the design of a functional programming language is
to mimic mathematical functions to the greatest extent possible.
This results in an approach to problem solving that is fundamentally
different from approaches used with imperative languages.
 In an imperative language, an expression is evaluated and the result
is stored in a memory location, which is represented as a variable in
a program.
 A program in an assembly language often must also store the
results of partial evaluations of expressions. For example, to
evaluate (x + y)/(a - b) the value of (x + y) is computed first. That
value must then be stored while (a - b) is evaluated. The compiler
handles the storage of intermediate results of expression
evaluations in high-level languages. The storage of intermediate
results is still required, but the details are hidden from the
programmer.
 A purely functional programming language does not use variables or
assignment statements, thus freeing the programmer from concerns
related to the memory cells, or state, of the program. The execution
of a function always produces the same result when given the same
parameters. This feature is called referential transparency.
 A functional language provides a set of primitive functions, a set of
functional forms to construct complex functions from those primitive
functions, a function application operation, and some structure or
structures for representing data.
 These structures are used to represent the parameters and values
computed by functions. If a functional language is well defined, it
requires only a relatively small number of primitive functions.

5.1.4 THE FIRST FUNCTIONAL PROGRAMMING LANGUAGE: LISP


Many functional programming languages have been developed. The
oldest and most widely used is LISP (or one of its descendants), which was
developed by John McCarthy at MIT in 1959. It is high level programming
language. It was first implemented by Steve Russell on an IBM 704
computer.
Features of LISP:
1. It is based on expressions. The prefix notations are used to
represent the expression.

6
2. It has advanced object-oriented features.
3. It has got automatic garbage collection. Hence the programmer
need not have to explicitly free the dynamically allocated memory.
4. A strong support for recursion in programs. Due to this feature this
language is widely used and accepted in artificial intelligence.
5. All computation is performed by applying functions to arguments.
Variable declarations are rarely used.
Applications of LISP:
Lisp is mainly used in-
1. Artificial intelligence robotics
2. 2. Computer games
3. Pattern recognition
4. Real time embedded systems
5. List handling and processing
6. For creating applications for educational purpose.
7. For List handling and processing.
Data Types and Structures:
There were only two categories of data objects in the original LISP: atoms
and lists. Atoms and lists are not types in the sense that imperative
languages have types.
 Atoms: All the expression in LISP are made up of list. Atoms are
either symbols, in the form of identifiers, or numeric literals. Space
separate elements of a list are known as ATOMS. Some examples of
atoms are:
name
123
xyz
 Lists: Lists are specified in LISP by delimiting their elements with
parentheses. The elements of simple lists are restricted to atoms,
as in (A B C D). Nested list structures are also specified by
parentheses. For example, the list (A (B C) D (E (F G) ) ) is a list of
four elements. The first is the atom A; the second is the sublist (B C); the
third is the atom D; the fourth is the sublist (E (F G)), which has as its
second element the sublist (F G).
List elements are pairs, where the first part is the data of the
element, which is a pointer to either an atom or a nested list. The
second part of a pair can be a pointer to an atom, a pointer to another
element, or the empty list. Elements are linked together in lists with the
second parts. Internally, a list is usually stored as linked list structure in
which each node has two pointers, one to reference the data of the
node and the other to form the linked list. A list is referenced by a
pointer to its first element.

7
The internal representations of our two example lists are shown in
below

Internal representation of two LISP lists


The First LISP Interpreter:
 The original intent of LISP’s design was to have a notation for
programs that would be as close to Fortran’s as possible, with
additions when necessary. This notation was called M-notation, for
meta-notation.
 The first requirement for the universal LISP function was a notation
that allowed functions to be expressed in the same way data was
expressed.
 Function calls were specified in a prefix list form originally
called Cambridge Polish, as in the following:
(function_name argument1 c argumentn)
 For example, if + is a function that takes two or more numeric
parameters, the following two expressions evaluate to 12 and 20,
respectively:
(+ 5 7)
(+ 3 4 7 6)
 The binding of functions to names so that functions could be
referenced by other functions and by themselves.
 This name binding was specified by a list consisting of the function
name and a list containing the lambda expression, as in
(function_name (LAMBDA (arg1 … argn) expression))
 LISP functions specified in this new notation were called S-
expressions, for symbolic expressions. Eventually, all LISP
structures, both data and code, were called S-expressions. An S-
expression can be either a list or an atom. We will usually refer to S-
expressions simply as expressions.

8
 Another feature of early LISP systems that was apparently
accidental was the use of dynamic scoping. Functions were
evaluated in the environments of their callers. Dynamic scoping was
used for most dialects of LISP before 1975.
Expression in LISP:
 The expressions are represented using the operands and operators.
Note that the prefix expression (that is operator operand! operand2)
is required for the evaluation of expression.
>(+10 >(*(+23) (+56))
20) 55
30
 If we do not want to evaluate an expression but want to print the
entire expression then the quote operator or' is used. For example
> (quote (+ 10 20))
(+10 20)
 The eval operator is used to evaluate an expression.
For instance
> (eval (+ 10 20))
30
Define Function in LISP:
The operator defun is used to define the procedure/function. The syntax
of procedure writing in LISP is
defun (proc_name(argument1 argument2)
body of procedure)
For example - procedure for addition of two numbers is as follows -
>(defun mysum(a b)
(+ a b))
Now we can use this procedure the way we want.
> (mysum 2 3)
5
Ex1: Procedure for calculate cube of number in LISP:
>(defun cube(a) (*(*a a)* a))
Output
> (cube 5)
125
Ex2: Procedure to display sum of Squares:
> (defun square(x)(xx))
> (defun sum-of-square(start end)
(if(> start end)
0
(+(square start) (sum-of-square(+ 1 start) end))
))

9
Output
> (sum-of-square 1 5)
55
Ex3: Procedure to Display the number and Its value after
incrementing It by 10:
>(defun myfun(n) (print n) (+ n 10))
Output
> (myfun 10)
10 20
DEFPARAMETER AND SETF IN LISP:
defparameter: The variable can be defined using defparameter. For
example
> (defparameter a 10)
A
When we type the variable name on the prompt then we get the value
assigned to it. It is as shown below-
>a
10

Setf: The setf is used to change the value of the variable. The setf will
make global variables.
> (self a 100) // changing the value of a from 10 to 100
100
>a // simply testing whether a=100 or not
100
>(+ a 10) // performing some operation with the changed value
110

Lambda Function in LISP:


The lambda function is used to define a function which returns some
value. The syntax of this function is
(lambda (parameters) Body)
For example- >((lambda (xy) (*xy)) 10 20)
200
Similarly we can assign a value to a function by the return value of some
function.
>(define (add n) (lambda (x) (+ x y))) add
>((add 10) 20) it returns 30.
Here we have defined the function add which returns an object of type
function.
Structure of list in LISP:
A list can be represented as follows
The list is enclosed within the brackets. The elements in the list are
separated by space.

10
(10 20 30)
The list containing no item is called the empty list. On entering the empty
li it will return the value NIL.
>()
NIL
Using the word list we can also create a list.
> (list 10 20 30)
(10 20 30)

List Manipulation Functions:


There are various functions that can be used for manipulation of lists.
1. Length: The length of empty list is 0. We can find out the length of the
list as follows-
(length (10 20 30 40 50))
5
We can also create a definition of length function follows-
> (define (length x)
(cond ((null? x) 0)
(else (+1(length (cdr x)))))
2. Append : The append is used to add the element in the list at the end.
For example
> (append (10 20 30) '(40 50))
(10 20 30 40 50)
We can also create a definition of append function as follows-
> (define (append x z)
(cond ((null? x) z)
(else (cons (car x) (append (cdr x) z)))))
3. Map: The map is basically applied to a function. Using map we can
extend the function from elements to list. Map returns a list of the results
of applying the function to elements taken from each list. For example
>(map abs '(1-2 3-4-5))
(1 2 3 4 5)
(map + (1 2 3) (4 5 6))
(5 7 9)
Thus map can handle more than one list.
4. Association Lists: An association list or a list for short, records a
mapping from keys to values. Using assoc we can obtain the most recent
binding of key to value. For example - following assoc returns the
appropriate values for the specified keys.
>(assoc 'one '((one 1) (two 2) (one 3)))
(ONE 1)
Another example
(assoc 'age '((name aa) (age 30) (salary 10000)))

11
(AGE 30)

LISP Functions:
One of the more common uses of the LISP-based programming languages
is list processing. This subsection introduces the Scheme functions for
dealing with lists. Suppose we have a function that has two parameters,
an atom and a list, and the purpose of the function is to determine
whether the given atom is in the given list. Neither the atom nor the list
should be evaluated; they are literal data to be examined. To avoid
evaluating a parameter, it is first given as a parameter to the primitive
function QUOTE, which simply returns it without change. The following
examples illustrate QUOTE:
(QUOTE A) returns A
(QUOTE (A B C)) returns (A B C)
the common abbreviation of the call to QUOTE is used, which is done
simply by preceding the expression to be quoted with an apostrophe (').
Thus, instead of (QUOTE (A B)), '(A B) will be
used.
CDR: The cdr returns rest of the list after the first element is removed. It
is pronounced as could- (CDR '(1 2 3 4)) returns (234)
(CDR '(A B C)) returns (B C)
(CDR '((A B) C D)) returns (C D)
(CDR 'A) is an error
(CDR '(A)) returns ()
(CDR '()) is an error
CAR: The car returns first element of a non-empty list. For example
(CAR '(1 2 3 4)) returns 1
(CAR '(A B C)) returns A
(CAR '((A B) C D)) returns (A B)
(CAR 'A) is an error because A is not a list
(CAR '(A)) returns A
(CAR '()) is an error
CONS: We can combine two lists using cons. The cons function takes two
arguments and returns a new cons cell containing the two values.
Following are example calls to CONS:
(CONS 10 (20 30 40)) returns (10 20 30 40)
(CONS 'A '()) returns (A)
(CONS 'A '(B C)) returns (A B C)
(CONS '() '(A B)) returns (() A B)
(CONS '(A B) '(C D)) returns ((A B) C D)

 CAR and CDR take a list apart, and CONS constructs a new list from
given list parts. The two parameters to CONS become the CAR and CDR
of the new list. Thus, if a_list is a list, then
(CONS (CAR a_list) (CDR a_list))
returns a list with the same structure and same elements as a_list
apply CONS to two atoms, although that is legal. The result of such an

12
application is a dotted pair, so named because of the way it is
displayed by Scheme.
For example, consider the following call:
(CONS 'A 'B)
If the result of this is displayed, it would appear as (A . B)
This dotted pair indicates that instead of an atom and a pointer or a
pointer and a pointer, this cell has two atoms.
 LIST is a function that constructs a list from a variable number of
parameters. It is a shorthand version of nested CONS functions, as
illustrated in the following:
(LIST 'apple 'orange 'grape) returns (apple orange
grape)
Using CONS, the call to LIST above is written as follows:
(CONS 'apple (CONS 'orange (CONS 'grape '())))

Conditional Statements in LISP:


The conditions can be specified using if. The syntax of writing if is
(if(conditional expression) (true-expression) (false expression))
The true-expression part will be executed only if the condition specified
in condition expression is true, otherwise the false expression part will
be executed.
For example
if(>10 20) 10) output is NIL
As 10>20 is false and there is no false expression, NIL will be returned.
We will change the above expression as follows-
>(if (>10 20) 10 20)
Returns 20
We can have nested if statement. The example is as shown below-
>(if(= 10 10) (if(>51) 51))
Returns 5
If we want to display a series of expression on the if condition then these
expressions are represented by a block. For this block progn is used.
progn can take any number of expressions, and evaluates each of its
expressions in order. progn then returns the value of the last expression.

Output:
“Hello"
"Welcome"

13
on-quoting in LISP:
The quoting is used for evaluation of expression. Quoting is used to treat
expressions as data. The symbol ' is used to represent the variable.
For example-
>pi
3.14159
But the
>(quote pi)
or
>'pi
will return pi

LET:
 LET is a function that creates a local scope in which names are
temporarily bound to the values of expressions. These names can then
be used in the evaluation of another expression, but they cannot be
rebound to new values in LET.
 The following example illustrates the use of LET. It computes the roots
of a given quadratic equation, assuming the roots are real. The
mathematical definitions of the real (as opposed to complex) roots of
the quadratic equation ax2 + bx + c are as follows:
root1 = (-b + sqrt(b2 - 4ac))/2a and root2 = (-b -
sqrt(b2 - 4ac))/2a

This example uses LIST to create the list of the two values that make up
the result.
LET construct:
The syntax of Let construct is as follows -
(let ((varl vall) (var2 val2).. (var valn)), last_val)
Where varl, var2, ..vara are variable names and vall, val2, .. valn are the
initial values assigned to the respective variables.
When let is executed, each variable is assigned the respective value and
lastly the s-expression is evaluated.
The value of the last expression evaluated is returned.
(let (x=2, y=3, z=x+y) print(x + y + z))
This will return 10
14
Factorial of a given number:
(defun factorial (n)
(let ((f 1)) // initialising f=1
(dotimes (x n) // repeating the following block for n times
(setff(*f (1+x)))) //f=f'(x+1)
f)) // returns the value of f each time.

Output
> (factorial 5)
120

Common LISP:
Common LISP (Steele, 1990) was created in an effort to combine the
features of several early 1980s dialects of LISP, including Scheme, into a
single language. Being something of a union of languages, it is quite large
and complex, similar in these regards to C++ and C#. Its basis, however,
is the original LISP, so its syntax, primitive functions, and fundamental
nature come from that language.
Following is the factorial function written in Common LISP:
(DEFUN factorial (x)
(IF (<= n 1)
1
(* n factorial (− n 1)))
))
Only the first line of this function differs syntactically from the Scheme
version of the same function.
The list of features of Common LISP is long:
 a large number of data types and structures, including records,
arrays, complex numbers, and character strings.
 powerful input and output operations and a form of packages for
modularizing collections of functions and data, and also for
providing access control.
 Common LISP includes several imperative constructs, as well as
some mutable types.

Scoping rules in LISP:


 Lexical scope: The names of parameters to a function normally
are lexically scoped.
 Indefinite scope: That means references may occur anywhere, in
any program.
 Dynamic extent: References may occur at any time in the interval
between establishment of the entity and the explicit
disestablishment of the entity. For example: the with-open-file

15
construct opens a connection to a file and creates a stream object
to represent the connection.
 Indefinite extent : The entity continues to exist as long as the
possibility of reference remains. For example- most Common Lisp
data objects have indefinite extent.

SUPPORT FOR FUNCTIONAL PROGRAMMING IN PRIMARILY IMPERATIVE


LANGUAGES:
Imperative programming languages have always provided only limited
support for functional programming. One indication of the increasing
interest and use of functional programming is the partial support for it
that has begun to appear over the last decade in programming languages
that are primarily imperative. For example, anonymous functions, which
are like lambda expressions, are now part of JavaScript, Python, Ruby, and
C#.
In JavaScript, named functions are defined with the following syntax:
function name (formal-parameters)
{
body
}
 C# supports lambda expressions that have a different syntax than
that of C# functions. For example, we could have the following:
i => (i % 2) == 0
This lambda expression returns a Boolean value depending on
whether the given parameter (i) is even (true) or odd (false). C#’s
lambda expressions can have more than one parameter and more
than one statement.
 Python’s lambda expressions define simple one-statement
anonymous functions that can have more than one parameter. The
syntax of a lambda expression in Python is exemplified by the
following:
lambda a, b : 2 * a – b
Note that the formal parameters are separated from function body
by a colon.
 In Python, strings, lists, and tuples are considered sequences.
Consider the following example of using the map function in Python:
map(lambda x: x ** 3, [2, 4, 6, 8])
This call returns [8, 64, 216, 512].
 Python also supports partial function applications. Consider the
following example:

16
from operator import add
add5 = partial (add, 5)
 The from declaration here imports the functional version of the
addition operator, which is named add, from the operator module.
After defining add5, it can be used with one parameter, as in the
following: add5 (15), This call returns 20.

A COMPARISON OF FUNCTIONAL AND IMPERATIVE LANGUAGES:


 Functional languages can have a very simple syntactic structure. The
list structure of LISP, which is used for both code and data, clearly
illustrates this. The syntax of the imperative languages is much more
complex. This makes them more difficult to learn and to use. The
semantics of functional languages is also simpler than that of the
imperative languages.
 Functional languages have a potential advantage in readability. In
many imperative programs, the details of dealing with variables
obscure the logic of the program. Consider a function that computes
the sum of the cubes of the first n positive integers. In C, such a
function would likely appear similar to the following:
int sum_cubes(int n)
{ int sum = 0;
for(int index = 1; index <= n; index++) sum += index *
index * index;
return sum;
}
In Haskell, the function could be: sumCubes n = sum (map (^3)
[1..n])
This version simply specifies three steps:
1. Build the list of numbers ([1..n]).
2. Create a new list by mapping a function that computes the cube
of a number onto each number in the list.
3. Sum the new list.
Because of the lack of details of variables and iteration control, this
version is more readable than the C version.

Imperative language Functional language


An imperative language uses a The functional language treats
sequence of statements to everything as a function. They does
determine how to reach a certain not have a state associated with
goal. These statements help to them.
change the state of the program as
they get executed.

17
The values can be assigned to some The values are returned from the
variable in imperative languages. functions depending upon the input
given to that function.
The order of execution is very The order of execution is of low
important in imperative languages. importance in functional languages.
The control flow is manipulated by The control flow is manipulated by
conditional statements, loops, functional calls including recursion.
function or method calls.
Examples of imperative languages Examples of functional languages
are C, Java, Python, Ruby, JavaScript are LISP, Haskell, ML and so on.
and so on.

OTHER IMPORTANT QUESTIONS FOR EXAM


HASKELL:
 Haskell is purely functional programming language.
 It has lazy evaluation technique i.e. the expression is not getting
evaluated until it is bound to a variable.
 The language support static type checking. All the values in Haskell
have a type which is determined at compile time. That means that a
lot of possible type errors are caught at compile time.
 The Haskell make use of functions to define the offside rule using
equation. The lexical analyzer handles these offside rules efficiently.
 It makes use of List comprehension technique to represent the list
of elements. The list comprehension means building more specific
set from the general set. For example, Consider that we want a set

denoted as S = {2*xx ∈ N, x≤ 10}


of first 10 natural even numbers then mathematically it can be

This will give the list of elements as [2,4,6,8,10].


 It supports the pattern matching. Pattern matching is a technique in
which the pattern is specified and some data is confirmed to it. Then
it is ensured if data behaves according to those patterns or not.
 An active and growing community exists for this language.

Scoping rule in Haskell:


 Haskell makes use of static scope rule.
 For example -

18
let c = 21 in
let cTimes = \x ->c*x in
let c = 5 in
cTimes 2
The result will be 42(21*2) as it uses static scope rule.

Functions Used in Haskell:


 Since Haskell is a functional language, one would expect functions
to play a major role, and indeed they do.
 It supports curried function.
 Currying is actually a process of transforming a function that takes
multiple arguments into a function that takes just one argument and
returns another function if any arguments are still needed.
 For example - sum 1 2 3 is applied then actually it is transformed as
((sum 1) 2) 3. Putting a space between two things is simply function
application. The space is sort of like an operator and it has the
highest precedence.
 In short, by sum 1 2 3, the function sum I is created, it returns a
function. So when 2 is applied to that it creates a function that will
take a parameter and add it by 3. When 3 is applied to that function
the result will be 6. Hence the code for this function could be
sum :: (Num a) => a -> a->a->a sum x y z = x+y+z
 Another example can be given by a map function of Haskell: Cosider
a function add which can be defined as
add ::Integer->Integer->Integer
add x y =x+y
Now the map function can be defined as
map =(a->b)-> [a] -> [b]
mapf [] =[]
map f (x:xs) = fx: map f xs
Then we can show that –
map (add 1) [1,2,3] => [2,3,4]
This denotes that the function add can be passed as a parameter to
map function. This is also an example of higher order function.
Examples on Haskell codes:
 Finding factorial of given number:
factorial 0 = 1
factorial 1 = 1
factorial n = n*factorial(n-1)
 Finding Fibonacci number at a given position.
fib 0 = 1
fib 1=1.
fib n |n>=2

19
=fib(n-1)+fib(n-2)
ML:
 ML (Milner et al., 1990) is a static-scoped functional programming
language, like Scheme.
 Function declarations in ML appear in the general form:
fun function_name(formal parameters) = expression;
When called, the value of the expression is returned by the function.
Actually, the expression can be a list of expressions, separated by
semicolons and surrounded by parentheses. The return value in this
case is that of the last expression.
 Consider the following ML function declaration:
fun circumf(r) = 3.14159 * r * r;
 This specifies a function named circumf that takes a floating-point
(real in ML) argument and produces a floating-point result.
 The ML selection control flow construct is similar to that of the
imperative languages. It has the following general form:
if expression then then_expression else else_expression
The first expression must evaluate to a Boolean value.
 The conditional expressions of Scheme can appear at the function
definition level in ML. In ML, the computation performed by a
function can be defined for different forms of the given parameter.
This feature is meant to mimic the form and meaning of conditional
function definitions in mathematics.

Scoping in ML:
 The scoping rule used in ML is called lexical scoping, because names
refer to their nearest preceding lexical (textual) definition.
 For example - if f() returns 12, then let val x = f() in x * x end is an
expression that evaluates to 144, using a temporary variable named
x to avoid calling f() twice.

DIFFERENCES BETWEEN HASKELL AND ML:


Haskell ML

Haskell is pure, without side ML has mutable data


effects or exceptions. structures such as references
and arrays.
Haskell has lazy evaluation ML has strict evaluation.

Haskell functions are curried. ML uses tuple or record


arguments for multi- argument
functions.
Haskell has minimal calculator ML syntax is heavier.

20
style syntax.
For example - The function type For example - The function
can be described as type can be described as
f:: Bool-> Int fun f (b:bool):
fb = if b then 1 else 0 int =if b then 1 else 0

21

You might also like