Functional Programming
Easy parts
https://slides.com/salamaashoush/fp-easy
I think the lack of reusability comes in object-oriented languages, not functional languages. Because the problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.
Joe Armstrong, creator of Erlang, on software reusability

A monad is just a monoid in the category of endofunctors.
Functional programmer:
(noun) One who names variables "x", names functions "f", and names code patterns "zygohistomorphic prepromorphism"
Agenda
-
What is a function?
-
First-class Functions
-
Pure functions
-
Curried functions
-
Composing functions
-
Point-free style
-
Naming Games
-
WHY?
function sayHello(){
const name = prompt("what is your name?");
if(name === "salama"){
alert("Hello boss");
}else{
alert(`Hello ${name}`);
}
}// f(x) = x + 1
// addOne :: Int -> Int
function addOne(x){
return x + 1
}Functions
are a mapping from an input to an output
First-class Functions
We can treat functions like any other data type and there is nothing particularly special about them — they may be stored in arrays, passed around as function parameters, assigned to variables, etc.
const hi = name => `Hi ${name}`; // as a normal value
const greeting = name => hi(name); // returned from a function// callbacks
const getServerStuff = callback => ajaxCall(json => callback(json));
// same as above
const getServerStuff = ajaxCall;Pure Functions
A pure function is a function that, given the same input, will always return the same output and does not have any observable side effects
const xs = [1,2,3,4,5];
// impure
xs.splice(0,3); // [1,2,3]
xs.splice(0,3); // [4,5]
// pure
xs.slice(0,3); // [1,2,3]
xs.slice(0,3); // [1,2,3]
// impure
const minimum = 21;
const checkAge = age => age >= minimum;
// pure
const checkAge = (age) => {
const minimum = 21;
return age >= minimum;
};Side effects may include, but are not limited to
- changing the file system
- inserting a record into a database
- making an http call
- mutations
- printing to the screen / logging
- obtaining user input
- querying the DOM
- accessing system state
Side Effects
Curried Functions
currying is the concept of calling a function with fewer arguments than it expects
const add = x => y => x + y;
const increment = add(1);
const addTen = add(10);
increment(2); // 3
addTen(2); // 12in languages like
but in javascript you have to do it manually this is possible in javascript because of first-class functions, recursion
function curry(fn) {
const arity = fn.length;
return function $curry(...args) {
if (args.length < arity) {
return $curry.bind(null, ...args);
}
return fn.call(null, ...args);
};
}
const match = curry((what, s) => s.match(what));
const replace = curry((what, replacement, s) => s.replace(what, replacement));
const filter = curry((f, xs) => xs.filter(f));
const map = curry((f, xs) => xs.map(f));the curried function is the concept that
Function Composition
mixing more than one small function to make a bigger one

const toUpperCase = x => x.toUpperCase();
const exclaim = x => `${x}!`;
// this one
const shout = x => toUpperCase(exclaim(x))
// is the same as
const shout = x => exclaim(toUpperCase(x))
shout('send in the clowns'); // "SEND IN THE CLOWNS!"// compose is the same as pipe
// the difference is the order of calling functions
// compose from right to left
// pipe from left to right
function compose(...fns) {
const n = fns.length;
return function $compose(...args) {
let $args = args;
for (let i = n - 1; i >= 0; i -= 1) {
$args = [fns[i].call(null, ...$args)];
}
return $args[0];
};
}const head = x => x[0];
const reverse = reduce((acc, x) => [x].concat(acc), []);
const last = compose(head, reverse);
last(['jumpkick', 'roundhouse', 'uppercut']); // 'uppercut'Point-free style
means functions that never mention the data upon which they operate. First class functions, currying, and composition all play well together to create this style.
point === argument
// not pointfree because we mention the data: word
const snakeCase = word => word.toLowerCase().replace(/\s+/ig, '_');
// pointfree
const snakeCase = compose(replace(/\s+/ig, '_'), toLowerCase);// not pointfree because we mention the data: name
const initials = name => name.split(' ').map(compose(toUpperCase, head)).join('. ');
// pointfree
const initials = compose(join('. '), map(compose(toUpperCase, head)), split(' '));
initials('hunter stockton thompson'); // 'H. S. T'Naming Game
const Box = x =>({
map: ƒ => Box(ƒ(x)),
fold: ƒ => ƒ(x),
inspect: ()=> `Box(${x})`
})
const nextChar = str =>
Box(str)
.map(s=>s.trim())
.map(s => parseInt(s))
.map(i=>i+1)
.map(i => String.fromCharCode(i))
.fold(c=>c.toLowerCase())
const result = nextChar(' 64 ')
[1,2,3].map(x => x +1) // [2,3,4]const Sum = x =>({
x,
concat: ({x:y}) => Sum(x+ y),
inspect: ()=> `Sum(${x})`,
empty: ()=> Sum(0)
})
const All = x =>({
x,
concat: ({x:y}) => All(x && y),
inspect: ()=> `All(${x})`,
empty: ()=> All(true)
})
const result = Sum().empty().concat(Sum(1).concat(Sum(2)))
const result = All().empty().concat(All().concat(All(true)))
[].concat([1,2,3]).map(x => x+1) //[2,3,4]
"" + "Salama" === "Salama"
0 + 5 === 5const Box = x =>({
x,
chain: ƒ => ƒ(x), // sometime it called join, flatmap or bind
map: ƒ => Box(ƒ(x)),
fold: ƒ => ƒ(x),
inspect: ()=> `Box(${x})`,
})
Box().empty().map(x => x+1).chain(x => console.log(x))
Promise.resolve()
.then(getValuesFromServer)
.then((values)=> console.log(values))A monad is just a monoid in the category of endofunctors.
Why?
-
Declarative
-
Pure functions are easier to reason about
-
Testing is easier
-
Debugging is easier
-
Programs are more bulletproof
-
Parallel/concurrent programming is easier
NEXT
?
Functional programming the easy parts
By Salama Ashoush
Functional programming the easy parts
- 126