monads & gonads douglas crockford. functional programming programming with functions

61
Monads & Gonads Douglas Crockford

Upload: brittany-swafford

Post on 31-Mar-2015

228 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

Monads & GonadsDouglas Crockford

Page 2: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

Functional Programming

Programming with functions.

Page 3: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

FORTRAN II (1958)

FUNCTION name(parameters)

COMMON ...

name = expression

RETURN

END

Page 4: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

First Class Functions

Higher Order Functions

Lexical Closure

Page 5: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

Pure Functional Programming

More mathematical.

Page 6: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

Functions as maps

Page 7: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

Memoization

Caching

Page 8: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

Programming without side-effects.

Remove assignment, loops (use recursion instead), freeze all array literals and object literals.

Remove Date and Math.random.

Page 9: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

In the real world, everything changes.

Immutability makes it hard to interact with the world.

Page 10: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

Monads

A loophole in the function contract.

Page 11: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

In order to understand monads, you need to first

learn Haskell and Category Theory.

Page 12: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

In order to understand monads, you need to first

learn Haskell and Category Theory.

In order to understand burritos, you must first learn

Spanish.

Page 13: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

(M t) → (t → M u) → (M u)

Not tonight, Josephine.

Page 14: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

…you must first learn JavaScript

function unit(value)

function bind(monad, function (value))

All three functions return a monad.

Page 15: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

Axioms

bind(unit(value), f) ==== f(value)

bind(monad, unit) ==== monad

bind(bind(monad, f), g) ====

bind(monad, function (value) { return bind(f(value), g);})

Page 16: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

bind(monad, func)

monad.bind(func)

The OO transform.

Page 17: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

function MONAD() { return function unit(value) { var monad = Object.create(null); monad.bind = function (func) { return func(value); }; return monad; };}

Context Coloring

Page 18: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

function MONAD() { return function unit(value) { var monad = Object.create(null); monad.bind = function (func) { return func(value); }; return monad; };}

Macroid

Page 19: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

function MONAD() { return function unit(value) { var monad = Object.create(null); monad.bind = function (func) { return func(value); }; return monad; };}

var identity = MONAD();var monad = identity("Hello world.");monad.bind(alert);

Page 20: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

Axioms

unit(value).bind(f) ==== f(value)

monad.bind(unit) ==== monad

monad.bind(f).bind(g) ==== monad.bind(function (value) { return f(value).bind(g);})

Page 21: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

Axioms

bind(bind(monad, f), g)

monad.bind(f).bind(g)

Page 22: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

The Ajax Monad

monad.bind(f).bind(g)

Page 23: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

Interstate (2001)

new Interform('text') .moveTo(100, 100) .setSize(400, 32) .moveInside() .setBgColor('pink') .select() .setZIndex(20000) .on('escapekey', 'erase');

Page 24: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

ADsafe (2007)

var input = dom.q("input_text") .on('enterkey', function (e) { dom.q('#ROMAN_RESULT') .value(roman(input .getValue())); input .select(); }) .focus();

Page 25: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

monad.bind(func)

monad.bind(func, [ a, b, c ])

monad.method()

monad.method(a, b, c)

Page 26: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

monad.bind(func)

monad.bind(func, [ a, b, c ])

monad.method()

monad.method(a, b, c)

Page 27: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

function MONAD() { var prototype = Object.create(null); function unit(value) { var monad = Object.create(prototype); monad.bind = function (func) { return func(value); };

return monad; }

return unit;}

Page 28: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

function MONAD() { var prototype = Object.create(null); function unit(value) { var monad = Object.create(prototype); monad.bind = function (func, args) { return func.apply(undefined, [value].concat(Array.prototype .slice.apply(args || []))); }; return monad; }

return unit;}

Page 29: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

function MONAD() { var prototype = Object.create(null); function unit(value) { var monad = Object.create(prototype); monad.bind = function (func, args) { return func(value, ...args)); }; return monad; }

return unit;}

Page 30: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

function MONAD() { var prototype = Object.create(null); function unit(value) { var monad = Object.create(prototype); monad.bind = function (func, args) { return func(value, ...args)); }; return monad; }

unit.method = function (name, func) { prototype[name] = func; return unit; }; return unit;}

Page 31: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

function MONAD() { var prototype = Object.create(null); function unit(value) { var monad = Object.create(prototype); monad.bind = function (func, args) { return func(value, ...args)); }; return monad; }

unit.lift = function (name, func) { prototype[name] = function (...args) { return unit(this.bind(func, args)); }; return unit; }; return unit;}

Page 32: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

var ajax = MONAD() .lift('alert', alert);

var monad = ajax("Hello world.");

monad.alert();

Page 33: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

null

Null Pointer Exception

Page 34: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

Maybe

NaN

Page 35: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

function MONAD(modifier) { var prototype = Object.create(null); function unit(value) { var monad = Object.create(prototype); monad.bind = function (func, args) { return func(value, ...args)); }; if (typeof modifier === 'function') { modifier(monad, value); } return monad; } return unit;}

Page 36: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

var maybe = MONAD(function (monad, value) { if (value === null || value === undefined) { monad.is_null = true; monad.bind = function () { return monad; }; }});

var monad = maybe(null);monad.bind(alert);

Page 37: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

Our Friend the Monad

The Identity MonadThe Ajax Monad

The Maybe Monad

Page 38: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

Concurrency

Threads are evil.

Page 39: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

Turn Based Processing

• Single-threaded. Race free. Deadlock free.

• The Law of Turns: Never wait. Never block. Finish fast.

• Events. Message passing. Threads. Mutexs.

• Web browsers.

• Most UI frameworks.

• Servers: Elko, Twisted, Nodejs.

• Asynchronicity can be hard to manage.

