KEMBAR78
The Evolution of Async-Programming (SD 2.0, JavaScript) | PDF
The Evolution of
Async Programming
    ZhaoJie @ SNDA
       Nov, 2010
About Me
•       /        / Jeffrey Zhao /

•
• Blog: http://blog.zhaojie.me/
• Twitter: @jeffz_cn
• F#, Scala, JavaScript, Python, .NET, mono...
• Java (as the language) hater
Agenda
• Why & How
• Callback-based
• Iterator-based
• Library-based
• Language-based
• The future
Why?


   Because the essence of
      Cloud, Web, Mobile
is asynchronous computations
How?


 By providing powerful language
features / programming model /
             libraries
Callback-based
Async means Callback

• In .NET
  •   Begin/End
  •   Event-based

• JavaScript
  •   XMLHttpRequest
  •   DOM events
Normalized Async Task
var xxxAsync = function(arg0, arg2, ...) {
    return {
        start: function(callback) {
             ...
             var result = ...
             callback(result);
        }
    }
}
E.g. sleepAsync

var sleepAsync = function(ms) {
    return {
        start: function(callback) {
             window.setTimeout(callback, ms);
        }
    };
}
E.g. receiveAsync
XMLHttpRequest.prototype.receiveAsync = function() {
    var _this = this;
    return {
        start: function(callback) {
             _this.onreadystatechange = function() {
                 if (this.readyState == 4) {
                     callback(_this.responseText);
                 }
             }

             _this.send();
         }
    };
}
E.g. moveAsync
var moveAsync = function(e, start, end, duration) {
  return {
    start: function(callback) {
      var t = 0;

             var loop = function() {
               if (t < duration) {
                 t += 50;
                 e.style.left = start.x + (end.x - start.x) * t / duration;
                 e.style.top = start.y + (end.y - start.y) * t / duration;
                 sleepAsync(50).start(loop); // composite with sleepAsync
               } else {
                 if (callback) callback();
               }
             }

             loop();
         }
    };
}
“Deal cards” in 4
 different ways
Demo 1

Callback-based
Code Locality is Broken

• Used to expressing algorithms linearly
• Async requires logical division of algorithms
  •   No if / using / while / for ...

• Very difficult to
  •   Combine multiple asynchronous operations
  •   Deal with exceptions and cancellation
Iterator-based
“yield” for Iterators
    function numbers() {

        var s0 = yield 0;
    	
        var s1 = yield 1;
    	
        var s2 = yield 2;

    }
“yield” for Iterators
var it = numbers();
                      function numbers() {

                          var s0 = yield 0;
                      	
                          var s1 = yield 1;
                      	
                          var s2 = yield 2;

                      }
“yield” for Iterators
var it = numbers();
                      function numbers() {
var n0 = it.next();
                          var s0 = yield 0;
                      	
                          var s1 = yield 1;
                      	
                          var s2 = yield 2;

                      }
“yield” for Iterators
var it = numbers();
                        function numbers() {
var n0 = it.next();
                            var s0 = yield 0;
                        	
var n1 = it.push(10);
                            var s1 = yield 1;
                        	
                            var s2 = yield 2;

                        }
“yield” for Iterators
var it = numbers();
                        function numbers() {
var n0 = it.next();
                            var s0 = yield 0;
                        	
var n1 = it.push(10);
                            var s1 = yield 1;
                        	
var n2 = it.push(20);
                            var s2 = yield 2;

                        }
“yield” for Iterators
var it = numbers();
                        function numbers() {
var n0 = it.next();
                            var s0 = yield 0;
                        	
var n1 = it.push(10);
                            var s1 = yield 1;
                        	
var n2 = it.push(20);
                            var s2 = yield 2;
it.push(30);
                        }
Demo 2

Iterator-based
“yield” for Async
• Programming features in modern languages
• Coming with new programming patterns
• Keep code locality
  •   Support most constructions: if / using / while / for ...

• The primitives for Fibers - lightweight
  computation units
Library-based /
Reactive Framework
Reactive Framework

 Fundamentally change the way you
   think about coordinating and
  orchestrating asynchronous and
     event-based programming
How


By showing that asynchronous and
 event-base computations are just
      push-based collections
Interactive                 Reactive
              Environment



               Program
Enumerable Collections
 interface IEnumerable<out T> {
     IEnumerator<T> GetEnumerator();
 }

 interface IEnumerator<out T> {
     bool MoveNext();
     T Current { get; }
 }
