# DA FUNC

`@gypsydave5     @deniseyu21`

A quick-and-dirty intro to FP

## Stuff we're gonna talk about

2. FP Language Features
3. Show me how this damn thing works!
4. Dave explains why you should care
5. Questions?

# Imperative

Telling the computer how to do something

``````dogs_called_erik = [];

for (i = 0, i < dogs.length, i += 1) do
if dogs[i].name == 'Erik'
dogs_called_erik.push dogs[i]
end
end``````

# Declarative

Tell the computer what to do, but not how to do it

``````SELECT * FROM dogs
WHERE dogs.name = 'Erik'``````

In modern programming languages,
imperative and declarative are relative terms

# Object Orientation

"I thought of objects being like biological cells and/or individual computers on a network, only able to communicate with messages... I wanted to get rid of data."

Alan Kay, creator of Smalltalk

## Methods are ways for objects to communicate.

``````class Dog
def initialize(name)
@name = name
end

def name
@name
end

def rename(new_name)
@name = new_name
end

def woof
"Woof!"
end
end
``````

# Functional

## Key differences from OO

• No objects
• No messages
• Lots of functions
• Much data
• Wow

Functional programming only needs two things:

data and functions.

# ["dave" "denise" "josh"]

``````{
"languages": {
"object-oriented": [
"ruby",
"smalltalk"
],
"functional": [
"clojure"
]
}
}``````

# f(x) = x + 1

y = f(x), where f(x) = x + 1

```function woof (name) {

return "Woof " + name + "!";

}```

# 1. First class functions

Not just a really, really fancy function.

• ## returned by other functions

### In languages without first-class functions, it's hard to get a reference to a function without calling it.

``````def say_hello
"hello!"
end

say_hello

# "hello!"

# no, stupid Ruby! tell me what 'say_hello' is``````

## OO languages like Ruby and Java  get around this with lambdas

``````say_hello = lambda { "hello!" }

say_hello

# <Proc:0x007ff9b2a59138@(irb):1 (lambda)>

say_hello.call

# "hello!"``````

## In languages with first-class functions, the default behaviour is to REFERENCE, notcall functions.

``````function yo () {
return "yo!";
}

yo

// [Function: yo]

yo()

// "yo!"``````

# 2. Referential transparency

## Functions can always be replaced with their results without changing overall behaviour.

Because

``````// so if

function sum (a, b) {
return a + b;
}

sum(1, sum(2, 3))

// is the same as

sum(1, 5)``````

## Let's see some contrived examples...

``````function sum (a, b) {
const n = Math.random();

if (n < 0.5) {
return a + b;
} else {
return 'wtf';
}
}

sum(3, sum(1, 2))

// Maths only works sometimes here``````
``````let counter = 0;

function next (number) {
counter++;

return number + counter;
}

next(1); // 2
next(1); // 3
next(1); // 4``````

# 3. Functional purity

Not just a really, really innocent function.

## Return what you mean, and nothing more!

``````let mutableVar = '';

function emitDirtyState () {
mutableVar += 'blah ';
return mutableVar;
}``````

This is impure:

``````function emitDirtyState () {
console.log("I'm a side effect");
return "yo";
}``````

This is impure:

``````function emitDirtyState () {
someNewGlobalVar = "wahoo!";
return "wtf?!?";
}

// you laugh, but this
// has been done before``````

This is REALLY impure:

# 4. Higher-order functions

## You've already done this if you've written a block in Ruby

``````cats = ["Felix", "Tom", "Puss in Boots", "Garfield"]

cats.map { |cat| cat.upcase }

// now JS!

cats.map(function(cat) { return cat.toUpperCase() })``````

# Show me how this damn thing works!

## Without fp principles, modifying behaviour of existing functions can be really tedious

``````// Suppose you have this amazing code

return a + b;
}``````

## Product owner decides that the user will only ever be adding 3. always.

``````// new code for new requirements

return a + 3;
}``````
``````// old code

return a + b;
}``````

## Product owner decides, actually, user will need to add 5 instead of 3. but definitely only 5, and always 5!

``````// new code for new requirements

return a + 5;
}``````
``````// old code

return a + 3;
}``````

## A brief recap:

``````function addTwoTogether (a, b) {
return a + b;
}

// Great, but we only ever want to add 3

return a + 3;
}

// JK, requirements change, now let's add 5, definitely

return a + 5;
}

// User didn't like it, add 10 now... and so on and so on...
// and maybe more requirements change later
// shit, if only we had a way to automate this like the
// lazy-ass programmers we are.....``````

# no, not that kind

(just in case you didn't know)

``````// A simple arity-of-2 curry function

function curryTwoInputs (fun) {
return function (a) {
return function (b) {
return fun (a, b);
}
}
}``````

## A few libraries like Lodash and Rambda have helper functions do to this

``````var _ = require('lodash');

return a + b;
}

// We can define new ones without manually writing a new function

``````

# Functional composition

``````Remember maths class?

f(x) = 2x

g(x) = x + 3

h(x) = f(g(x))

h(1) = f(g(1)) = f(4) = 8``````

## Most of the time, composed Functions get evaluatedright to left (inner to outer)

``````(defn add
[a b]
(+ a b))

``````// a simple arity-of-2 compose

function simpleCompose(fun1, fun2) {
return function (x) {
return fun1(fun2(x))
}
}``````

## once again, lots of great functional js helper libraries here

``````var _ = require('ramda');

addTwo(2) // => 4 ... remember this guy?

// We can toss functions together arbitrarily now

``````var addFiveThenSeven = simpleCompose(addFive, addSeven);

# 4. Dave rants for a while

``````def log_formatter(log)
log.group_by do |entry|
entry[:time]
end.values.map do |entries_by_time|
entries_by_time.reduce(:merge)
end
end``````

By Denise Yu

• 2,168