Post on 10-May-2015
The Evolution ofAsync Programming
ZhaoJie @ SNDANov, 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 ofCloud, 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. receiveAsyncXMLHttpRequest.prototype.receiveAsync = function() { var _this = this; return { start: function(callback) { _this.onreadystatechange = function() { if (this.readyState == 4) { callback(_this.responseText); } }
_this.send(); } };}
E.g. moveAsyncvar 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
function numbers() { var s0 = yield 0; var s1 = yield 1; var s2 = yield 2;
}
var it = numbers();
“yield” for Iterators
function numbers() { var s0 = yield 0; var s1 = yield 1; var s2 = yield 2;
}
var n0 = it.next();
var it = numbers();
“yield” for Iterators
function numbers() { var s0 = yield 0; var s1 = yield 1; var s2 = yield 2;
}
var n0 = it.next();
var n1 = it.push(10);
var it = numbers();
“yield” for Iterators
function numbers() { var s0 = yield 0; var s1 = yield 1; var s2 = yield 2;
}
var n0 = it.next();
var n1 = it.push(10);
var n2 = it.push(20);
var it = numbers();
“yield” for Iterators
function numbers() { var s0 = yield 0; var s1 = yield 1; var s2 = yield 2;
}
var n0 = it.next();
var n1 = it.push(10);
var n2 = it.push(20);
it.push(30);
var it = numbers();
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
Environment
Program
Interactive Reactive
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 writingLINQ or declarative codein an interactive program...
LINQ to Observable
If you are writingLINQ or declarative codein 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 Arrowvar 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 Lookupvar 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
async { let! res = <async work> ...}
React!
Async Workflow
async { let! res = <async work> ...}
React!
an HTTP Responsean UI Event
a Timer Callbacka Query Response
a Web Servcie Responsea Disk I/O Completion
an Agent Message
How async { ... } Worksasync { let! img = AsyncRead "http://..." printfn "loaded!" do! AsyncWrite img @"c:\..." printfn "saved!" }
How async { ... } Worksasync { 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# Resourceshttp://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
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;}
Source
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;}
Compiled
Conclusion
• Async Programming is difficult
• New programming language / feature / library / model can help
• JavaScript is incredible.
Q & A
Thanks