Functional Programming Notes
Functional Programming Notes
topics to cover
Imperative
Functional
Pure function, impure function
Recursive function
Higher order function
Currying
Free and bound variable
Name and value
Applicative order Normal order
Call by name - call by value - call by need
Session and script
Combination function
Advantages of functional programming
Alpha and Beta reduction
Functional Programming 1
✅ What is Functional Programming?
Functional Programming (FP) is a programming paradigm where:
Programs are built using pure functions, avoiding shared state and side
effects, and treating functions as first-class citizens.
🧠 Core Characteristics
1️⃣ Pure Functions
A function is pure if:
Same input → Same output
No side effects (no changing global variables, no printing, no file writing)
Example:
f(x) = x + 2
2️⃣ Immutability
Variables do not change after creation.
Imperative:
x = 5
x = 10 ❌ (state changed)
Functional:
Functional Programming 2
x = 5
y = 10 ✅ (new value)
3️⃣ First-Class Functions
Functions can:
Be assigned to variables
Be passed as arguments
Be returned from other functions
🔹2️⃣
Functional Programming 4
🔹 2️⃣ Impure Function
A function is impure if:
1. ❌ Output depends on external state
2. ❌ It modifies something outside
3. ❌ It has side effects
def add_to_x(y):
return x + y
Why impure?
If x changes, output changes.
Depends on external variable.
Why impure?
It prints (side effect)
Does not just compute and return
Functional Programming 5
Updating database
Changing input data
📌 Example (Python)
✔ Assigned to Variable
def greet(name):
return "Hello " + name
x = greet
print(x("Harsh"))
✔ Passed as Argument
def square(x):
return x * x
print(apply_function(square, 5))
Functional Programming 7
return "Inside"
return inner
📌
Functional Programming 8
📌 Built-in HOFs in Python
map()
filter()
reduce()
Example:
numbers = [1,2,3,4]
result = list(map(lambda x: x*2, numbers))
🔥 Important Difference
First-Class Function Higher-Order Function
Property of language Type of function
Functions treated as values Function that takes/returns function
👉 First-class is a feature
👉 Higher-order is a result of that feature
🧠 Why Important in Functional
Programming?
Because FP relies heavily on:
Abstraction
Code reuse
Composition
Currying
Functional Programming 9
function as an argument or returns a function. Higher-order functions are
possible because functions are first-class citizens in functional programming
languages.
Python Example:
def factorial(n):
if n == 0: # Base case
return 1
Functional Programming 10
else:
return n * factorial(n-1) # Recursive call
How It Works:
If we call:
factorial(3)
It becomes:
3 * factorial(2)
2 * factorial(1)
1 * factorial(0)
Base case:
factorial(0) = 1
Then result:
3 × 2 × 1 × 1 = 6
⚔ Recursion vs Iteration
Functional Programming 11
Recursion Iteration
Function calls itself Uses loops
Needs base case Needs loop condition
Common in FP Common in imperative programming
✅ What is Currying?
Currying is the process of converting a function that takes multiple arguments
into a sequence of functions, each taking one argument.
f (x, y) = x + y
🔹 Curried Version
f (x)(y) = x + y
Functional Programming 12
Here:
First function takes x
🧠 Step-by-Step Understanding
Instead of:
add(2,3)
We do:
add(2)(3)
First:
add(2)
λy. 2 + y
Then:
(λy. 2 + y)(3) = 5
📌 Example in Python
def add(x):
def add_y(y):
return x + y
return add_y
result = add(2)(3)
print(result)
Functional Programming 13
🔥 Why Currying is Important?
Helps in partial application
Increases modularity
Makes function composition easier
Very common in Lambda Calculus
📌 Partial Application
Example:
add5 = add(5)
Now:
add5(3) = 8
add5(10) = 15
Functional Programming 14
programs. It is widely used in lambda calculus and functional programming
languages.
📌 Example 1
λx.x + 1
Here:
x is bound
Because it is declared after λ
📌 Example 2
λx.λy.x + y
Here:
x is bound (by first λ)
y is bound (by second λ)
No free variables here.
Functional Programming 15
🔓 2️⃣ Free Variable
A variable is free if it is NOT declared inside a lambda abstraction.
It has no λ binding it.
📌 Example 3
λx.x + y
Here:
x → Bound
🧠
👉
Important Rule
A variable is bound if it appears inside its corresponding λ scope.
👉 If no λ binds it → it is free.
🔍 Example with Nested Scope
λx.(λy.x + y + z)
Now identify:
x → Bound (by outer λ)
z → Free
📌 What is Scope?
The scope of a bound variable extends to the body of its lambda expression.
Example:
Functional Programming 16
x is bound in entire body
y is bound only inside (λy. y + x)
λx.x → λy.y
✅ What is “Value”?
A value is a final evaluated result.
Examples:
5
True
Functional Programming 17
"Hello"
🔥
👉
Call by Value (CBV)
Argument is evaluated first
👉 Then passed to function
Example
(λx.x + 1)(2 + 3)
Step 1:
Evaluate argument first:
2+3=5
Step 2:
(\lambda x. x + 1) 5
Result:
Functional Programming 18
🔥
👉
Call by Name (CBN)
Argument is NOT evaluated first
👉 Expression is substituted directly
Same example:
(λx.x + 1)(2 + 3)
Step:
Substitute directly:
(2 + 3) + 1
Then evaluate:
🧠 Key Difference
Call by Value Call by Name
Evaluate argument first Do not evaluate first
Faster May recompute
Used in Python, Java Used in lazy languages
Strict evaluation Non-strict evaluation
Call by Value:
First evaluate infinite_loop
Functional Programming 19
Call by Name:
Substitute directly
Since x is never used
Result = 5 ✅
This shows:
👉 Call by Name can terminate even when Call by Value does not.
📌 In Short (Exam Ready Answer)
Call by Value is an evaluation strategy where the argument to a function is
evaluated before being passed to the function. Call by Name is a strategy
where the argument is not evaluated before substitution; instead, the
expression is directly substituted into the function body and evaluated only
when needed.
🔹
👉
1️⃣ Normal Order Evaluation
Also called Call by Name
👉 Evaluate the leftmost outermost expression first
👉 Do NOT evaluate arguments unless necessary
📌 Rule:
Reduce the outer function first, before evaluating arguments.
Example
(λx.5) ((λy.y + 1) 3)
Functional Programming 20
=5
🔹
👉
2️⃣ Applicative Order Evaluation
Also called Call by Value
👉 Evaluate the innermost arguments first
👉 Then apply function
Same Example
(λx.5) ((λy.y + 1) 3)
(λy.y + 1) 3 = 4
Step 2:
(λx.5) 4 = 5
Result = 5
(λx.5) (∞)
Applicative Order:
Try to evaluate infinite loop first ❌
Never terminates
Functional Programming 21
Normal Order:
Apply outer function first
Result = 5 ✅
Terminates
👉 Normal order always finds a result if one exists.
This is a very important exam line.
⚔ Comparison Table
Normal Order Applicative Order
Leftmost outermost reduction Innermost first
Arguments evaluated only if needed Arguments evaluated first
Corresponds to Call by Name Corresponds to Call by Value
May be slower Usually faster
Guaranteed to find normal form if exists May not terminate
🧠 Memory Trick
Normal → "Outer first"
Applicative → "Argument first"
✅
👉
1️⃣ Call by Value (CBV)
Argument is evaluated first
Functional Programming 22
👉 Then passed to the function
Evaluation Style:
Strict / Eager evaluation
📌 Example
(λx.x + 1) (2 + 3)
Step 1:
Evaluate argument:
2+3=5
Step 2:
(λx.x + 1) 5 = 6
✔ Used in:
Python
Java
C
Most imperative languages
✅
👉
2️⃣ Call by Name (CBN)
Argument is NOT evaluated first
👉 Expression is substituted directly
👉 Evaluated only when needed
Same Example
(λx.x + 1) (2 + 3)
Step 1:
Substitute directly:
Functional Programming 23
(2 + 3) + 1
Step 2:
⚠ Important
If argument is used multiple times → it is recomputed multiple times.
Example:
(λx.x + x) (2 + 3)
Call by Name:
(2 + 3) + (2 + 3)
Computed twice.
✅
👉
3️⃣ Call by Need (Lazy Evaluation)
Like Call by Name
BUT
👉 Argument is evaluated only once
👉 Result is stored (memoized)
This avoids repeated computation.
Same Example
(λx.x + x) (2 + 3)
Call by Need:
Step 1:
Store result of (2+3) = 5
Step 2:
5 + 5 = 10
Functional Programming 24
✔ Computed only once.
🔥 Infinite Loop Example (Very Important
for Exam)
(λx.5) (∞)
Call by Value:
Evaluate ∞ first ❌
Never terminates
Call by Name:
Substitute directly
Since x not used → result = 5 ✅
Call by Need:
Same as Call by Name
Also returns 5 ✅
⚔ Comparison Table (Very Important)
Feature Call by Value Call by Name Call by Need
Argument evaluated first? Yes No No
Re-computation possible? No Yes No
Stores result? Yes No Yes
Efficient? Usually Can be slow More efficient
Used in Python, Java Theoretical model Haskell
Functional Programming 25
Need → Lazy + remember result
🔹 Characteristics of Session
Executes line by line
Immediate output
Good for testing
Functional Programming 26
Temporary (variables lost when session ends)
x = 10
y = 20
print(x + y)
python [Link]
🔹 Characteristics of Script
Written in file
Executed as a whole
Permanent storage
Used for real applications
Functional Programming 27
🧠 Why This Matters in Functional
Programming?
In FP learning:
Session is used to test lambda expressions
Script is used to implement functional programs
🔹 Example of a Combinator
λx.x
Functional Programming 28
✔ is bound
x
✔ No free variables
👉 This is a combinator
🔹 Example NOT a Combinator
λx.x + y
Here:
x is bound
y is free ❌
👉 So this is NOT a combinator.
🔥 Important Combinators (Very Common
in Exam)
1️⃣ Identity Combinator (I)
I = λx.x
2️⃣ K Combinator
K = λx.λy.x
K 5 10 = 5
3️⃣ S Combinator
Functional Programming 29
S = λx.λy.λ[Link](yz)
🧠
👉
Important Fact
A program written only using combinators has:
No free variables
No external dependency
Functional Programming 30
✅ Advantages of Functional
Programming
Functional Programming (FP) has several advantages due to pure functions and
immutability.
1️⃣ Predictability
Because of pure functions:
Same input → Same output
No hidden state
No side effects
👉 Makes programs easy to understand and debug.
2️⃣ Easier Testing
Pure functions:
Do not depend on global variables
Do not modify external data
So testing becomes simple.
Example:
If f(5) always gives 10 , testing is straightforward.
⚔ Summary Table
Feature Advantage
Pure functions Predictable behavior
Immutability No unexpected state change
Higher-order functions Reusable and modular code
No side effects Easy debugging
Functional Programming 32
Feature Advantage
Stateless design Safe parallel execution
✅ Disadvantages of Functional
Programming
Although functional programming has many benefits, it also has some
limitations.
4️⃣
Functional Programming 33
4️⃣ Not Always Efficient for I/O
Functional programming avoids side effects, but:
Real-world applications require input/output.
Managing I/O purely can be complicated.
Functional Programming 34
✅ What is Alpha (α) Reduction?
Alpha reduction means:
Renaming a bound variable in a lambda expression.
It does NOT change the meaning of the function.
🔹 Example 1
λx.x
We can rename x to y :
λy.y
✔ Same meaning
✔ Only variable name changed
🔹 Example 2
λx.λy.x + y
Rename outer x to a :
Functional Programming 35
λa.λy.a + y
⚠ Important Rule
You can rename only bound variables.
You cannot rename free variables randomly.
Here:
x is bound → can rename
y is free → cannot rename
Correct alpha reduction:
λz.z + y
Wrong:
λx.x + z
(λx.λy.x) y
If we directly substitute:
λy.y
Functional Programming 36
This changes meaning due to variable capture.
Correct method:
Step 1: Alpha convert inner y
λx.λz.x
λz.y
✔ Correct result
⚔ Alpha vs Beta
Alpha Reduction Beta Reduction
Renames bound variables Applies function
No computation Substitution happens
Avoids variable capture Performs actual evaluation
🧠 General Rule
(λx.E) A
After β-reduction:
E[x := A]
🔹 Simple Example
(λx.x + 1) 5
Substitute x = 5 :
5+1=6
🔹 Example 2
(λx.x × x) 3
Substitute:
3×3=9
🔥 Example 3 (Important)
(λx.x + x) (2 + 3)
After substitution:
Functional Programming 38
(2 + 3) + (2 + 3)
Then evaluate:
5 + 5 = 10
Substitute x = 5 :
λy.5 + y
Substitute:
(λy.y) (λy.y)
λy.y
Functional Programming 40