Dualize
Observable Collections
interface IObservable<out T> {
    IDisposable Subscribe(IObserver<T> o)
}

interface IObserver<in T> {
    void OnCompleted();
    void OnNext(T item);
    void OnError(Exception ex);
}
IEnumerable & IEnumerator are prototypical
interfaces for interactive collections and
interactive programs.

IObservable & IObserver are prototypical
interfaces for observable collections and
reactive, asynchronous & event-based programs.
LINQ to Observable

        If you are writing
    LINQ or declarative code
   in an interactive program...
LINQ to Observable

         If you are writing
     LINQ or declarative code
    in an interactive program...


  You already know how to use it!
LINQ
... the principle we go by is, don't expect to see
a particular concurrency model put into C#
because there're many different concurrency
model ... it's more about finding things are
common to to all kinds of concurrency ...

                              - Anders Hejlsberg
LINQ
... the principle we go by is, don't expect to see
a particular concurrency model put into C#
because there're many different concurrency
model ... it's more about finding things are
common to to all kinds of concurrency ...

                              - Anders Hejlsberg
Rx in JavaScript
• A full featured port for JavaScript
  •   Easy-to-use conversions from existing DOM,
      XmlHttpRequest, etc
  •   In a download size of less than 7kb (gzipped)

• Bindings for various libraries / frameworks
  •   jQuery
  •   MooTools
  •   Dojo
  •   ...
Time Flies like an Arrow
var container = $("#container");
var mouseMove = container.toObservable("mousemove");

