Your SlideShare is downloading. ×
Функциональное реактивное программирование
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

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

273

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
273
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
0
Comments
0
Likes
1
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

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

×