Top Banner
ZNAKI MOCY DLA LAIKÓW Wiktor Toporek
66

UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

Aug 08, 2015

Download

Technology

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

ZNAKI MOCYDLA LAIKÓW

Wiktor Toporek

Page 2: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

O MNIEBlog: Na co dzień PHP i JSInspirują mnie inne języki programowania i podejścia

http://wiktortoporek.name/blog

Page 3: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

Jak wyobrażam sobie nasze codzienne programowanie?

Page 4: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript
Page 5: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript
Page 6: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

Jak wyobrażam sobie programowanie funkcyjne?

Page 7: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript
Page 8: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

PURE FUNCTIONSfunction f(x) { return x * 2;}

Page 9: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

IMMUTABILITYfunction f(x) { x[0] = 1;}✗

Page 10: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

Źródło: http://thecodinglove.com/post/120526844813

Page 11: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

FIRST CLASS CITIZENFUNCTIONS

function f(x) { ...}

var g = f;

Page 12: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

(λ)FUNKCJE WYŻSZYCH RZĘDÓW

Page 13: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript
Page 14: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript
Page 15: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript
Page 16: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

FOREACH

Page 17: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

var doubled = [];

[1, 2, 3].forEach( function(v) { doubled.push(v * 2); });

FOREACH

Page 18: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

MAP[1, 2, 3].map( function(v) { return v * 2; }); //-> [2, 4, 6]

[1,2,3] → [2,4,6]

Page 19: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

FILTER[5, 6, 2, 1].filter( function(v) { return v % 2 == 0; }); //-> [6, 2]

[5,6,2,1] → [6,2]

Page 20: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

REDUCE

Page 21: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

var grades = [5, 5, 4, 3, 4, 2];var sum = 0;for (var i in grades) { sum += grades[i];}var avg = sum / grades.length;

Page 22: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

var grades = [5, 5, 4, 3, 4, 2];var sum = grades.reduce( function(currentSum, currentGrade) { return currentSum + currentGrade; });var avg = sum / grades.length;

[5,5,4,3,4,2] → 23

Page 23: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

[1, 2, 3]