Page 40: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

Promises

• Promises are an excellent mechanism for managing asynchronicity.

• A promise is an object that represents a possible future value.

• Every promise has a corresponding resolver that is used to ultimately assign a value to the promise.

• A promise can have one of three states: 'kept', 'broken', or 'pending'.

Page 41: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

Promises

• A promise is an event generator. It fires its event when the value of the promise is ultimately known.

• At any time after the making the promise, event handling functions can be registered with the promise, which will be called in order with the promise’s value when it is known.

Page 42: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

Promises

• A promise can accept functions that will be called with the value once the promise has been kept or broken.

• promise.when(success, failure) returns another promise for the result of your success function.

Page 43: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

Make a vow

var my_vow = VOW.make();

.keep(value)

.break(reason)

.promise

.when(kept, broken)

Page 44: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

Filesystem API

read_file(name) .when(function success(string) { ... }, failure);

Page 45: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

Exceptions

• Exceptions modify the flow of control by unwinding the state.

• In a turn based system, the stack is empty at the end of every turn.

• Exceptions cannot be delivered across turns.

• Broken promises can.

Page 46: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

Breakage flows to the end

my_promise .when(success_a) .when(success_b) .when(success_c, failure);

success_a gets the value of my_promisesuccess_b gets the value of success_asuccess_c gets the value of success_bunless any promise breaks: failure gets the reason

Page 47: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

Composition

f() .when(function (f_value) { return g(f_value); }) .when(function (g_value) { ... })

==== f() .when(function (f_value) { return g(f_value) .when(function (g_value) { ... }); })

Page 48: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

A promise is a monad

• The value is not known when the monad is made.

• Each promise is linked to two resolver functions, keep and break, that determine the promise’s success and value.

• when can take two functions, bind only one.

Page 49: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

var VOW = (function () {

// function enlighten...

return { make: function make() { ... } };})();

Page 50: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

var VOW = (function () {

// function enlighten...

return { make: function make() { ... } };})();

Dog balls

Page 51: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

var VOW = (function () { // function enlighten...

return { make: function make() { ... } };}());

Page 52: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

make: function make() { var breakers = [], fate, keepers = [], status = 'pending';

// function enqueue here... // function herald here...

return { break: function (reason) { herald('broken', reason, breakers); }, keep: function (value) { herald('kept', value, keepers); }, promise: { ... } };}

Page 53: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

promise: { is_promise: true, when: function (kept, broken) { var vow = make(); switch (status) { case 'pending': enqueue('keep', kept, vow); enqueue('break', broken, vow); break; case 'kept': enqueue('keep', kept, vow); enlighten(keepers, fate); break; case 'broken': enqueue('break', broken, vow); enlighten(breakers, fate); break; } return vow.promise; }}

Page 54: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

make: function make() { var breakers = [], fate, keepers = [], status = 'pending';

// function enqueue here... // function herald here...

return { break: function (reason) { herald('broken', reason, breakers); }, keep: function (value) { herald('kept', value, keepers); }, promise: { ... } };}

Page 55: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

function enqueue(resolution, func, vow) { var queue = resolution === 'keep' ? keepers : breakers; queue[queue.length] = typeof func !== 'function' ? vow[resolution] : function (value) { try { var result = func(value); if (result && result.is_promise === true) { result.when(vow.keep, vow['break']); } else { vow.keep(result); } } catch (e) { vow['break'](e); } };}

Page 56: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

function herald(state, value, queue) { if (status !== 'pending') { throw "overpromise"; } fate = value; status = state; enlighten(queue, fate); keepers.length = 0; breakers.length = 0;}

Page 57: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

function enlighten(queue, fate) { queue.forEach(function (func) { setImmediate(func, fate); });}

https://github.com/douglascrockford/monad

Page 58: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

var VOW = (function () { function enlighten(queue, fate) { queue.forEach(function (func) { setImmediate(func, fate); }); } return { make: function make() { var breakers = [], fate, keepers = [], status = 'pending'; function enqueue(resolution, func, vow) { var queue = resolution === 'keep' ? keepers : breakers; queue[queue.length] = typeof func !== 'function' ? vow[resolution] : function (value) { try { var result = func(value); if (result && result.is_promise === true) { result.when(vow.keep, vow['break']); } else { vow.keep(result); } } catch (e) { vow['break'](e); } }; } function herald(state, value, queue) { if (status !== 'pending') { throw "overpromise"; } fate = value; status = state; enlighten(queue, fate); keepers.length = 0; breakers.length = 0; } return { break: function (reason) { herald('broken', reason, breakers); }, keep: function (value) { herald('kept', value, keepers); }, promise: { is_promise: true, when: function (kept, broken) { var vow = make(); switch (status) { case 'pending': enqueue('keep', kept, vow); enqueue('break', broken, vow); break; case 'kept': enqueue('keep', kept, vow); enlighten(keepers, fate); break; case 'broken': enqueue('break', broken, vow); enlighten(breakers, fate); break; } return vow.promise; } } }; } };}());

Page 59: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

Our Friend the Monad

The Identity MonadThe Ajax Monad

The Maybe MonadThe Promise Monad

Page 60: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

;

Page 61: Monads & Gonads Douglas Crockford. Functional Programming Programming with functions

Further Viewing

Carl Hewitt. The Actor Model (everything you wanted to know, but were afraid to ask)

http://channel9.msdn.com/Shows/Going+Deep/Hewitt-Meijer-and-Szyperski-The-Actor-Model-everything-you-wanted-to-know-but-were-afraid-to-ask

Mark Miller. Secure Distributed Programming with Object-capabilities in JavaScript

http://www.youtube.com/watch?v=w9hHHvhZ_HYhttp://www.youtube.com/watch?v=oBqeDYETXME