(Using Python)
Software Engineer at Pesto Tech
@salman_arfat
Presented at PyDelhi
Life is too short for imperative programming
-- John Hughes (One of the designers of Haskell)
Main Programming Paradigms
A paradigm describes distinct concepts or thought patterns some scientific discipline.
uses statements that change a program's state.
The most common way (informal) way to understand imperative programs is as instruction sequences to a von Neumann Computer
Given a numeric string, get the next character that comes after it.
There's a strong correspondence between
Problem: How can we avoid conceptualising programs words by word?
treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data.
It's a paradigm of programming where fundamental operation is the application of functions to arguments.
class QuickSort
{
int partition(int arr[], int low, int high)
{
int pivot = arr[high];
int i = (low-1); // index of smaller element
for (int j=low; j<high; j++)
{
if (arr[j] <= pivot)
{
i++;
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
int temp = arr[i+1];
arr[i+1] = arr[high];
arr[high] = temp;
return i+1;
}
void sort(int arr[], int low, int high)
{
if (low < high)
{
int pi = partition(arr, low, high);
sort(arr, low, pi-1);
sort(arr, pi+1, high);
}
}
}
FP combines the flexibility and power of abstract mathematics with the intuitive clarity of abstract mathematics.
-- xkcd
There are many possible answers to this question, but generally speaking:
total = 0;
for (i = 1; i <= 10; ++i)
total = total+i;
sum [1..10]
A side effect is any application state change that is observable outside the called function other than its return value. Side effects include:
A function is called higher-order if it takes a function as an argument or returns a function as a result.
The Map Function
The higher-order library function called map applies a function to every element of a list.
map :: (a -> b) -> [a] -> [b]
> map (+1) [1,3,5,7]
[2,4,6,8]
def nextCharFromNumberString(numStr):
trimmed = numStr.strip()
number = int(trimmed)
number = number + 1
return chr(number)
result = nextCharFromNumberString(' 64 ')
print(result)
def nextCharFromNumberString2(numStr):
return map(
chr,
map(
lambda num: num + 1,
map(
lambda stripped: int(stripped),
map(
lambda string: string.strip(),
[numStr]
)
)
)
)
def findColor(name):
colors = {
'red': '#ff4444',
'blue': '#3b5998',
'yellow': '#fff68f'
}
return colors.get(name)
Either = Right || Left
Enforce a null check with composable code branching using Either
Either doesn't actually come into play. It will just refer to one of these two types.
Usually, we don't know if we have a Right or a Left. We don't know which one it is.
class Left:
def __init__(self, x):
self.x = x
def map(self, f):
return Left(self.x)
def fold(self, f, _):
return f(self.x)
def __str__(self):
return 'Left(%s)' % self.x
class Right:
def __init__(self, x):
self.x = x
def map(self, f):
return Right(f(self.x))
def fold(self, _, g):
return g(self.x)
def __str__(self):
return 'Right(%s)' % self.x