Welcome to Try Joinads!
This web site is an interactive tutorial that introduces joinads - a research extension of the F# language. The tutorial presents several uses of the extension. It focuses on concurrent, parallel and asynchronous programming, but it also shows several examples from other domains, including parsers and option values. Aside from uses of joinads, there are also several sections that discuss how to implement joinads for other types of values or computations.
Aside from joinads, the web site also includes examples of encoding various abstract computation types (such as monads, monoids, applicative functors and monad transformers) using F# computation expressions. These use mostly standard F# computation expressions, with an extension for applicative functors and accompany the article F# Computation Zoo.
The tutorial uses an Interactive F# console hosted in a web browser using Silverlight (Windows or Mac) or Moonlight (Linux), so you can run the tutorials in your browser and experiment on your own. The console is based on an open-source release of the F# compiler. A research implementation of the F# compiler that implements joinads is also available.
If you have any comments or suggestions regarding the tutorials, or if you have another interesting implementation of joinads or an extension of the F# compiler that could be added, please get in touch: tomas@tomasp.net or @tomaspetricek.
The following article is the best place to start if you haven't seen joinads before. It shows a basic example and includes links to other resources.
Introduction shows a basic example of parallel programming with joinads in F# and provides a general overview of the concept, as well as basic Haskell example.
Publications provides links to academic publications related to joinads. These contain more details about joinad as an algebraic structure and about the language feature design.
The following articles show several examples of using joinads for concurrent, parallel and reactive programming. They use an implementation of joinad operations that is available in standard joinads library.
Asynchronous workflows and joinads shows how to use joinads in asynchronous programming. Applications include asynchronously waiting for multiple computations or waiting for the first computation that produces certain value.
Task-based parallelism has been already demonstrated in the introduction. This tutorial shows a more complete example that uses joinads for recursive tree processing with short-circuiting.
Agent-based programming
can benefit from the notation used by joinads when implementing agent (MailboxProcessor
) that
uses the Scan
method. This tutorial shows several examples.
Concurrent programming using joins shows a library that uses joinads to embed join calculus in F#. The library can be used for writing concurrent primitives, such as blocking collection and others.
The following articles briefly explain how to implement joinads for several standard types
of computations including option
values and F# asynchronous workflows.
Programming with option values
shows the implementation of joinad computation builder for the option<'T>
type. The sample
uses parallel composition and choice.
Writing parsers with joinads shows that joinads are useful in areas other than just concurrent and parallel programming. For parsers, joinads make it possible to express the intersection of languages.
Joinads for asynchronous workflows
explains how to add joinad operations to the Async<'T>
type. The sample also provides more
details on how aliasing is used in joinads.
Functional monads and laws discusses the definition of computation expression for a monad in terms of bind and return and shows syntactic equalities that correspond to well-known monad laws.
Sequencing of monads shows how (untracked) effects can be handled in computation expressions. The section shows both approaches - for monadic containers and for monadic computations.
Monadic control flow extends the previous definitions of
a monad with additional control flow constructs including for
and while
loops and
exception handling constructs.
Additive parsers shows one alternative syntax for working with computations that are monadic and monoidal at the same time. The syntax is demonstrated using parser combinators.
Additive sequences shows an alternative syntax for working with monadic and monoidal computation. The syntax emphasizes the monoidal structure and is demonstrated using lists.
Layered monads demonstrates a computation expression that can be used to work with computations that are formed by composing monads. The example is based on monad transformers known from Haskell.