for (var i = 0; i < text.length; i++) {
    (function(i) {
        var ele = $("<span/>").text(text.charAt(i));
        ele.css({position: "absolute"}).appendTo(container);

        mouseMove.Delay(i * 100).Subscribe(function (ev) {
            ele.css({
                left: ev.clientX + i * 20 + 15 + "px",
                top: ev.clientY + "px"
            });
        });

    })(i);
Wikipedia Lookup
var textBox = $("#searchInput");
var searcher = textBox
    .toObservable("keyup")
    .Throttle(500)
    .Select(function(_) { return textBox.val(); })
    .Select(function(term) { return queryWikipedia(term); })
    .Switch();

searcher.Subscribe(
    function(data) {
        var results = $("#results");
        results.empty();
        $.each(data, function(_, value) {
            results.append($("<li/>").text(value));
        });
    },
    function(error) { $("#error").html(error); });
Demo 4

  Library-based /
Reactive Framework
Benefits of Rx
• Easy to composite and coordinate async
  operations

• Express the algorithm in functional ways
  •   Helper method: For / While / If / Try / Switch...

• Easy to be unit tested
• ...
Rx & Language Features
• Features in C# that Rx uses
 •   Extension method
 •   Lambda expression & closure
 •   Type inference
 •   LINQ query expression

• Rx has been implemented in ...
 •   C# & VB
 •   JavaScript
 •   F#
Portability
• Rx can be easily ported to various languages
  •   Scala
  •   Ruby
  •   Python
  •   modern languages with basic functional features

• Almost impossible to implement Rx in Java
  •   Cannot extend a type without breaking code
  •   Missing enough functional features
Rx Resources
• Matthew Podwysocki
 •   http://codebetter.com/blogs/matthew.podwysocki/

• Reactive Framework on MSDN DevLabs
 •   http://msdn.microsoft.com/en-us/devlabs/
     ee794896.aspx

• Tomáš Petříček
 •   http://tomasp.net/
Language-based
F#
• Language by Don Syme, MS Research
• Strongly statically typed language
• Functional language with OO ability
• For industry and education
 •   Open source (Apache 2.0)
 •   Cross-platform supported by Microsoft
Concurrency Challenges

• Shared State - Immutability
• Code Locality - async { ... }
• I/O Parallelism - async { ... }
• Scaling to Multi-Machine - Agents with
  async { ... }
What’s async { ... }
... the principle we go by is, don't expect to see
a particular concurrency model put into C#
because there're many different concurrency
model ... it's more about finding things are
common to to all kinds of concurrency ...

                              - Anders Hejlsberg
Async Workflow
async { 	
    let! res = <async work>
    ...	
}
Async Workflow
            React!
async { 	
    let! res = <async work>
    ...	
}
Async Workflow
              React!
async { 	
    let! res = <async work>
    ...	
}
        an HTTP Response
            an UI Event
         a Timer Callback
        a Query Response
     a Web Servcie Response
      a Disk I/O Completion
         an Agent Message
How async { ... } Works
   async {
       let! img = AsyncRead "http://..."
       printfn "loaded!"
       do! AsyncWrite img @"c:..."
       printfn "saved!" }
How async { ... } Works
       async {
           let! img = AsyncRead "http://..."
           printfn "loaded!"
           do! AsyncWrite img @"c:..."
           printfn "saved!" }


                        =
async.Delay(fun ->
	 async.Bind(AsyncRead "http://...", (fun img ->
	 	 printfn "loaded!"
	 	 async.Bind(AsyncWrite img @"c:...", (fun () ->
	 	 	 printfn "saved!"
	 	 	 async.Return())))))
F# Async Workflow
• Library, not a language feature
  •   Based on Computation Expressions in F#

• Support all kinds of language constructions
  •   Error handling: try...catch
  •   Loop: while / for (like “foreach” in C#)
  •   Others: if / use (like “using” in C#), etc.

• Easy to
  •   Combine multiple asynchronous operations
  •   Deal with exceptions and cancellation
F# Resources
                 http://fsharp.net




Programming F#     Expert F# 2.0     Real World FP
Comparison

• F# Async Workflow
 •   Elegant, simple, easy to use
 •   Can only be used at server-side (WebSharper come to
     rescure?)

• Reactive Framework
 •   Can be used at both server-side and client-side.
 •   New async model brings learning cost.
Can we use
“Async Workflow”
  in JavaScript?
Demo 5

Jscex & Jscex.Async
The Future / C# vNext
Source

async Task<XElement> GetRssAsync(string url) {
    var client = new WebClient();
    var task = client.DownloadStringTaskAsync(url);
    var text = await task;
    var xml = XElement.Parse(text);
    return xml;
}
Compiled
Task<XElement> GetRssAsync(string url) {
    var $builder = AsyncMethodBuilder<XElement>.Create();
    var $state = 0;
    TaskAwaiter<string> $a1;
    Action $resume = delegate {
        try {
            if ($state == 1) goto L1;
            var client = new WebClient();
            var task = client.DownloadStringTaskAsync(url);
            $state = 1;
            $a1 = task.GetAwaiter();
            if ($a1.BeginAwait($resume)) return;
        L1: var text = $a1.EndAwait();
            var xml = XElement.Parse(text);
            $builder.SetResult(xml);
        }
        catch (Exception $ex) { $builder.SetException($ex); }
    };
    $resume();
    return $builder.Task;
}
Conclusion

• Async Programming is difficult
• New programming language / feature /
  library / model can help

• JavaScript is incredible.
Q &A
Thanks

The Evolution of Async-Programming (SD 2.0, JavaScript)

  • 1.
    The Evolution of AsyncProgramming ZhaoJie @ SNDA Nov, 2010
  • 2.
    About Me • / / Jeffrey Zhao / • • Blog: http://blog.zhaojie.me/ • Twitter: @jeffz_cn • F#, Scala, JavaScript, Python, .NET, mono... • Java (as the language) hater
  • 3.
    Agenda • Why &How • Callback-based • Iterator-based • Library-based • Language-based • The future
  • 4.
    Why? Because the essence of Cloud, Web, Mobile is asynchronous computations
  • 5.
    How? By providingpowerful language features / programming model / libraries
  • 6.
  • 7.
    Async means Callback •In .NET • Begin/End • Event-based • JavaScript • XMLHttpRequest • DOM events
  • 8.
    Normalized Async Task varxxxAsync = function(arg0, arg2, ...) { return { start: function(callback) { ... var result = ... callback(result); } } }
  • 9.
    E.g. sleepAsync var sleepAsync= function(ms) { return { start: function(callback) { window.setTimeout(callback, ms); } }; }
  • 10.
    E.g. receiveAsync XMLHttpRequest.prototype.receiveAsync =function() { var _this = this; return { start: function(callback) { _this.onreadystatechange = function() { if (this.readyState == 4) { callback(_this.responseText); } } _this.send(); } }; }
  • 11.
    E.g. moveAsync var moveAsync= function(e, start, end, duration) { return { start: function(callback) { var t = 0; var loop = function() { if (t < duration) { t += 50; e.style.left = start.x + (end.x - start.x) * t / duration; e.style.top = start.y + (end.y - start.y) * t / duration; sleepAsync(50).start(loop); // composite with sleepAsync } else { if (callback) callback(); } } loop(); } }; }
  • 12.
    “Deal cards” in4 different ways
  • 13.
  • 15.
    Code Locality isBroken • Used to expressing algorithms linearly • Async requires logical division of algorithms • No if / using / while / for ... • Very difficult to • Combine multiple asynchronous operations • Deal with exceptions and cancellation
  • 16.
  • 17.
    “yield” for Iterators function numbers() { var s0 = yield 0; var s1 = yield 1; var s2 = yield 2; }
  • 18.
    “yield” for Iterators varit = numbers(); function numbers() { var s0 = yield 0; var s1 = yield 1; var s2 = yield 2; }
  • 19.
    “yield” for Iterators varit = numbers(); function numbers() { var n0 = it.next(); var s0 = yield 0; var s1 = yield 1; var s2 = yield 2; }
  • 20.
    “yield” for Iterators varit = numbers(); function numbers() { var n0 = it.next(); var s0 = yield 0; var n1 = it.push(10); var s1 = yield 1; var s2 = yield 2; }
  • 21.
    “yield” for Iterators varit = numbers(); function numbers() { var n0 = it.next(); var s0 = yield 0; var n1 = it.push(10); var s1 = yield 1; var n2 = it.push(20); var s2 = yield 2; }
  • 22.
    “yield” for Iterators varit = numbers(); function numbers() { var n0 = it.next(); var s0 = yield 0; var n1 = it.push(10); var s1 = yield 1; var n2 = it.push(20); var s2 = yield 2; it.push(30); }
  • 23.
  • 24.
    “yield” for Async •Programming features in modern languages • Coming with new programming patterns • Keep code locality • Support most constructions: if / using / while / for ... • The primitives for Fibers - lightweight computation units
  • 25.
  • 26.
    Reactive Framework Fundamentallychange the way you think about coordinating and orchestrating asynchronous and event-based programming
  • 27.
    How By showing thatasynchronous and event-base computations are just push-based collections
  • 28.
    Interactive Reactive Environment Program
  • 29.
    Enumerable Collections interfaceIEnumerable<out T> { IEnumerator<T> GetEnumerator(); } interface IEnumerator<out T> { bool MoveNext(); T Current { get; } }
  • 30.
  • 31.
    Observable Collections interface IObservable<outT> { IDisposable Subscribe(IObserver<T> o) } interface IObserver<in T> { void OnCompleted(); void OnNext(T item); void OnError(Exception ex); }
  • 32.
    IEnumerable & IEnumeratorare prototypical interfaces for interactive collections and interactive programs. IObservable & IObserver are prototypical interfaces for observable collections and reactive, asynchronous & event-based programs.
  • 33.
    LINQ to Observable If you are writing LINQ or declarative code in an interactive program...
  • 34.
    LINQ to Observable If you are writing LINQ or declarative code in an interactive program... You already know how to use it!
  • 35.
    LINQ ... the principlewe go by is, don't expect to see a particular concurrency model put into C# because there're many different concurrency model ... it's more about finding things are common to to all kinds of concurrency ... - Anders Hejlsberg
  • 36.
    LINQ ... the principlewe go by is, don't expect to see a particular concurrency model put into C# because there're many different concurrency model ... it's more about finding things are common to to all kinds of concurrency ... - Anders Hejlsberg
  • 37.
    Rx in JavaScript •A full featured port for JavaScript • Easy-to-use conversions from existing DOM, XmlHttpRequest, etc • In a download size of less than 7kb (gzipped) • Bindings for various libraries / frameworks • jQuery • MooTools • Dojo • ...
  • 38.
    Time Flies likean Arrow var container = $("#container"); var mouseMove = container.toObservable("mousemove"); for (var i = 0; i < text.length; i++) { (function(i) { var ele = $("<span/>").text(text.charAt(i)); ele.css({position: "absolute"}).appendTo(container); mouseMove.Delay(i * 100).Subscribe(function (ev) { ele.css({ left: ev.clientX + i * 20 + 15 + "px", top: ev.clientY + "px" }); }); })(i);
  • 39.
    Wikipedia Lookup var textBox= $("#searchInput"); var searcher = textBox .toObservable("keyup") .Throttle(500) .Select(function(_) { return textBox.val(); }) .Select(function(term) { return queryWikipedia(term); }) .Switch(); searcher.Subscribe( function(data) { var results = $("#results"); results.empty(); $.each(data, function(_, value) { results.append($("<li/>").text(value)); }); }, function(error) { $("#error").html(error); });
  • 40.
    Demo 4 Library-based / Reactive Framework
  • 41.
    Benefits of Rx •Easy to composite and coordinate async operations • Express the algorithm in functional ways • Helper method: For / While / If / Try / Switch... • Easy to be unit tested • ...
  • 42.
    Rx & LanguageFeatures • Features in C# that Rx uses • Extension method • Lambda expression & closure • Type inference • LINQ query expression • Rx has been implemented in ... • C# & VB • JavaScript • F#
  • 43.
    Portability • Rx canbe easily ported to various languages • Scala • Ruby • Python • modern languages with basic functional features • Almost impossible to implement Rx in Java • Cannot extend a type without breaking code • Missing enough functional features
  • 44.
    Rx Resources • MatthewPodwysocki • http://codebetter.com/blogs/matthew.podwysocki/ • Reactive Framework on MSDN DevLabs • http://msdn.microsoft.com/en-us/devlabs/ ee794896.aspx • Tomáš Petříček • http://tomasp.net/
  • 45.
  • 46.
    F# • Language byDon Syme, MS Research • Strongly statically typed language • Functional language with OO ability • For industry and education • Open source (Apache 2.0) • Cross-platform supported by Microsoft
  • 47.
    Concurrency Challenges • SharedState - Immutability • Code Locality - async { ... } • I/O Parallelism - async { ... } • Scaling to Multi-Machine - Agents with async { ... }
  • 48.
    What’s async {... } ... the principle we go by is, don't expect to see a particular concurrency model put into C# because there're many different concurrency model ... it's more about finding things are common to to all kinds of concurrency ... - Anders Hejlsberg
  • 49.
    Async Workflow async {   let! res = <async work> ... }
  • 50.
    Async Workflow React! async {   let! res = <async work> ... }
  • 51.
    Async Workflow React! async {   let! res = <async work> ... } an HTTP Response an UI Event a Timer Callback a Query Response a Web Servcie Response a Disk I/O Completion an Agent Message
  • 52.
    How async {... } Works async { let! img = AsyncRead "http://..." printfn "loaded!" do! AsyncWrite img @"c:..." printfn "saved!" }
  • 53.
    How async {... } Works async { let! img = AsyncRead "http://..." printfn "loaded!" do! AsyncWrite img @"c:..." printfn "saved!" } = async.Delay(fun -> async.Bind(AsyncRead "http://...", (fun img -> printfn "loaded!" async.Bind(AsyncWrite img @"c:...", (fun () -> printfn "saved!" async.Return())))))
  • 54.
    F# Async Workflow •Library, not a language feature • Based on Computation Expressions in F# • Support all kinds of language constructions • Error handling: try...catch • Loop: while / for (like “foreach” in C#) • Others: if / use (like “using” in C#), etc. • Easy to • Combine multiple asynchronous operations • Deal with exceptions and cancellation
  • 55.
    F# Resources http://fsharp.net Programming F# Expert F# 2.0 Real World FP
  • 56.
    Comparison • F# AsyncWorkflow • Elegant, simple, easy to use • Can only be used at server-side (WebSharper come to rescure?) • Reactive Framework • Can be used at both server-side and client-side. • New async model brings learning cost.
  • 57.
    Can we use “AsyncWorkflow” in JavaScript?
  • 58.
    Demo 5 Jscex &Jscex.Async
  • 59.
    The Future /C# vNext
  • 60.
    Source async Task<XElement> GetRssAsync(stringurl) { var client = new WebClient(); var task = client.DownloadStringTaskAsync(url); var text = await task; var xml = XElement.Parse(text); return xml; }
  • 61.
    Compiled Task<XElement> GetRssAsync(string url){ var $builder = AsyncMethodBuilder<XElement>.Create(); var $state = 0; TaskAwaiter<string> $a1; Action $resume = delegate { try { if ($state == 1) goto L1; var client = new WebClient(); var task = client.DownloadStringTaskAsync(url); $state = 1; $a1 = task.GetAwaiter(); if ($a1.BeginAwait($resume)) return; L1: var text = $a1.EndAwait(); var xml = XElement.Parse(text); $builder.SetResult(xml); } catch (Exception $ex) { $builder.SetException($ex); } }; $resume(); return $builder.Task; }
  • 62.
    Conclusion • Async Programmingis difficult • New programming language / feature / library / model can help • JavaScript is incredible.
  • 63.
  • 64.