4. What are the problems?
No (known) medium in space.
No chemicals in space (i.e. no oxygen).
Many more.
One of the biggest:
Speed of Light = speed limit
5. Can we “break” the speed limit?
Sci-Fi authors: “Yes” Scientists: “No!”
10. Further Information
Alcubierre Drive (Wikipedia)
Miguel Alcubierre (Wikipedia)
“The warp drive: hyper-fast travel within
general relativity” - Miguel Alcubierre, 1994
Warp Drive (Wikipedia)
RF resonant cavity thruster (Wikipedia)
22. Amdahl’s Law
Given
●𝑛 ∊ ℕ, the number of threads of execution
●B ∊ [0, 1], strictly serial fraction of algorithm
Time T(𝑛) it takes to finish with n threads is
T(𝑛) = T(1)(B + 1/𝑛 (1 − B))
Therefore, the theoretical speedup S(𝑛) is
S(𝑛) = T(1) / T(𝑛) = 1 / (B + 1/𝑛 (1 - B))
25. Gustafson’s Law
Given a the sequential time, b the parallel time,
P the number of processors,
a + b single thread time
a + P b sequential time
(a + P b) / (a + b) speedup
α = a / (a + b)
sequential fraction S(P):
S(P) = α + P (1 − α) = P − α (P − 1)
28. Alonzo Church (Wikipedia)
John McCarthy (Wikipedia)
John Backus (Wikipedia)
Functional Programming History (Wikipedia)
Some History of Functional Programming Languages (D.
A. Turner)
Gordon Moore (Wikipedia)
Moore’s Law (Wikipedia)
Gene Amdahl (Wikipedia)
Amdahl’s Law (Wikipedia)
John Gustafson (Wikipedia)
Gustafson’s Law (Wikipedia)
History of Functional Programming
References
30. f(x) = 2x + 3
f(2) = 4 + 3 = 7
The value of x will never change inside a mathematical
function.
Same input, same output - all the time!
Call f() multiple times, without any side-effects.
We don’t have to recalculate f(2), replace occurrence of
f(2) with 7 (Referential Transparency)
32. Pure Function
public int calculate(int x) {
return (2 * x) + 3;
}
calculate(2) = 7
calculate(2) = 7
33. public class Account {
int balance;
public Account(int balance) {
this.balance = balance;
}
public int credit(int amount) {
balance = balance + amount;
return balance;
}
}
Account account = new Account(100);
account.credit(500); // → balance == 600
account.credit(500); // → balance == 1100
34. class Account {
final int balance;
public Account(int balance) {
this.balance = balance;
}
public Account credit(int amount) {
return new Account(balance + amount);
}
}
Account account = new Account(100)
Account currentAccountState = account.credit(500)
===> currentAccountState(600)
Account newAccountState = currentAccountState.credit(500)
===> newAccountState(1100)
account.credit(500)
===> currentAccount(600)
35. Modifying global variable / data structure
Modifying input value
Throwing an exception
Read / Write (File, Console, Database)
Communication with External System
Side Effects
36.
37. Thin layer of impure functions
(DB, I/O, exceptions)
Pure functions at the core
38. Why Pure Functions?
No Side-effects
A function f is said to be a “pure function” if
f(x) is “referentially transparent”
Memoization
Execution Order can be rearranged (!)
Local Reasoning
Parallel Execution
public int square (int number) {
return number * number;
}
54. What if you want to reuse A without B?
Dependency Inversion Principle
Component A Component B
55. What if you want to reuse A without B?
Dependency Inversion Principle
Component A Component B
Sort Article
56. What if you want to reuse A without B?
Dependency Inversion Principle
Component A Component B
Sort ArticleComparable
57. Higher Order Functions
Are a form of polymorphism
Serve the Dependency Inversion Principle
Decouple software entities
Make software entities reusable
58. Higher-Order Functions and OO
Higher-Order Functions can always be
expressed using Objects.
Not every expression using Objects is also a
Higher-Order Function.
I recommend to avoid calling methods that
have Methods with side-effects as
parameters or return values “Higher-Order
Functions”.
61. Find Even Numbers
Double it
Sum it up
public int calculate() {
int[] numbers = {1, 5, 10, 9, 12};
List<Integer> doubledEvenNumbers = new ArrayList<>();
for (int number : numbers)
if (number % 2 == 0)
doubleEvenNumbers.add(num * 2);
int total = 0;
for (int even : doubleEvenNumbers)
total = total + even;
return total;
}
Imperative Style
62. Declarative Style
val list = List(1, 5, 10, 9, 12)
val total = list.filter( number => number % 2 == 0)
.map ( evenNumber => evenNumber * 2)
.sum
63. Imperative Paradigm
How to do it
Mutability
Use locking / synchronization for thread safety
Side effects
null values
67. Now listen carefully and learn something
about Git at the same time!
If you do not know
Git internals
68. “All fields final” - even in data structures.
Previous version is preserved.
Modifying data structures actually creates
copies of modified parts, references of
unmodified parts.
Persistent Data Structure
69. Three Levels of Persistence
1.Partially Persistent
Query all versions
Update only latest version
2.Fully Persistent
Query all versions
Update all versions
3.Confluently Persistent
Combinators -> Directed Acyclic Graph
70. Immutable (Persistent) Object
1 class Point {
2 final int x;
3 final int y;
4 Point(final int x, final int y) {
5 this.x = x;
6 this.y = y;
7 }
8 }
71. Persistent Data Structures: List
1 public class ListNode<T> {
2 public final ListNode<T> next;
3 public final T data;
4 public ListNode(final T data) { this(null, data); }
5 public ListNode(final ListNode<T> next, final T data) {
6 this.next = next;
7 this.data = data;
8 }
9 }
74. Persistent Data Structures: Tree
1 public class TreeNode<T> {
2 public final TreeNode<T> left;
3 public final TreeNode<T> right;
4 public final T data;
5 public TreeNode(final T data) {this(null, null, data);}
6 TreeNode(TreeNode<T> left, TreeNode<T> right, T data) {
7 this.left = left;
8 this.right = right;
9 this.data = data;
10 }
11 }
75. Persistent data structure (Wikipedia)
Data Structures (Clojure)
Persistent Data Structures
References
79. int x = 5 * 3;
System.out.println(x);
int x = product(2);
System.out.println(x);
public int product(int num) {
System.out.println("product method");
return num * 3;
}
product method
6
80. Evaluate immediately at the time of
assignment
Call By Value
Call By Reference
Strict Evaluation
81. multiply(true, 10 / 0);
int multiply(boolean flag, int i) {
if (flag)
return 100;
else
return i * 5;
}
// → Division by zero
84. val result = product(true, 10/0)
println(result)
def product(flag: => Boolean, num: => Int) = {
if (flag)
100
else
5 * num
}
// → 100
85. Call By Name (Function Parameters)
Call By Need (Variables)
Call By Need = Lazy Evaluation
Non Strict Evaluation
86. public class Singleton {
private static Singleton instance = null;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
System.out.println("Create new for the first time.");
instance = new Singleton();
}
return instance;
}
public static void main(final String... args) {
Singleton.getInstance();
Singleton.getInstance();
}
}
93. 𝑓 : ℕ0 × ℕ0 → ℕ0
𝑓(𝑥, 𝑦) = 𝑥 + 𝑦
Defined ∀ 𝑥: 𝑥 ∊ ℕ0
⇒ Total Function
Partial Functions in Mathematics
typedef uint32_t u32;
u32 f(u32 x, u32 y)
{
return x + y;
}
94. 𝑓 : ℕ0 × ℕ0 → ℕ0
𝑓(𝑥, 𝑦) = 𝑥 + 𝑦
Defined ∀ 𝑥: 𝑥 ∊ ℕ0
⇒ Total Function
𝑓 : ℕ0 × ℕ0 → ℕ0
𝑓(𝑥, 𝑦) = 𝑥 − 𝑦
Only when 𝑥 ≥ 𝑦
⇒ Partial Function
Partial Functions in Mathematics
typedef uint32_t u32;
u32 f(u32 x, u32 y)
{
return x + y;
}
u32 f(u32 x, u32 y)
{
return x - y;
}
95. Partial Functions in Scala
val isEven: PartialFunction[Int, String] = {
case x if x % 2 == 0 => x + "is even"
}
val isOdd: PartialFunction[Int, String] = {
case x if x % 2 == 1 => x + "is odd"
}
val sample = 1 to 10
val evenNumbers = sample collect isEven
val numbers = sample map (isEven orElse isOdd)
99. float x, y, z;
y = g(x);
z = f(y);
z = f(g(x));
100. “Function Composition” is applying one function to the
results of another.
Haskell
foo = f . g
Scala
val add = (x: Int) => x + 10
val subtract = (x: Int) => x - 5
List(10, 20, 30).map(add and Then subtract)
First Class Composition
102. “Currying is similar to the process of calculating
a function of multiple variables for some given
values on paper.” - Wikipedia
Currying
103. Currying for the poor:
Method Overloading
class Complex {
final double real;
final double imaginary;
Complex(double real, double imaginary) {
this.real = real;
this.imaginary = imaginary;
}
static Complex real(double real) {
return new Complex(real, 0);
}
}
104. Formal Definition of Currying
Given a function f of type f : (X × Y) → Z,
currying it makes a function
curry(f): X → (Y → Z)
That is, curry(f) takes an argument of type X
and returns a function of type Y → Z.
105. Currying in Scala
def add(x: Int, y: Int) = x + y
add(1, 2) // 3
add(7, 3) // 10
def add(x: Int)(y: Int) = x + y
add(1)(2) // 3
add(7)(3) // 10
106. Currying existing Functions
def add(x: Int, y: Int) = x + y
val addCurried = Function.curried(add _)
add(1, 2) // 3
addCurried(1)(2) // 3
115. qsort :: (Ord a) => [a] -> [a]
qsort [] = []
qsort (x:xs) =
let left = qsort [a | a <- xs, a <= x]
right = qsort [a | a <- xs, a > x]
in left ++ [x] ++ right
--or even shorter
qsort (x:xs) =
qsort [a | a <- xs, a <= x]
++ [x] ++
qsort [a | a <- xs, a > x]
Quicksort in Haskell
116. Quicksort in Perl 5
sub qsort {
return @_ if @_ < 2;
my $p = splice @_, int rand @_, 1;
qsort(grep$_<$p,@_), $p,
qsort(grep$_>=$p,@_);
}
117. Quicksort in Scala
def qsort[T](list: List[T])(implicit ev1: T =>
Ordered[T]): List[T] = list match {
case Nil => Nil
case p :: xs =>
val (lesser, greater) = xs partition (_ <=
p)
qsort(lesser) ++ List(p) ++ qsort(greater)
}
121. f(x) = 2x2 - 2x + 3
f(4) = 2*4*4 - 2*4 + 3 = 32 - 14 + 3 = 27
The value of x will never change inside a mathematical
function.
Same input, same output - all the time!
Call f() multiple times, without any side-effects.
We don’t have to recalculate f(4), replace occurrence of
f(4) with 27 (Referential Transparency)
122. public class Account {
int balance;
public Account(int balance) {
this.balance = balance;
}
public int credit(int amount) {
return balance += amount;
}
}
Account account = new Account(100);
account.credit(500); // → balance == 600
account.credit(500); // → balance == 1100
123. public class Account {
final int balance;
public Account(int balance) {
this.balance = balance;
}
public Account credit(int amount) {
return new Account(balance + amount);
}
}
Account account = new Account(100);
Account currentAccountState = account.credit(500);
Account newAccountState = currentAccountState.credit(500);
account.credit(500); // → currentAccount(600)
124.
125.
126. public int calculate() {
int[] numbers = {1, 5, 10, 9, 12};
List<Integer> doubledEvenNumbers = new ArrayList<>();
int total = c;
for (int number : numbers)
if (number % 2 == 0)
total += num * 2;
return total;
}
Imperative Style
127. Declarative Style
public int calculate() {
return IntStream.of(1, 5, 10, 9, 12)
.filter(number -> number % 2 == 0)
.map(number -> number * 2)
.sum();
}
129. public int product(int num) {
System.out.println("product method");
return num * 3;
}
int x = 5 * 3;
System.out.println(x);
x = product(2);
System.out.println(x);
15
product method
6
130. int multiply(boolean flag, int i) {
if (flag)
return 100;
else
return i * 5;
}
System.out.println(multiply(true, 10 / 0));
// → Division by zero
131. public class Singleton {
private Singleton() {
System.out.println("Create new for the first time.");
}
public static Singleton getInstance() {
return LazyHolder.INSTANCE;
}
private static class LazyHolder {
private static final Singleton INSTANCE = new
Singleton();
}
}
132. public class Singleton {
public static final Singleton
INSTANCE = new Singleton();
private Singleton() {
System.out.println("Init");
}
}