[keyDown, keyDown, keyDown, ...

Page 24: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

RxJS

github.com/Reactive-Extensions/RxJS

Page 25: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

REAGOWANIE NA KLAWISZ ENTERvar keydown = Rx.Observable.fromEvent(document, 'keydown');keydown.forEach( function(event) { if (event.which === 13) { // do something } });

Elastyczniej:var keydown = Rx.Observable.fromEvent(document, 'keydown');var enterPresses = keydown.filter( function(event) { return event.which === 13; });enterPresses.forEach(function() {/* do something */});

Page 26: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

RXMARBLES.COM

Page 27: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

DRAG & DROP

Page 28: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

M↓ M↓ M⇝ M⇝ M⇝ M⇝ M⇝ M⇝ M⇝ M↑ M↑var mousedown = Rx.Observable.fromEvent(dragTarget, 'mousedown');var mousemove = Rx.Observable.fromEvent(document, 'mousemove');var mouseup = Rx.Observable.fromEvent(dragTarget, 'mouseup' );

Page 29: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

var mousedrag = mousedown.flatMap( function (md) { // calculate offsets when mouse down var startX = md.offsetX, startY = md.offsetY;

// Calculate delta with mousemove until mouseup return mousemove.map(function (mm) { mm.preventDefault();

return { left: mm.clientX - startX, top: mm.clientY - startY }; }).takeUntil(mouseup); });

mousedrag.forEach(function(newPosition) { // change element position});

Page 30: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

(())KOMPOZYCJA

Page 31: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

Przykład startowyvar name = "Doge"console.log("Hello " + name);

Page 32: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

Trochę elastyczniej...

...ale nie do końca

var name = "Doge"function printIt(name) { console.log("Hello " + name);}

printIt(name);

printIt("Bye Doge"); // Hello Bye Doge

Page 33: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

Osobna funkcja do witania:function greeting(name) { return "Hello " + name;}

Użycie:var name = "Doge";printIt(greeting("Doge")); // Hello Doge

Page 34: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

POŁĄCZMY DWIE FUNKCJE W JEDNĄKlasyczną drogą:

var name = "Doge";function greet(name) { printIt(greeting(name));}greet(name);

Drogą FP:var name = "Doge";var greet = compose(printIt, greeting);greet(name);

Page 35: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

CO ROBI COMPOSE?

Page 36: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

A co z parametrem innego typu?var user = { id: 123, name: "Doge"};

To:greet(user); // Hello [object Object]

Page 37: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

Dopiszmy kolejną funkcję:function printIt(name) { console.log(name);}function greeting(name) { return "Hello " + name;}function getName(user) { return user.name;}

Skomponujmy nową ze wszystkich trzech:var greetUser = compose(printIt, greeting, getName);var user = { id: 123, name: "Doge"};greetUser(user);

Page 38: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

Nie musimy ograniczać się do własnych funkcji:function getFullname(person) { return [person.firstName, person.lastName].join(' ');}

var getFullnameFromJson = compose(getFullname, JSON.parse);

Page 39: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

()()()CURRYING

Page 40: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

Przykład startowy

Użycie:

function sendMessage(from, to, message) { console.log([from, ' -> ', to, ': ', message].join(""));}

sendMessage('John', 'Alice', 'Hello!'); //John -> Alice: Hello!

Page 41: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

Jako John:sendMessage('John', 'Alice', 'Hello!');sendMessage('John', 'Alice', 'How are you?');sendMessage('John', 'Bob', 'Hello!');

Page 42: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

Ułatwmy Johnowi:function sendMessageFromJohn(to, message){ sendMessage('John', to, message);}

sendMessageFromMe('Alice', 'Hello!');sendMessageFromMe('Alice', 'How are you?');sendMessageFromMe('Bob', 'Hello!');

Page 43: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

Ręczny Curryingfunction sendMessage(from) { return function(to) { return function(message) { console.log([from, ' -> ', to, ': ', message].join("")); } }}

Użycie:var sendMessageFromMe = sendMessage(currentUser);sendMessageFromMe('Alice')('Hey');

Page 44: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

Currying z Lodashvar sendMessage = _.curry( function(from, to, message) { console.log([from, ' -> ', to, ': ', message].join("")); });

Użycie:var sendMessageFromMe = sendMessage(currentUser);sendMessageFromMe('Alice', 'Hey');

Page 45: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

v←λMONADA

Page 46: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

Źródło: https://en.wikipedia.org/wiki/Monad_(category_theory)

Page 47: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

Źródło: http://thecodinglove.com/post/119589628797/

Page 48: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

Źródło: http://pl.wikipedia.org/wiki/Monada_(programowanie)

Page 49: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

Źródło: https://twitter.com/jlouis666/status/569465010759573505

Page 50: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

[TASK].[ASSIGNED_COMPANY_LOGO_URL]

[TASK] → [ASIGNEE] → [COMPANY] → [LOGO] → [URL]

function getTaskCompanyLogoUrl(task){ return task.asignee.company.logo.url;}

Page 51: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

Problem:var task = { 'asignee': null};

getTaskCompanyLogoUrl(task);

Page 52: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

Źródło: http://www.practical-programming.org/articles/love_null/love_null.html

Page 53: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

Klasycznie:function getTaskCompanyLogo(task){ if (task.asignee !== null) { if (task.asignee.company !== null) { if (task.asignee.company.logo !== null) { return task.asignee.company.logo.url; } } }

return null;}

Page 54: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

task → getAsignee → getCompany → getLogo → getUrl

task → stop if null → getAsignee → stop if null → ... → getUrl

Page 55: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

MAYBE

Page 56: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

MONADOWY PLAN:Value - Bieżemy wartość[ Value ] - Opakowujemy ją[ Value ].map(f).map(f)... - Dowiązujemy pewne operacje[ Value ].getValue() - Odpakowujemy nową wartość

Page 57: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

Przykład z pomocą Monet.js*:function getTaskCompanyLogo(task){ var maybeCompanyLogoUrl = Maybe.of(task) .map(getAsignee) .map(getCompany) .map(getLogo) .map(getUrl);

return maybeCompanyLogoUrl.val;}

* fork vViktorPL/monet.js z drobną zmianą na potrzeby prezentacji

Page 58: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

Gettery:function getCompany(object) { return object.company;}function getLogo(object) { return object.logo;}function getUrl(object) { return object.url;}

Page 59: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

ES6:function getTaskCompanyLogo(task){ var maybeCompanyLogoUrl = Maybe.of(task) .map(task => task.asignee) .map(asignee => asignee.company) .map(company => company.logo) .map(logo => logo.url);

return maybeCompanyLogoUrl.val;}

Page 60: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

JAK TO DZIAŁA?Maybe = Some | None

Some.map(f) => { var result = f(this.val); if (result !== null) { return Some(result); } else { return None; }}

None.map(f) => None

Page 61: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

PROMISE

Page 62: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

Angularowe $q

Źródło: https://docs.angularjs.org/api/ng/service/$q

function asyncGreet(name) { // perform some asynchronous operation, resolve or reject the promise when appropriate. return $q(function(resolve, reject) { setTimeout(function() { if (okToGreet(name)) { resolve('Hello, ' + name + '!'); } else { reject('Greeting ' + name + ' is not allowed.'); } }, 1000); });}

Page 63: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

function asyncGreet(name) { ...}

var promise = asyncGreet('Robin Hood');promise.then(function(greeting) { alert('Success: ' + greeting);}, function(reason) { alert('Failed: ' + reason);});

var promise = asyncGreet(name); - Opakowanie wartościpromise.then() - .map()?greeting - wyłuskana nowa wartość

Page 64: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

PODSUMOWANIEFunkcje wyższych rzędów takie jak map czy filterułatwiają przetworzenie serii danychKompozycja umożliwia w łatwy sposób składanie kilkufunkcji w jednąCurrying może przydać się do funkcji które przyjmująwiele argumentówMonada to warstwa abstrakcji która sama decyduje w jakisposób wykona przekazane jej operacje

Page 65: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

MOJE WNIOSKIWzorce z FP da się odnaleźć w OOFP rzuca inne światło na niektóre problemyProgramowanie czysto funkcyjne jest szaleństwem dlaaplikacji z życia wziętych (potrzebujemy stanu prędzej czypóźniej)FP jest źle "sprzedawane"FP można łączyć z OO

Page 66: UszanowankoProgramowanko 5 - Znaki Mocy Dla Laikow - Programowanie Funkcyjne w Javascript

DZIĘKUJE ZA UWAGĘPYTANIA?

KOMENTARZE?