Asynchrony, Concurrency and Parallelism

0 Index

1 Introduction
2 Microsoft .NET
2.1 Reactive Extensions for .NET (Rx)
2.2 Async
2.3 F# First-Class Events
2.4 Five-Spice Powder
3 Google Go
3.1. The Language
3.2 Practical Matters
3.3 Origins
4 References

1 Introduction

Concurrency and (orthogonally) parallelism have become unavoidable topics in the last couple of years.

In this post I’ll talk about interesting recent developments in a couple of programming languages and environments.

2 Microsoft .NET

In the realm of C#, F# and .NET a couple of interesting developments have taken place recently.

2.1 Reactive Extensions for .NET (Rx)

Erik Meijer dualized the concepts of IEnumerable/IEnumerator (IE) into the concepts of IObservable/IObserver (IO).

All four concepts already existed, roughly, but Meijer showed how they were duals of eachother. Whereas IE are pull-based collections where the client pulls out the values of the collection, either explicitly, by working with an IEnumerator or using a foreach over an IEnumerable, or implicitly, by using LINQ sequence operators like Where, Select and SelectMany, IO are push-based collections where the values are pushed towards the client. Since IE and IO are duals, it is possible to create views of one or the other by using ToEnumerable and ToObservable.

As a dual, IO collections also support LINQ sequence operators and therefore become compositional which is a very powerful notion.

Meijer has shown how to implement drag-and-drop in a GUI program via composition over first-class events as realized via IO collections. Traditional C#/.NET events are projected into IO collections via convenience functions and then composed via LINQ sequence operators to produce a drag-and-drop IO collection.

2.2 Async

C# and VB now has a notion of asynchrony via the new async feature. Whereas IE and IO are used for multi-value collections, Async is for single-value returns. A few keywords spread throughout the code is enough to turn a sequential program into a fully asynchronous one, with nasty nested callbacks in the compiler generated code. This means that lazy programmers, and who doesn’t want to be lazy, can easily introduce asynchrony in the code to have a responsive, non-blocking UI, without thinking explicitly about threads.

2.3 F# First-Class Events

I believe Rx was inspired by F# first-class events. I’m not very familiar with F# events yet but in general F# is a very concise and interesting language to play with.

2.4 Five-Spice Powder

Meijer refers to this zoo of constructs as a kind of Chinese five-spice powder for programs, taking the previous analogy of Yin and Yang (IE and IO) further:

  • single-value synchronous eager method: x foo () …
  • single-value synchronous lazy method: Lazy<x> foo () …
  • single-value asynchronous method: async Task<x> foo () …
  • multi-value synchronous lazy method: IEnumerable<x> foo () …
  • multi-value asynchronous eager method: IObservable<x> foo () …

See references for a link to the talk where Meijer talks about these constructs.

3 Google Go

3.1. The Language

Go is the new’ kid on the block. It is a quite new programming language (3 years old now), developed by Rob Pike,  Robert Griesemer and Ken Thompson. I have no practical experience with Go yet but its built-in concurrency primitives are extremely alluring to any would-be concurrist.

(‘ Not quite fair, since Go is now 3 years old, C#/VB async is newer and Go is a development of concepts dating back decades. But it’s not alone in this respect.)

Rob Pike has given a number of interesting talks about Go and its origins. I highly recommend watching them all. See references  Pike presents a lot of insights and knowledge in a short period of time, so often it can be interesting to watch a video more than once.

The basic concurrency primitives in Go are the following constructs:

  • Goroutine; a concurrent process
  • Channel; a medium to and/or from a process

To launch a goroutine, just put go before the call. The code that follows the goroutine call will not be blocked. To communicate to and from a goroutine, one does not use global or shared mutable state. Instead a goroutine function can return a channel and it can also have one or more channels as input and as part of structured values passed to it.

These two concepts allow programs which would otherwise be very hard to express in languages like Java to be trivially expressed in Go.

Importantly, a go channel is a first-class value. This means a channel can be passed around to functions, stored structures and even sent over other channels. Channels are compositional! This allows for some very funky stuff indeed.

Say you have two channels and want to process values as fast as they come out but don’t want to blockingly wait for a value from either channel? Then you can create a for loop and have a select statement inside which will pick the first available value from either channel and the loop will go around. This can be used to multiplex (mux) two or more channels together into a new one.

Also of interest: Go does not have inheritance or traditional classes; instead it has structs, a kind of duck-typing and a way to associate functions with values (either primitive, like booleans and numbers, or structured, like structs; I’m not sure if they can be applied to channels).

3.2 Practical Matters

Programs in Go compile lightning fast. The demos I’ve seen are very very impressive to look at for someone used to working with Visual Studio. It’s almost embarassing to watch in retrospect. Rob Pike often talks about one of the reasons for Go was not just concurrency but the fact that many modern languages, although they may be fast at run-time, are excruciatingly slow to compile. There are several Go compilers but the fastest you’d use for development purposes compiles many large programs in less than a second – that’s faster than many compiled programs start up. Things like that could start to become addictive.

Go is interest not just because of what it adds but because of what it doesn’t add (since it wasn’t there to begin with, you can’t really say anything was taken away, unless you look at Go as a delta from another language).

The standard library for Go is quite comprehensive and appears very well-designed. It does look sketchy in places but it covers many areas and has a very simple layout and structure.

The compositionality of Go channels might (I’m not sure) be somewhat compromised due to a lack of generics. Why are generics interesting? Because generics is at the heart of LINQ, as defined in .NET, C# and VB. Crucially, it enables strongly-typed LINQ sequence operators to be generically defined. If this is (or will become) possible in Go, we are in for a treat. I trust go inventor Rob Pike (et al) to make the right design and not include any new feature unless it’s really clean and doesn’t compromise the elegance, simplicity and efficiency of Go. For now, channels are still compositional and that is very powerful.

The .NET genericity also has its limits. In particular .NET does not have a kind system. I’m not convinced how important a kind system is but it does allow fully generic definition of monads.

3.3. Origins

In the references I’ve added links to several cool Go talks. The most recent one I’ve watched is old and about Newsqueak – a previous language Rob Pike designed but Go has the same concurrency primitives so the lessons of Newsqueak can be carried over directly to Go! The interesting thing about this particular video is the compositional definition of power series via channels and, even more practically interesting, a definition of a UI environment as 3 basic channels (mouse, keyboard, graphics). This is of course simplified but the cool bit is how signals are multiplexed over channels. Once you have first-class channels, you can do a lot of interesting things. Easily mock stuff, etc.

Piece of advice to the Go folks: you may consider skipping Go 2, as it is considered harmful (sorry for the pun ;‐)

4 References


About xosfaere

Software Developer
This entry was posted in Computer Science, Declarative, Imperative, Paradigm, Software, Technical, Uncategorized and tagged , , , , , , , , , , , , , , , , , , . Bookmark the permalink.

2 Responses to Asynchrony, Concurrency and Parallelism

  1. Aasemoon says:

    Oh awesome… impeccable timing. =) I’ve recently been looking into Go also… this help!

  2. Pingback: Asynchrony, Concurrency and Parallelism | Ragnarok Connection

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s