When we evaluate rich Internet platforms we tend to focus on the tip of the iceberg, even more so than in conventional software. After all rich Internet applications are about graphics, animation, and other multimedia right? By these measures it it is hard to deny that Silverlight and Flex are very evenly matched - for now. However Flex developers are beginning to notice that Flex lacks a feature that will become increasingly important: Threading.
Retrofitting Flex to make it a suitable platform for multithreaded programming is a very hard problem because of its heritage as a vector animation platform . Assuming that Adobe is willing to go through this painful step the job of making Flex a hospitable platform for multithreaded programing will be far from complete. Why?
Making it possible to do threading is a platform problem. Making it easy is a language problem.
Microsoft made a key decision to develop their own programming languages and they've evolved them in ways that make them extremely well-suited to multi-threaded programming. The results are pretty spectacular. Here are two examples (coming soon to Silverlight):
Parallel Linq is Linq provider that will execute a query in parallel. In some cases parallelizing a query can be as easy as adding "AsParallel" to it like so:
var q = from x in list.AsParallel() where x < 3300 select x;
It just doesn't get much easier than this.
It is interesting to note that it is the programming language that makes this possible. Parallel Linq relies on C# and VB.net's ability to convert Linq expressions into data. The Parallel Linq library then analyzes the expression at run-time and determines the best way of executing it.
2. F#
F# is an extended version of OCaml. Microsoft research added a feature to the language which makes it incredibly easy to write asynchronous applications. This is important given that Rich Internet applications spend a whole lot of time waiting on IO.
Let's take a look at an example of F# function which synchronously retrieves the HTML of a web page:
let getHtml(url:string) = let req = WebRequest.Create(url) use resp = req.GetResponseAsync() use stream = resp.GetResponseStream() use reader = new StreamReader(stream) reader.ReadToEnd()
You can think of the "let" key word is equivalent to C#'s "var" and the "use" keyword as equivalent to C#'s "using." Now let's take a look at what it takes to make this function asynchronous.
let getHtml(url:string) = async { let req = WebRequest.Create(url) use! resp = req.GetResponseAsync() use stream = resp.GetResponseStream() use reader = new StreamReader(stream) return reader.ReadToEnd() }
Can you spot the differences? The obvious one is the "async." Less obvious is the "!" in from of the use keyword. Whenever a "!" is placed in front of a keyword inside of an "async", the operation is executed on another thread and the rest of the computation is suspended until the operation finishes. When the operation finishes control jumps from one thread to another and the rest of the computation is executed. No threading code necessary.
Once again it's the language that makes this possible. How's it done?
In certain contexts F# allows you to overload language keywords and have a custom function execute them instead of the programming language. This makes it possible to do very complex types of transformations. In this case the execution of "use!" is handled by a Use method on an instance of the AsyncBuilder class. It turns out that"async" isn't a keyword, it is actually just an instance of type AsyncBuilder!
This is somewhat similar to implementing the query pattern in C#.The principle difference is that F# supports many more keywords. To find out more check out Don Syme's talk on asynchronous workflows on Channel 9.
A Blessing in Disguise
A few months ago there was quite a bit of controversy when efforts towards JavaScript standardization fell apart. In retrospect I believe that this is the best thing that could've happened to Adobe. They are now free to extend JavaScript to make it a more suitable language for multi-threaded programming.
The real question is: Will they?
I've been disappointed by the evolution of JavaScript. Many of the features recently added seem to be inspired by Python, which is not surprising given the similarities between the two languages. Although Python is a great language for doing dynamic, imperative development it is certainly not my first choice for doing functional programming, and by extension multi-threaded programming. Unfortunately Javascript seems to have inherited some of Python's mistakes. For example Javascript adopted Python's iterator model which is inferior to that of .NET's Enumerable model but that's another blog post entirely. :-)
In the interest of making multi-threaded programming (and a host of other problems in different domains) easier I'd add two features to ActionScript:
1. Code-to-data transformations (which makes Parallel Linq possible)
2. Monad comprehensions (which F# uses to transform synchronous code into asynchronous code)
If Flex stays a one language platform and Actionscript continues to evolve in Python's direction instead of Haskell's direction I see a grim future ahead for the platform. I hope I'm wrong because competition is a healthy thing :-).