A novel exploration of symbolic transformations across discrete domains
Every good wizard knows;
if you have the name of a spirit,
you have power over it.
clojure
js
scala
java
python
λ
recursion
lambdas
symbols
atoms
recursion
λ what is fp ?
a style of building the structure and elements of computer programs that treats computation as the evaluation of mathematical functions and avoids state and mutable data
... DUH
λ why ?
powerful
expressive
fun
referential transparency
closure
lambda
side-effect
higher order function
currying
flatmap
fold
functor
reactive
combinators
metaprogramming
lazy evaluation
macro
monad
bind
parametric types
variadic
immutability
map inputs to outputs
that's it...
an impure function
# borrowed from garrett smith: http://vimeo.com/97337252
def new_array(element, array=[]):
"""create an array with a starting element"""
array.append(element)
return array
In [3]: new_array(1)
Out[3]: [1]
In [4]: my_array = new_array(2)
In [5]: my_array.append(3)
In [6]: my_array
Out[6]: [1, 2, 3]
# python mutable metaprogramming for the wat
In [7]: new_array(1)
Out[7]: [1, 2, 3, 1]
a pure function
;; thanks clojure
(defn new-array
"create an array with a starting element"
([element] (new-array element [])
([element array] (conj array element)))
(new-array 1)
; => [1]
(conj (new-array 2) 3)
; => [2 3]
(new-array 1)
; => [1]
the same inputs always return the same outputs
and many more...
imperative
functional
declarative
Collections in Java
class JavaExample {
List<Integer> incrementedList(List<Integer> numbers) {
for (int i = 0; i < numbers.size(); i++) {
numbers.set(i, numbers.get(i) + 1);
}
return numbers;
}
List<Integer> incrementedList(List<Integer> numbers) {
List<Integer> result = new ArrayList<Integer>();
for (Integer num : numbers) {
result.add(num + 1);
}
return result;
}
}
(initialization; termination; iteration) vs. (for : each)
val inc = { x: Int => x + 1 }
val incrementedList = { xs: Iterable[Int] => xs.map(inc) }
var nums = [ 1, 2, 3, 4, 5, 6];
function even(x) {
return x % 2 == 0;
}
nums.filter(even);
// => [ 2, 4, 6 ]
Collections in JavaScript
gang of HOF
(def up-to-ten (range 10))
up-to-ten
; => (0 1 2 3 4 5 6 7 8 9)
(reduce + up-to-ten)
; => 45
(reductions + up-to-ten)
; => (0 1 3 6 10 15 21 28 36 45)
Understanding Reduce
variously called fold, collect, or inject
The call is coming from inside the code!
function reduce(fn, xs, init) {
var result = init;
xs.each(function(x) {
result = fn(result, x);
});
return result;
}
function map(fn, xs) {
return reduce(function(accumulated, element) {
return conj(accumulated, fn(element));
}, xs, []);
}
function filter(fn, xs) {
return reduce(function(accumulated, element) {
return fn(element) ?
conj(accumulated, element) :
accumulated;
}, xs, []);
}
Building Blocks
function Person(name, age) {
return {
name: name,
age: age
};
}
var brothers = [
new Person("Thomas", 25),
new Person("Eric", 16)
];
map(function(person) {
return person["name"];
}, brothers);
function get(attribute) {
return function(obj) {
return obj[attribute];
};
}
map(get("age"), brothers);
map(get("name"), brothers);
Defining "pluck"
pluck("age", brothers);
// => [ 25, 16 ];
function pluck(attribute, xs) {
map(get(attribute), xs);
}
Inverting filter
reject(even, range(10));
// is the same as:
filter(odd, range(10));
// even and odd are complementary functions
function complement(fn) {
// returns the complement of a given function
return function(x) {
return ! f(x);
}
}
function reject(fn, xs) {
return filter(complement(fn), xs);
}
def factorial(n, accumulation=1):
if n == 1:
# terminal case
return accumulation
else:
# inductive case
return factorial(n-1, accumulation*n)
def fibonacci(n):
if n < 2:
# terminal case
return n
else:
# inductive case
return fibonacci(n-1) + fibonacci(n-2)
Simple examples...
def whoops(n):
if n == 0:
# terminal case
return "yay!"
# these cases take us further away!
elif n > 0:
return whoops(n + 1)
else:
return whoops(n - 1)
Parallel Processing
Divide and conquer!
# count all the words in hdfs
sentences = spark.textFile("hdfs://...")
word_counts = sentences.flatMap(lambda line: line.split(" "))
.map(lambda word: (word, 1))
.reduceByKey(lambda a, b: a + b)
let spark distribute your functions
Functional UIs
// from: https://gist.github.com/jordwalke/6350319
var PeopleList = React.createClass({
render: function() {
var friends = this.props.friends;
var followers = this.props.followers;
return div({className: 'list'},
// data pipeline to transform a collection into dom nodes
friends.concat(followers)
.filter(function(person) {return person.isFavorite;})
.sort(function(one, two) {return one.followCount - two.followCount;})
.slice(0, 10)
.map(function(person) {
return div({className: person.isVerified ? 'star' : 'gray'}, person.name);
})
);
}
});
functional, immutable dom
lazy sequences
generics
thinking with types
Has functional programming gone too far?