4. CHAPTER 1: INTRODUCTION
USAGE IN INDUSTRY
Haskell is the most famous functional language. It is being many big
companies like Facebook, Microsoft, AT&T as internal tools
Erlang / Elixir is the first-class choice for concurrency because of its Actor
Model. It’s most used in telecom industry and chat services (Facebook,
Whatsapp, Discord, Heroku, RabbitMQ, …)
Clojure belongs to LISP family and runs on JVM. It’s being used by CircleCI,
SoundCloud, Groupon, Weebly, , Netflix. Clojure is good for concurrency
with concepts like Persistent Data Structure and Software Transational
Memory
Scala is the solid choice for those who seek comfort in both Functional and
Object Oriented. It’s in use by big companies like: Twitter, Foursquare,
Soundcloud, 9GAG, Tumblr,…
6. CHAPTER 2: PURITY
Functional Languages favors “pure function”
A pure function is a function that:
- Output only depends on Input
- Has no side effects
7. CHAPTER 2: PURITY
examples of
pure functions:
function sayHello(name) {
return "Hello " + name;
}
var name = "Lam";
function sayHello() {
return "Hello " + name;
}
function sayHello() {
return "Hello " + this.name;
}
examples of
impure functions:
8. CHAPTER 2: PURITY
why pure functions matter
Pure function is deterministic, it always returns the same output for the
same input
It’s easy to understand and easy to test
Pure functions can be cached, impure functions cannot
11. CHAPTER 3: FIRST-CLASS FUNCTIONS
In Functional Languages, functions are first-class
- It can be assigned to a variable
- It can be passed into other function
- We can return a function from another function
First-class means that, functions plays an equal role as objects:
12. CHAPTER 3: FIRST-CLASS FUNCTIONS
Functions as objects
<?php
$foo = function() {
return "Hello World";
};
$foo(); // 'Hello world’
call_user_func($foo); // 'Hello world’
const hello = () => 'Hello World';
const foo = hello;
const bar = foo;
bar(); // 'Hello world’
bar.call(); // 'Hello world’
bar.length; // 1
Available in most programming languages
13. CHAPTER 3: FIRST-CLASS FUNCTIONS
Returning a function from a function
function add(number1) {
return function(number2) {
return number1 + number2;
}
}
add(3)(5) // 8
// instead of add(3, 5)
This is called Curry-ing, which is named after Haskell Curry
It helps you to build up function and gives name to those functions
var increment = add(1);
// . . .
// meanwhile, in another code
increment(2) // 3
14. CHAPTER 3: FIRST-CLASS FUNCTIONS
Passing function to another function
const whatToDoToday = (what) => {
return 'I am ' + what() // ‘I am doing TedTalk'
};
const action = random() > 0.5
? () => 'doing TedTalk'
: () => 'doing Nothing';
whatToDoToday(action);
In Javascript, function can be passed into other functions.
15. CHAPTER 3: FIRST-CLASS FUNCTIONS
First-Class Function is so powerful that in most Functional Languages, GoF
Design Patterns do not exist
21. CHAPTER 4: COMPOSITION
Real world example (Functional Haskell way)
let capitalize name = map toUpper name
let sayHello name = "Hello " ++ name
let addExcitement sentence = sentence ++ " !!!!!”
addExcitement . sayHello . capitalize $ "nfq"
-- "Hello NFQ !!!!!"
22. CHAPTER 4: COMPOSITION
Benefits of composition
Avoid naming, one of the hardest things in computer science
Encourage us to writer very small functions that do just one thing
Shorter than traditional method
24. CHAPTER 5: LOOP
In functional languages, we don’t use For loop
In functional languages, everything map and reduce (sometimes recursion)
The first step to learn a functional language is trying not to use loop
WHY?
25. CHAPTER 5: LOOP
1. For loop is usually longer and duplicated (example 1)
var input = [1, 2, 3, 4];
var output = [];
for (var n of input) {
output.push(n + 1);
}
console.log(output); // [2, 3, 4, 5]
var input = [1, 2, 3, 4];
var output = input.map(n => n + 1);
console.log(output); // [2, 3, 4, 5]
26. CHAPTER 5: LOOP
1. For loop is usually longer and duplicated (example 2)
var input = [1, 2, 3, 4];
var output = [];
for (var n of input) {
if (n % 2 === 0) {
output.push(n);
}
}
console.log(output); // [2, 4]
var input = [1, 2, 3, 4];
var output = input.filter(n => n % 2 === 0);
console.log(output); // [2, 4]
27. CHAPTER 5: LOOP
1. For loop is usually longer and duplicated (example 3)
var input = [1, 2, 3, 4];
var result = null;
for (var n of input) {
if (n === 3) {
result = n;
break;
}
}
console.log(result); // 3
var input = [1, 2, 3, 4];
var result = input.find(n => n === 3);
console.log(result); // 3
29. CHAPTER 5: LOOP
2. For loop cannot be run in parallel easily
… because all the threads still refer to the output variable,
and they must run one by one to maintain orders
30. CHAPTER 5: LOOP
3. For loop modifies the output object
… which violates a very important property of
Functional Programming:
Immutability
32. CHAPTER 6: IMMUTABILITY
What is immutability like in OOP languages?
1. Programming without setter methods
2. Everything is initiated once in the constructor
3. Create a new object, always
33. CHAPTER 6: IMMUTABILITY
Reason 1: You can debug easier
var person = new Person({
firstName: 'John',
lastName: 'Doe'
});
person.getFullName();
// null
There are only two
possible places
where I did wrong
In the constructor
In the getter
34. CHAPTER 6: IMMUTABILITY
Reason 1: You can debug easier
var person = new Person();
person.setFirstName('John');
person.setLastName('Doe');
person.getFullName();
// null
There are only four
possible places
where I did wrong
In the constructor
In the setter
In the other setter
In the getter
35. CHAPTER 6: IMMUTABILITY
Reason 2: Temporal Coupling
person.setLastName('Doe');
person.getFullName();
// null
Things get complicated in multi-threaded environment
person.setFirstName('John');
var person = new Person();
THREAD 1 THREAD 2
36. CHAPTER 6: IMMUTABILITY
Reason 2: Temporal Coupling
happens when the orders of execution are dependent on each other
var person = new Person();
person.setFirstName('John');
person.setLastName('Doe');
person.getFullName(); // null
1. You have to remember to call setters before calling getter.
Even if you don't, program stills run, and you get run-time error
2. Your getter functions will now include a lot of if-else
37. CHAPTER 6: IMMUTABILITY
Reason 2: Temporal Coupling
Immutability removes Temporal coupling completely
class Person {
constructor({ firstName, lastName }) {
if (!firstname) throw ...;
if (!lastName) throw ...;
}
getFullName() {
return this.firstName + this.lastName;
}
}
38. THE END
CONCLUSION
▸ Functions in FP languages are first-class: it can be assigned to
variables, can be passed to another functions
▸ Composition helps avoid naming and encourage writing small
functions
▸ We don't use loop, seriously. Map/Reduce can run in parallel
freely and is shorter to write
▸ Immutability is the required in FP language to avoid concurrency
bugs and temporal coupling
▸ Functional programming encourages writing Pure functions