66
ROME 27-28 march 2015 functional programming you already know @KevlinHenney

Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

Embed Size (px)

Citation preview

Page 1: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

ROME 27-28 march 2015

functional programming

you already know

@KevlinHenney

Page 2: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Page 3: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Page 4: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Page 5: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Page 6: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

functional

programming

higher-order functions

recursion

statelessness

first-class functions

immutability

pure functions

unification

declarative

pattern matching

non-strict evaluation

idempotence

lists

mathematics

lambdas currying

monads

Page 7: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

Excel is the world's most popular functional language.

Simon Peyton Jones

Page 8: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

To iterate is human,

to recurse divine.

L Peter Deutsch

Page 9: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

int factorial(int n)

{

int result = 1;

while(n > 1)

result *= n--;

return result;

}

Page 10: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

int factorial(int n)

{

if(n > 1)

return n * factorial(n - 1);

else

return 1;

}

Page 11: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

int factorial(int n)

{

return

n > 1

? n * factorial(n - 1)

: 1;

}

Page 12: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

n! = 1

(n – 1)! n

if n = 0,

if n > 0. {

Page 13: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

n! =

n

k = 1

k

Page 14: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

seriesProduct(k, k, 1, n)

Page 15: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

reduce(

int.__mul__,

range(1, n+1), 1)

Page 16: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

reduce(

lambda l, r: l*r,

range(1, n+1), 1)

Page 17: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Page 18: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Page 19: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Page 20: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

#include <stdio.h>

/* printd: print n in decimal */

void printd(int n)

{

if (n < 0) {

putchar('-');

n = -n;

}

if (n / 10)

printd(n / 10);

putchar(n % 10 + '0');

}

Page 21: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Page 22: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

/* grep: search for regexp in file */

int grep(char *regexp, FILE *f, char *name)

{

int n, nmatch;

char buf[BUFSIZ];

nmatch = 0;

while (fgets(buf, sizeof buf, f) != NULL) {

n = strlen(buf);

if (n > 0 && buf[n-1] == '\n')

buf[n-1] = '\0';

if (match(regexp, buf)) {

nmatch++;

if (name != NULL)

printf("%s:", name);

printf("%s\n", buf);

}

}

return nmatch;

}

/* matchhere: search for regexp at beginning of text */

int matchhere(char *regexp, char *text)

{

if (regexp[0] == '\0')

return 1;

if (regexp[1] == '*')

return matchstar(regexp[0], regexp+2, text);

if (regexp[0] == '$' && regexp[1] == '\0')

return *text == '\0';

if (*text!='\0' && (regexp[0]=='.' || regexp[0]==*text))

return matchhere(regexp+1, text+1);

return 0;

}

/* match: search for regexp anywhere in text */

int match(char *regexp, char *text)

{

if (regexp[0] == '^')

return matchhere(regexp+1, text);

do { /* must look even if string is empty */

if (matchhere(regexp, text))

return 1;

} while (*text++ != '\0');

return 0;

}

/* matchstar: search for c*regexp at beginning of text */

int matchstar(int c, char *regexp, char *text)

{

do { /* a * matches zero or more instances */

if (matchhere(regexp, text))

return 1;

} while (*text != '\0' && (*text++ == c || c == '.'));

return 0;

}

Page 23: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

int atexit(void (*func)(void));

Page 24: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

void qsort(

void *base,

size_t nmemb, size_t size,

int (*compar)(

const void *, const void *));

Page 25: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

void (*signal(

int sig, void (*func)(int)))(int);

Page 26: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

Use procedure arguments to provide

flexibility in an interface.

This technique can greatly simplify

an interface, eliminating a jumble of

parameters that amount to a small

programming language.

Butler W Lampson

"Hints for Computer System Design"

Page 27: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

public class HeatingSystem

{

public void turnOn()

public void turnOff()

}

public class Timer

{

public Timer(TimeOfDay toExpire, Runnable toDo)

public void run()

public void cancel()

}

Page 28: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

Timer on =

new Timer(

timeToTurnOn,

new Runnable()

{

public void run()

{

heatingSystem.turnOn();

}

});

Timer off =

new Timer(

timeToTurnOff,

new Runnable()

{

public void run()

{

heatingSystem.turnOff();

}

});

Page 29: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

class Timer

{

public:

Timer(TimeOfDay toExpire, function<void()> toDo);

void Run();

void Cancel();

...

};

Page 30: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

Timer on(

timeOn,

bind(&HeatingSystem::TurnOn, &heatingSystem));

Timer off(

timeOff,

bind(&HeatingSystem::TurnOff, &heatingSystem));

Page 31: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

public class Timer

{

public Timer(TimeOfDay toExpire, Action toDo) ...

public void Run() ...

public void Cancel() ...

...

}

Page 32: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

Timer on = new Timer(timeOn, heatingSystem.TurnOn);

Timer off = new Timer(timeOff, heatingSystem.TurnOff);

Page 33: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

Timer on = new Timer(timeOn, heatingSystem::turnOn);

Timer off = new Timer(timeOff, heatingSystem::turnOff);

Page 34: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

Timer on =

new Timer(timeOn, () => heatingSystem.TurnOn());

Timer off =

new Timer(timeOff, () => heatingSystem.TurnOff());

Page 35: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

Timer on =

new Timer(timeOn, () -> heatingSystem.turnOn());

Timer off =

new Timer(timeOff, () -> heatingSystem.turnOff());

Page 36: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

Timer on(

timeOn, [&]() { heatingSystem.TurnOn(); });

Timer off(

timeOff, [&]() { heatingSystem.TurnOff(); });

Page 37: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

William Cook, "On Understanding Data Abstraction, Revisited"

Page 38: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

newStack = (let items = ref()

{ isEmpty = #items = 0,

depth = #items,

push = x items := xˆitems,

top = items0

})

Page 39: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

var newStack = function() {

var items = []

return {

isEmpty: function() {

return items.length === 0

},

depth: function() {

return items.length

},

push: function(newTop) {

items = items.unshift(newTop)

},

top: function() {

return items[0]

}

}

}

Page 40: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Page 41: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

One of the most powerful mechanisms

for program structuring [...] is the block

and procedure concept.

A procedure which is capable of giving

rise to block instances which survive its

call will be known as a class; and the

instances will be known as objects of

that class.

A call of a class generates a new object

of that class.

Ole-Johan Dahl and C A R Hoare

"Hierarchical Program Structures"

Page 42: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

Concatenative programming is so called because it uses function composition instead of function application—a non-concatenative language is thus called applicative.

Jon Purdy http://evincarofautumn.blogspot.in/2012/02/

why-concatenative-programming-matters.html

Page 43: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

f(g(h(x)))

Page 44: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

(f ○ g ○ h)(x)

Page 45: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

x h g f

Page 46: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

h | g | f

Page 47: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

This is the basic reason Unix pipes are so powerful: they form a rudimentary string-based concatenative programming language.

Jon Purdy http://evincarofautumn.blogspot.in/2012/02/

why-concatenative-programming-matters.html

Page 48: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Page 49: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

find . -name "*.java" | sed 's/.*\///' | sort | uniq -c | grep -v "^ *1 " | sort -r

Heinz Kabutz "Know Your IDE"

97 Things Every Programmer Should Know

Page 50: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

Concurrency

Page 51: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

Concurrency

Threads

Page 52: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

Concurrency

Threads

Locks

Page 53: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

Some people, when confronted with a problem, think, "I know, I'll use threads," and then two they hav erpoblesms.

Ned Batchelder https://twitter.com/#!/nedbat/status/194873829825327104

Page 54: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

public class Date implements ... { ... public int getYear() ... public int getMonth() ... public int getDayInMonth() ... public void setYear(int newYear) ... public void setMonth(int newMonth) ... public void setDayInMonth(int newDayInMonth) ... ... }

Page 55: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

public class Date implements ... { ... public int getYear() ... public int getMonth() ... public int getWeekInYear() ... public int getDayInYear() ... public int getDayInMonth() ... public int getDayInWeek() ... public void setYear(int newYear) ... public void setMonth(int newMonth) ... public void setWeekInYear(int newWeek) ... public void setDayInYear(int newDayInYear) ... public void setDayInMonth(int newDayInMonth) ... public void setDayInWeek(int newDayInWeek) ... ... }

Page 56: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

public final class Date implements ... { ... public int getYear() ... public int getMonth() ... public int getWeekInYear() ... public int getDayInYear() ... public int getDayInMonth() ... public int getDayInWeek() ... ... }

Page 57: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

When it is not necessary to change, it is necessary not to change.

Lucius Cary

Page 58: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

public final class Date implements ... { ... public int getYear() ... public int getMonth() ... public int getWeekInYear() ... public int getDayInYear() ... public int getDayInMonth() ... public int getDayInWeek() ... ... }

Page 59: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

public final class Date implements ... { ... public int year() ... public int month() ... public int weekInYear() ... public int dayInYear() ... public int dayInMonth() ... public int dayInWeek() ... ... }

Page 60: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

Mutable

Immutable

Unshared Shared

Unshared mutable data needs no synchronisation

Unshared immutable data needs no synchronisation

Shared mutable data needs synchronisation

Shared immutable data needs no synchronisation

Page 61: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Page 62: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

Instead of using threads and shared memory

as our programming model, we can use

processes and message passing. Process here

just means a protected independent state

with executing code, not necessarily an

operating system process.

Russel Winder "Message Passing Leads to Better Scalability in Parallel Systems"

Page 63: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. It can be done in Smalltalk and in LISP. There are possibly other systems in which this is possible, but I'm not aware of them.

Alan Kay

Page 64: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

Languages such as Erlang (and occam before

it) have shown that processes are a very

successful mechanism for programming

concurrent and parallel systems. Such

systems do not have all the synchronization

stresses that shared-memory, multithreaded

systems have.

Russel Winder "Message Passing Leads to Better Scalability in Parallel Systems"

Page 65: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Page 66: Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015

http://xkcd.com/224/

We lost the documentation on quantum mechanics.

You'll have to decode the regexes yourself.