If you have been following my blog, you've probably already heard of joinads. It is a research extension of F# computation expressions (or monads in Haskell). The extension makes computation expressions more useful in domains like parallel, concurrent and reactive programming. However, it can be used for any type of computation including, for example, parsers. If you're interested in detailed description, you can find it in two academic papers that I blogged about previously: PADL 2011 and Haskell 2011.
The extension adds a keyword
match! - as the syntax suggests, it is akin to pattern
match, but instead of pattern matching on values, you can pattern match
on computations like
Async<'T> (or on other monadic values). Just like other features of
computation expressions, the
match! syntax is translated to applications of several
methods defined by the computation builder.
Try it at TryJoinads.org
I won't say more about joinads in this post, because you can now easily try joinads yourself! Previously, the only option was to use a prototype F# compiler from command line. However, a recent open-source release of F# also includes the source code of a Silverlight-based F# compiler and a control used at TryFsharp.org.
This inspired me to create a web site where you could play with the
match! extension in
your web browser. The web site runs a modified version of the F# compiler and contains
tutorials that demonstrate several applications:
- Experiment with joinads in F# at: TryJoinads.org
At the moment, the web site contains only a few tutorials, but I'll keep adding more as I publish them on this blog. To whet your appetite, the following list shows applications that I'm working on (and that I'll publish on the blog in the next few days).
TryJoinads (I.): Asynchronous programming shows how to use joinads to asynchronously wait for multiple computations or to wait for the first computation that produces a certain value.
TryJoinads (II.): Task-based parallelism shows how to use joinads for parallel programming using the .NET
Task<'T>type. An example implements recursive tree processing.
TryJoinads (III.): Agent-based programming demonstrates how to simplify your F# agents with joinads (the
MailboxProcessor<'T>type) and avoid the (ugly)
Scanmethod when waiting for certain messages.
TryJoinads (IV.): Programming with joins shows a library that uses joinads to embed join calculus in F#.
TryJoinads (V.): Implementing the option joinad explains the joinad operations by implementing a simple computation builder for the
TryJoinads (VI.): Parsing with joinads shows how to implement simple parser combinators that support the
match!notation. Joinads capture intersection of languages and a choice without back-tracking.
TryJoinads (VII.): Implementing asynchronous builder explains how to implement joinad operations for F# asynchronous workflows (
Async<'T>type) and how the aliasing operation works.
Source code & contributions
One of my motivations for working on TryJoinads.org was to
make it possible for others to experiment with the extension. The above list of possible
match! is definitely not complete and I believe there are numerous other
interesting computation expressions that could use the feature.
Using the Silverlight-hosted F# compiler, you can write your own joinads. To make it possible to easily share your experiments, I published the entire source code of the TryJoinads.org project on GitHub. If you implement your own computation expression that uses joinads, I'd be more than happy to include it as one of the tutorials. You can find more information about contributing on the GitHub page of the project.