Javascript unleashed
Функциональное программирование объединяет гибкость и мощь абстрактной математики с
интуитивной понятностью абстрактной ма...
function Counter(element) {
var that = this;
this.count = 0;
this.clicked = function () {
this.count += 1;
}
$(element).cl...
$("#login").on("click", function (event) {
var value = $(event.target).val();
if (value.length > 0) {
$("#notice").text(va...
$("#login").on("click", function (event) {
var value = $(event.target).val();
if (value.length > 0) {
$("#notice").text(va...
$("#login").on("click", function (event)
{
var value = $(event.target).val();

var clickE = $("#login").events("click");
v...
$("#login").on("click", function (event) {
var value = $(event.target).val();

var values = $("#login").events("click")
.m...
$("#login").on("click", function (event)
{

var values = $("#login").events("click")
.map(chain(pluck('target'), $, method...
type Stream[a] = [(T, a)]
type Box[a] = T -> a

A

B

C

Stream will receive B and C

A

B

C

Box immediately receives A ...
new Stream( function (sink) {
sink(new Event(10));
sink(new Event(20));
return function() {};
});
Box.nothing();
Box.unit(10);
Stream.never();
Stream.unit(10);

//
//
//
//

empty box
box with constant value of 10
empty ...
Stream.error(10); // stream with immediate error of 10
Box.error(10);
// box with constant error of 10
Stream.later(1000, 10);
// in a second pops out 10
$('input').stream('keyup');
// stream with keyup events
asyncCall(data, function (response) {
// You have response from your asynchronous call here.
}, function (err) {
// if the...
asyncCall(data,function(response){
// You have response from your asynchronous call here.
}, function(err){
// if the asyn...
Stream.fromPromise($.ajax(params));
// pops a success event on successful response
// or the error event on error response
_.map([1, 2, 3], function (x) { return x*x; });
// returns [1, 4, 9]
_.map([1, 2, 3], function (x) { return x*x; });
// returns [1, 4, 9]

priceValue.map(function(x) {
return x > 1000;
});
priceValue.filter(function(x) {
return x >= 1000;
});
_.flatMap(users, function (user) { return user.comments(); });
// returns flat list of all the comments the users have
var requests = usernames.map(function(u) {
return { url: "/check-username/" + u; }
});
requests.flatMap(function (params) ...
Stream.prototype.map = function (f) {
return this.flatMap(function (x) {
return Stream.unit(f(x));
});
}
Stream.prototype....
password.map2(passwordConfirmation,
function(l, r) { return l == r; });
Box.prototype.map2 = function (other, f) {
return this.flatMap(function (x) {
return other.map(function (y) { return f(x, ...
Box.prototype.apply = function (other) {
return this.map2(function (f, x) { return f(x); } );
}
var id = function (x) { return x; }
Stream.merge = function (streams) {
return Stream.fromList(streams).flatMap(id);
}
var inc = plusClicks.map(function() { return 1; });
var dec = minusClicks.map(function() { return -1; });
var change = plu...
Stream.prototype.debounce = function (delay) {
return this.flatMapLast(function (value) {
return Stream.later(delay, value...
Box.prototype.sampledBy = function (sampler) {
var that = this;
return sampler.flatMap(function () {
return that.take(1);
...
votes.take(10);
hp.takeWhile(function (hp) { return hp > 0; } );
mousemove.takeUntil(escapePressed);
потоки событий мыши
mousedown = $(document).stream('mousedown', '.item')
mouseup = $(document).stream('mouseup')
mousemove = $(document).strea...
mousedrag = mousedown.flatMapLast(
(e)-> mousemove.takeUntil(mouseup)
)
позиции курсора
cursorPosition = mousemove.box().map(
(e)-> { x: e.clientX, y: e.clientY }
)
# cursorPosition → { x: 112, y: 234 }

startPosition = cursorPosition.sampledBy mousedown
currentPosition = cursorPosition...
shiftPosition = startPosition.zip(currentPosition)
.map((s, m)->
{ left: m.x-s.x, top: m.y-s.y }
)
shiftPosition.onValue( (pos)-> $('.item').css(pos) )
mousedown.onValue (e)-> e.preventDefault()
newPosition = mousedown.flatMapLast (md)->
target = $(md.target);
{left, top} = target.offset();
[startX, startY] = [md.cl...
чо?
Функциональное реактивное программирование
Функциональное реактивное программирование
Функциональное реактивное программирование
Upcoming SlideShare
Loading in …5
×

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

841 views

Published on

Выступление Дмитрия Кириенко и Алексея Осипенко на ноябрьской встрече Донецкого Лямбда-клуба.

http://l.dn.ua/
http://dimoneverything.blogspot.com/2013/11/blog-post.html

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
841
On SlideShare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
2
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

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

  1. 1. Javascript unleashed
  2. 2. Функциональное программирование объединяет гибкость и мощь абстрактной математики с интуитивной понятностью абстрактной математики
  3. 3. function Counter(element) { var that = this; this.count = 0; this.clicked = function () { this.count += 1; } $(element).click(function() { return that.clicked(); }); };
  4. 4. $("#login").on("click", function (event) { var value = $(event.target).val(); if (value.length > 0) { $("#notice").text(value); } });
  5. 5. $("#login").on("click", function (event) { var value = $(event.target).val(); if (value.length > 0) { $("#notice").text(value); var clickE = $("#login").events("click"); clickE.onValue(function (event) { var value = $(event.target).val(); if (value.length > 0) { $("#notice").text(value); } }); } });
  6. 6. $("#login").on("click", function (event) { var value = $(event.target).val(); 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); }); if (value.length > 0) { $("#notice").text(value); } });
  7. 7. $("#login").on("click", function (event) { var value = $(event.target).val(); 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); }); if (value.length > 0) { $("#notice").text(value); } });
  8. 8. $("#login").on("click", function (event) { var values = $("#login").events("click") .map(chain(pluck('target'), $, method('val')) .filter(nonEmpty); values.onValue(function (value) { $("#notice"). text(value); }); var value = $(event.target).val(); if (value.length > 0) { $("#notice").text(value); } });
  9. 9. type Stream[a] = [(T, a)] type Box[a] = T -> a A B C Stream will receive B and C A B C Box immediately receives A and will receive B and C
  10. 10. new Stream( function (sink) { sink(new Event(10)); sink(new Event(20)); return function() {}; });
  11. 11. Box.nothing(); Box.unit(10); Stream.never(); Stream.unit(10); // // // // empty box box with constant value of 10 empty stream stream with immediate value of 10
  12. 12. Stream.error(10); // stream with immediate error of 10 Box.error(10); // box with constant error of 10
  13. 13. Stream.later(1000, 10); // in a second pops out 10
  14. 14. $('input').stream('keyup'); // stream with keyup events
  15. 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 });
  16. 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. });
  17. 17. Stream.fromPromise($.ajax(params)); // pops a success event on successful response // or the error event on error response
  18. 18. _.map([1, 2, 3], function (x) { return x*x; }); // returns [1, 4, 9]
  19. 19. _.map([1, 2, 3], function (x) { return x*x; }); // returns [1, 4, 9] priceValue.map(function(x) { return x > 1000; });
  20. 20. priceValue.filter(function(x) { return x >= 1000; });
  21. 21. _.flatMap(users, function (user) { return user.comments(); }); // returns flat list of all the comments the users have
  22. 22. 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}
  23. 23. 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(); } }); }
  24. 24. password.map2(passwordConfirmation, function(l, r) { return l == r; });
  25. 25. Box.prototype.map2 = function (other, f) { return this.flatMap(function (x) { return other.map(function (y) { return f(x, y); }); }); }
  26. 26. Box.prototype.apply = function (other) { return this.map2(function (f, x) { return f(x); } ); }
  27. 27. var id = function (x) { return x; } Stream.merge = function (streams) { return Stream.fromList(streams).flatMap(id); }
  28. 28. var inc = plusClicks.map(function() { return 1; }); var dec = minusClicks.map(function() { return -1; }); var change = plus.merge(minus);
  29. 29. Stream.prototype.debounce = function (delay) { return this.flatMapLast(function (value) { return Stream.later(delay, value); }); }
  30. 30. Box.prototype.sampledBy = function (sampler) { var that = this; return sampler.flatMap(function () { return that.take(1); }); }
  31. 31. votes.take(10); hp.takeWhile(function (hp) { return hp > 0; } ); mousemove.takeUntil(escapePressed);
  32. 32. потоки событий мыши
  33. 33. mousedown = $(document).stream('mousedown', '.item') mouseup = $(document).stream('mouseup') mousemove = $(document).stream('mousemove')
  34. 34. mousedrag = mousedown.flatMapLast( (e)-> mousemove.takeUntil(mouseup) )
  35. 35. позиции курсора
  36. 36. cursorPosition = mousemove.box().map( (e)-> { x: e.clientX, y: e.clientY } )
  37. 37. # cursorPosition → { x: 112, y: 234 } startPosition = cursorPosition.sampledBy mousedown currentPosition = cursorPosition.sampledBy mousedrag
  38. 38. shiftPosition = startPosition.zip(currentPosition) .map((s, m)-> { left: m.x-s.x, top: m.y-s.y } )
  39. 39. shiftPosition.onValue( (pos)-> $('.item').css(pos) )
  40. 40. mousedown.onValue (e)-> e.preventDefault()
  41. 41. 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
  42. 42. чо?

×