TryJoinads (VII.) - Implementing joinads for async workflows
The article Asynchronous workflows and joinads gives numerous
examples of programming with asynchronous workflows using the match!
construct.
Briefly, when matching on multiple asynchronous workflows, they are executed in
parallel. When pattern matching consists of multiple clauses, the clause that matches
on computations that complete first gets executed. These two behaviours are
implemented by the Merge
and the Choose
operation of joinads. Additionally,
asynchronous workflows require the Alias
operation, which makes it possible to
share the result of a started asynchronous workflow in multiple clauses.
In this article, we look at the definition of the additional AsyncBuilder
operations that enable the match!
syntax. We do not look at additional examples
of using the syntax, because these can be found in a previous article.
Note: This blog post is a re-publication of a tutorial from the TryJoinads.org web page. If you read the article there, you can run the examples interactively and experiment with them: view the article on TryJoinads.
Published: Friday, 23 March 2012, 5:21 PM
Tags:
asynchronous, f#, research, joinads
Read the complete article
TryJoinads (VI.) - Parsing with joinads
In functional programming, parser combinators are a powerful way of writing parsers. A parser is a function that, given some input, returns possible parsed values and the rest of the input. Parsers can be written using combinators for composition, for example run two parsers in sequence or perform one parser any number of times.
Parsers can also implement the monad structure. In some cases, this makes the parser
less efficient, but it is an elegant way of composing parsers and we can also benefit
from the syntactic support for monads. In this article, we implement a simple parser
combinators for F# and we look what additional expressive power we can get from the
joinad structure and match!
construct. This article is largely based on a
previous article "Fun with Parallel Monad Comprehensions", which can be found on the
publications page.
Note: This blog post is a re-publication of a tutorial from the TryJoinads.org web page. If you read the article there, you can run the examples interactively and experiment with them: view the article on TryJoinads.
Published: Wednesday, 21 March 2012, 4:27 PM
Tags:
f#, joinads, research
Read the complete article
TryJoinads (V.) - Implementing the option joinad
This article shows how to implement the joinad structure for one of the
simplest monads - the option<'T>
type. This is a slightly oversimplified example.
The match!
construct can be used to write patterns that specify that a monadic
value (in this case option<'T>
) should contain a certain value, or we can specify
that we do not require a value. When working with options, this means the same thing
as matching the value against Some
and against _
, respectively.
However, the example demonstrates the operations that need to be implemented and their type signatures. Later articles give more interesting examples including parsers and asynchronous workflows (and you can explore other examples if you look at the FSharp.Joiands source code at GitHub).
Note: This blog post is a re-publication of a tutorial from the TryJoinads.org web page. If you read the article there, you can run the examples interactively and experiment with them: view the article on TryJoinads.
Published: Friday, 2 March 2012, 1:24 PM
Tags:
f#, research, joinads
Read the complete article
TryJoinads (IV.) - Concurrency using join calculus
Join calculus provides a declarative way of expressing asynchronous synchronization
patterns. It has been use as a basis for programming languages (JoCaml and COmega), but also
as a basis for libraries (embedded in C# and Scala). Using joinads, it is possible to
embed join calculus in F# with a nice syntax using the match!
construct. Formally,
join calculus does not form a monad, but it can be viewed as a version of joinad
as described in the first paper on joinads.
The programming model is based on channels and join patterns. A channel can be viewed as a thread-safe mailbox into which we can put values without blocking the caller. In some sense, this is quite similar to F# agents. A join pattern is then a rule saying that a certain combination of values in channels should trigger a specific reaction (and remove values from the channels). The ability to match on multiple channels distinguishes join calculus from F# agents.
Note: This blog post is a re-publication of a tutorial from the TryJoinads.org web page. If you read the article there, you can run the examples interactively and experiment with them: view the article on TryJoinads.
Published: Wednesday, 22 February 2012, 5:38 PM
Tags:
f#, research, joinads, asynchronous, parallel
Read the complete article
TryJoinads (III.): Agent-based programming
Another area where the match!
syntax can be used is when programming with F# agents,
implemented by the MailboxProcessor
type. Formally, agents do not form the monad
structure in a useful way - when programming with agents, we do not compose a new agents,
but instead we write code that (imperatively) receives messages from the agent's mailbox
and handles them.
This article demonstrates an agent { ... }
computation builder that can be used for
implementing the body of an agent. Normally, the body of an agent is an asynchronous
workflow. The code in the body uses let!
to perform asynchronous operations, most
importantly to call inbox.Receive
to get the next message from the inbox. When the
agent intends to handle only certain kinds of messages, it can use inbox.Scan
. When
using the agent
builder, pattern matching on messages can be written using match!
and
it is possible to write code that ignores certain types of messages simply by writing an
incomplete pattern matching.
Note: This blog post is a re-publication of a tutorial from the TryJoinads.org web page. If you read the article there, you can run the examples interactively and experiment with them: view the article on TryJoinads.
Published: Monday, 20 February 2012, 12:36 PM
Tags:
joinads, research, f#, parallel, asynchronous
Read the complete article
TryJoinads (II.): Task-based parallelism
The implementation of joinad operations for the Task<'T>
type is quite similar to the
implementation of Async<'T>
, because the two types have similar properties. They both
produce at most one value (or an exception) and they both take some time to complete.
Just like for asynchronous workflows, pattern matching on multiple computations using
match!
gives us a parallel composition (with the two tasks running in parallel) and
choice between clauses is non-deterministic, depending on which clause completes first.
Unlike asynchronous workflows, the Task<'T>
type does not require any support for
aliasing. A value of type Task<'T>
represents a running computation that can be
accessed from multiple parts of program. In this sense, the type Async<'T>
is more
similar to a function unit -> Task<'T>
than to the type Task<'T>
itself.
The key difference between tasks and asynchronous workflows is that the latter provides better support for writing non-blocking computations that involve asynchronous long-running operations such as I/O or waiting for a certain event. Tasks are more suitable for high-performance CPU-intensive computations.
Note: This blog post is a re-publication of a tutorial from the TryJoinads.org web page. If you read the article there, you can run the examples interactively and experiment with them: view the article on TryJoinads.
Published: Friday, 17 February 2012, 1:10 PM
Tags:
research, f#, parallel, joinads
Read the complete article
TryJoinads (I.) - Asynchronous programming
Asynchronous workflows provide a way of writing code that does not block a thread
when waiting for a completion of long-running operation such as web service call,
another I/O operation or waiting for the completion of some background operation.
In this article, we look at the new expressive power that joinads add to
asynchronous workflows written using the async { ... }
block in F#.
Note: This blog post is a re-publication of a tutorial from the TryJoinads.org web page. If you read the article there, you can run the examples interactively and experiment with them: view the article on TryJoinads.
Published: Monday, 13 February 2012, 5:35 PM
Tags:
f#, research, joinads
Read the complete article
Introducing TryJoinads.org
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
matching using 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.
I won't say more about joinads in this post, because you can now easily try joinads yourself...
Published: Monday, 13 February 2012, 4:21 PM
Tags:
parallel, asynchronous, f#, research, links, joinads
Read the complete article
Extending Monads with Pattern Matching (Haskell 2011)
Some time ago, I wrote a paper about joinads and the match!
extension
of the F# language. The paper was quite practically oriented and didn't go into much details about
the theory behind joinads. Many of the examples from the F# version relied on some
imperative features of F#. I believe that this is useful for parctical programming, but I
also wanted to show that the same idea can work in the purely functional context.
To show that joinads work in the pure setting, I created a Haskell version of the idea. The implementation (available below) is quite simple and consists of a pre-processor for Haskell source files and numerous examples. However, more important part of the recent work of joinads is a more detailed theoretical background.
The theory of joinads, together with the language design of Haskell extension that implements it is discussed in a paper Extending Monads with Pattern Matching, which was accepted for publication at the Haskell Symposium 2011. Here is the abstract of the paper:
Sequencing of effectful computations can be neatly captured using monads and elegantly written using
do
notation. In practice such monads often allow additional ways of composing computations,
which have to be written explicitly using combinators.
We identify joinads, an abstract notion of computation that is stronger than monads and captures
many such ad-hoc extensions. In particular, joinads are monads with three additional operations:
one of type m a -> m b -> m (a, b)
captures various forms of parallel composition,
one of type m a -> m a -> m a
that is inspired by choice and one of type m a -> m (m a)
that captures aliasing of computations. Algebraically, the first two operations form a
near-semiring with commutative multiplication.
We introduce docase
notation that can be viewed as a monadic version of case
. Joinad laws
make it possible to prove various syntactic equivalences of programs written using docase
that are analogous to equivalences about case
. Examples of joinads that benefit from the notation
include speculative parallelism, waiting for a combination of user interface events, but also
encoding of validation rules using the intersection of parsers.
Links to the full paper, source code and additional materials are available below.
Published: Wednesday, 20 July 2011, 12:19 AM
Tags:
parallel, writing, research, haskell, joinads
Read the complete article
Variations in F#: Research compiler with Joinads and more!
In this article, I'll write about an experimental extension for F# that I call joinads. If you're following my blog, you may have seen an academic paper that I wrote about it some time ago. Anyway, the motivation for the extension is that there are many useful programming models for reactive, concurrent and parallel programming that would deserve some syntactic support in the programming language.
For example, when programming with futures (the Task<T>
type),
you may want to implement logical "or" operator for tasks that returns true
immediately when the first task completes returning true
. When programming with
events (the IObservable<T>
type),
we'd like to wait for the event that happens first. Finally, when programming using agents,
we sometimes need to wait only for certain types of messages. All of these problems can
be solved, but require the use of (sometimes fairly complicated) functions. Joinads make
it possible to solve them directly using the match!
syntax. For example, here
is the "or" operator for tasks:
1: future { 2: match! after 100 true, after 1000 false with 3: | !true, _ -> return true 4: | _, !true -> return true 5: | !a, !b -> return a || b }
I'll write more about this example (and the implementation) in a later article. This article focuses on the compiler extension itself. I created a first implementation of the idea above during my internship with Don Syme at MSR Cambridge, but then changed it quite a bit when writing the academic paper mentioned above. However, I never released the source code.
Thanks to the open-source release of F# it is now quite easy to modify the F# compiler and make the modifications available, so I decided I should finally release my F# extensions. I also recently blogged about encoding idioms (also called applicative functors) in C#. I was wondering how to do that in F# and so I also created a simple extension computations based on this abstraction. The support for idioms is just an experiment, but it could be useful, for example, for programming with formlets. You'll find more about it at the end of the article.
You can find the source code on my GitHub (there is also a link compiled binaries at the end of the article). The source code is cloned from an F# Mono repository, which means that it should build on Linux and MacOS too.
Full name: JoinadsDemo.future
Full name: JoinadsDemo.after
type: bool
implements: IComparable
implements: IConvertible
implements: IComparable<bool>
implements: IEquatable<bool>
inherits: ValueType
type: bool
implements: IComparable
implements: IConvertible
implements: IComparable<bool>
implements: IEquatable<bool>
inherits: ValueType
Published: Friday, 25 March 2011, 12:04 AM
Tags:
research, f#, joinads
Read the complete article
Reactive, parallel and concurrent programming in F# (PADL 2011)
Don Syme blogged about a paper on the F# Asynchrounous Programming Model that I helped to write. Without any doubt, the asynchronous programming features of F# are one of the reason for its success and also influence other teams in Microsoft. However, I'm very glad that there is now also an academic paper that makes this idea accessible to the academic community. I believe that the ideas could evolve in interesting ways when used in other programming languages and also, it is now easier to create research projects that build on top of the F# model.
Don already mentioned that we have another paper accepted at PADL. The paper describes work that started during my internship at Microsoft Research in 2009. It presents a simple language extension for computation expressions that makes them even more useful in some reactive, concurrent and parallel programming models. Note that this is only a research project and there are currently no plans to support the extension in the F# language (although, if there will, eventually, be an open-source F# release, then you'll hear about the extension again...)
Here is the abstract of the paper (accepted at PADL 2011) and a PDF download link:
Joinads: A retargetable control-flow construct for reactive, parallel and concurrent programming
Modern challenges led to a design of a wide range of programming models for reactive, parallel and concurrent programming, but these are often difficult to encode in general purpose languages. We present an abstract type of computations called joinads together with a syntactic language extension that aims to make it easier to use joinads in modern functional languages.
Our extension generalizes pattern matching to work on abstract computations. It keeps a familiar syntax and semantics of pattern matching making it easy to reason about code, even in a non-standard programming model. We demonstrate our extension using three important programming models – a reactive model based on events; a concurrent model based on join calculus and a parallel model using futures. All three models are implemented as libraries that benefit from our syntactic extension. This makes them easier to use and also opens space for exploring new useful programming models.
- Download the full text (PDF, pre-publication draft)
The paper can still be revised before the final publication, so any comments and suggestions for improvement are largely welcome. You can contact me either via comments (below) or using email at tomas@tomasp.net. I would be also quite interested to hear from anybody who would like to implement similar feature in other programming languages (for example Haskell or Scala).
Published: Monday, 25 October 2010, 12:00 AM
Tags:
f#, research, links, joinads
Read the complete article
Internship project: Reactive pattern matching
I already mentioned that I was doing my second internship with Don Syme at Microsoft Research in Cambridge. This time, I was in Cambridge for 6 months from October until April, so it has been more than a month since I left, but as you can guess I didn't have time to write anything about the internship until now... There isn't much to say though, because the internship was simply fantastic. Cambridge is a beautiful place (here are some autumn and winter photos), the Microsoft Research lab in Cambridge is full of smart people, so it is a perferct working environment (except that you realize that you're not as clever as you think :-)). Also, it is just a few meters away from the Computer Laboratory of the Cambridge University, so there are always many interesting talks and seminars. So, big thanks to Don Syme, James Margetson and everyone else who I had a chance to work with during the internship.
One of the reasons why I didn't have much time to write about the internship earlier is that I was invited to the Lang.NET Symposium shortly after the end of the internship. I had a chance to talk about my project there as well and there is even a video recording from the talk (the link is below), so you can watch it to find out more about my recent F# work.
Published: Sunday, 17 May 2009, 11:00 PM
Tags:
random thoughts, universe, parallel, asynchronous, joinads
Read the complete article