Функциональное реактивное программирование

45
Javascript unleashed

Upload: dmitriy-kiriyenko

Post on 08-Jul-2015

341 views

Category:

Technology


0 download

DESCRIPTION

Выступление Дмитрия Кириенко и Алексея Осипенко на ноябрьской встрече Донецкого Лямбда-клуба. http://l.dn.ua/ http://dimoneverything.blogspot.com/2013/11/blog-post.html

TRANSCRIPT

Page 1: Функциональное реактивное программирование

Javascript unleashed

Page 2: Функциональное реактивное программирование

Функциональное программирование объединяет гибкость и мощь абстрактной математики с интуитивной понятностью абстрактной математики

Page 3: Функциональное реактивное программирование

function Counter(element) { var that = this; this.count = 0; this.clicked = function () { this.count += 1; } $(element).click(function() { return that.clicked(); });};

Page 4: Функциональное реактивное программирование

$("#login").on("click", function (event) {

var value = $(event.target).val();

if (value.length > 0) {

$("#notice").text(value);

}

});

Page 5: Функциональное реактивное программирование

var clickE = $("#login").events("click");clickE.onValue(function (event) { var value = $(event.target).val(); if (value.length > 0) { $("#notice").text(value); }});

$("#login").on("click", function (event) {

var value = $(event.target).val();

if (value.length > 0) {

$("#notice").text(value);

}

});

Page 6: Функциональное реактивное программирование

var clickE = $("#login").events("click");var values = clickE.map(function (event) { return $(event.target).val();});var nonEmptyValues = values.filter(function (value) { return value.length > 0;});nonEmptyValues.onValue(function (value) { $("#notice").text(value);});

$("#login").on("click", function (event)

{

var value = $(event.target).val();

if (value.length > 0) {

$("#notice").text(value);

}

});

Page 7: Функциональное реактивное программирование

var values = $("#login").events("click") .map(function (event) { return $(event.target).val();}).filter(function (value) { return value.length > 0;});

values.onValue(function (value) { $("#notice").text(value);});

$("#login").on("click", function (event) {

var value = $(event.target).val();

if (value.length > 0) {

$("#notice").text(value);

}

});

Page 8: Функциональное реактивное программирование

var values = $("#login").events("click") .map(chain(pluck('target'), $, method('val')) .filter(nonEmpty);

values.onValue(function (value) { $("#notice").text(value); });

$("#login").on("click", function (event)

{

var value = $(event.target).val();

if (value.length > 0) {

$("#notice").text(value);

}

});

Page 9: Функциональное реактивное программирование

type Stream[a] = [(T, a)]type Box[a] = T -> a

Stream will receive B and C

Box immediately receives A and will receive B and C

A B C

A B C

Page 10: Функциональное реактивное программирование

new Stream( function (sink) {

sink(new Event(10));

sink(new Event(20));

return function() {};

});

Page 11: Функциональное реактивное программирование

Box.nothing(); // empty boxBox.unit(10); // box with constant value of 10Stream.never(); // empty streamStream.unit(10); // stream with immediate value of 10

Page 12: Функциональное реактивное программирование

Stream.error(10); // stream with immediate error of 10Box.error(10); // box with constant error of 10

Page 13: Функциональное реактивное программирование

Stream.later(1000, 10);// in a second pops out 10

Page 14: Функциональное реактивное программирование

$('input').stream('keyup');

// stream with keyup events

Page 15: Функциональное реактивное программирование

asyncCall(data, function (response) { // You have response from your asynchronous call here.}, function (err) { // if the async call fails, the error callback is invoked});

Page 16: Функциональное реактивное программирование

asyncCall(data,function(response){ // You have response from your asynchronous call here.}, function(err){ // if the async call fails, the error callback is invoked});

var promise = asyncCall(data);

promise.done(function(response){

// You have response from your asynchronous call here.

}).fail(function(err){

// if the async call fails, you have the error response

here.

});

Page 17: Функциональное реактивное программирование

Stream.fromPromise($.ajax(params));

// pops a success event on successful response

// or the error event on error response

Page 18: Функциональное реактивное программирование

_.map([1, 2, 3], function (x) { return x*x; });

// returns [1, 4, 9]

Page 19: Функциональное реактивное программирование

_.map([1, 2, 3], function (x) { return x*x; });

// returns [1, 4, 9]

priceValue.map(function(x) { return x > 1000;});

Page 20: Функциональное реактивное программирование
Page 21: Функциональное реактивное программирование

priceValue.filter(function(x) { return x >= 1000;});

Page 22: Функциональное реактивное программирование

_.flatMap(users, function (user) { return user.comments(); });

// returns flat list of all the comments the users have

Page 23: Функциональное реактивное программирование

var requests = usernames.map(function(u) { return { url: "/check-username/" + u; }});requests.flatMap(function (params) { return Stream.fromPromise($.ajax(params));});// usernames => "John", "Peter"// requests => {"url": "/check-username/John"}, ...// flatMap => {correct: true}, {correct: false}

Page 24: Функциональное реактивное программирование

Stream.prototype.map = function (f) { return this.flatMap(function (x) { return Stream.unit(f(x)); });}

Stream.prototype.filter = function (f) { return this.flatMap(function (x) { if f(x) { return Stream.unit(x); } else { return Stream.nothing(); } });}

Page 25: Функциональное реактивное программирование

password.map2(passwordConfirmation, function(l, r) { return l == r; });

Page 26: Функциональное реактивное программирование

Box.prototype.map2 = function (other, f) { return this.flatMap(function (x) { return other.map(function (y) { return f(x, y); }); });}

Page 27: Функциональное реактивное программирование
Page 28: Функциональное реактивное программирование

Box.prototype.apply = function (other) { return this.map2(function (f, x) { return f(x); } );}

Page 29: Функциональное реактивное программирование

var id = function (x) { return x; }

Stream.merge = function (streams) {

return Stream.fromList(streams).flatMap(id);

}

Page 30: Функциональное реактивное программирование

var inc = plusClicks.map(function() { return 1; });var dec = minusClicks.map(function() { return -1; });var change = plus.merge(minus);

Page 31: Функциональное реактивное программирование

Stream.prototype.debounce = function (delay) { return this.flatMapLast(function (value) { return Stream.later(delay, value); });}

Page 32: Функциональное реактивное программирование

Box.prototype.sampledBy = function (sampler) { var that = this; return sampler.flatMap(function () { return that.take(1); });}

Page 33: Функциональное реактивное программирование

votes.take(10);

hp.takeWhile(function (hp) { return hp > 0; } );

mousemove.takeUntil(escapePressed);

Page 34: Функциональное реактивное программирование
Page 35: Функциональное реактивное программирование

потоки событий мыши

Page 36: Функциональное реактивное программирование

mousedown = $(document).stream('mousedown', '.item')mouseup = $(document).stream('mouseup')mousemove = $(document).stream('mousemove')

Page 37: Функциональное реактивное программирование

mousedrag = mousedown.flatMapLast( (e)-> mousemove.takeUntil(mouseup))

Page 38: Функциональное реактивное программирование

позиции курсора

Page 39: Функциональное реактивное программирование

cursorPosition = mousemove.box().map( (e)-> { x: e.clientX, y: e.clientY })

Page 40: Функциональное реактивное программирование

startPosition = cursorPosition.sampledBy mousedowncurrentPosition = cursorPosition.sampledBy mousedrag

# cursorPosition → { x: 112, y: 234 }

Page 41: Функциональное реактивное программирование

shiftPosition = startPosition.zip(currentPosition) .map((s, m)-> { left: m.x-s.x, top: m.y-s.y } )

Page 42: Функциональное реактивное программирование

shiftPosition.onValue( (pos)-> $('.item').css(pos) )

Page 43: Функциональное реактивное программирование

mousedown.onValue (e)-> e.preventDefault()

Page 44: Функциональное реактивное программирование

newPosition = mousedown.flatMapLast (md)-> target = $(md.target); {left, top} = target.offset(); [startX, startY] = [md.clientX - left, md.clientY - top] mousemove.map (mm)-> target: target left: mm.clientX - startX top: mm.clientY - startY .takeUntil mouseup

Page 45: Функциональное реактивное программирование

чо?