Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it difficult to implement Go's concurrency patterns in Scala?

There is no doubt about it, Go's syntax is much simpler than Scala's. It also has fewer language features. I quite like the ease with which one can write concurrency code with Go.

As it turns out, performant code is none blocking code ( see http://norvig.com/21-days.html#Answers ) and both Go and Scala are very good at this.

My question is about how one can write programs in Scala that behaves the exact same way as Go programs, by implementing the same concurrency patterns. The first thing that comes to mind is using Futures in a similar way with Channels.

I'm looking for

  • possible implementations of Go's concurrency patterns in Scala
  • if the Go constructs are hard to simulate exactly in Scala
  • code snippets

Any help is much appreciated.

[Edit] A few examples of Go concurrency patterns http://talks.golang.org/2012/concurrency.slide

Fan-in

func fanIn(input1, input2 <-chan string) <-chan string {
  c := make(chan string)
  go func() {
    for {
      select {
        case s := <-input1:  c <- s
        case s := <-input2:  c <- s
      }
    }
  }()
  return c
}

Timeout granularity (one channel vs whole conversation)

Replicating service calls amongst multiple instances and returning the value of the first one to respond. (this is uses a bundle of patterns)

All with: No locks. No condition variables. No callbacks. (Scala Futures use callbacks)

like image 870
Raul Avatar asked Nov 26 '13 00:11

Raul


People also ask

Does Scala support concurrent programming?

Although Scala is still a language on the rise that has yet to receive the wide-scale adoption of a language such as Java, its support for concurrent programming is rich and powerful.

Is Golang better than Scala?

Scala is an object-oriented programming language. Golang is suitable for cloud-native, serverless functions, and, microservices. Scala is the best suitable for monoliths and mini services. The better choice for Stream processing.

Is Golang faster than Scala?

The real key takeaway here is that Golang's native support for web development, which inherently means a smoother and faster process than Scala.

Why is Golang good for concurrency?

Concurrency in Golang is cheap and easy. Goroutines are cheap, lightweight threads. Channels, are the conduits that allow for communication between goroutines. Communicating Sequential Processes, or CSP for short, is used to describe how systems that feature multiple concurrent models should interact with one another.


2 Answers

Go has concurrency features built in to the core language while Scala uses the concurrent package and concurrency primitives from Java's java.util.concurrent.

In Scala it's idiomatic to use either thread-based concurrency or the Actor Model, while Go concurrency is based on Hoare's Communicating Sequential Processes.

Although the concurrency primitives between the two languages aren't the same, it looks like there is some similarity.

In Go concurrency is usually achieved using Goroutines and Channels. There are also other more traditional low level synchronization primitives such as mutexes and wait groups.

In Scala, as far as I know, any class that is declared "Runnable" will be launched in a separate thread, and will not block. This is functionally similar to goroutines.

In Scala Queues can be used to pass information between routines in a similar fashion to Channels in Go.

EDIT: As pointed out by Chuck, "the crucial difference between Scala's Queues and Go channels is that, by default, Go's channels block on write until something is ready to read from them and block on read until something is ready to write to them.". This would need to be written into any Scala implementation of channels.

EDIT 2: As pointed out by Maurício Linhares, "You can do concurrency without visible callbacks in Scala using Async - github.com/scala/async - but you can't do it without callbacks at all, it's just not possible given the way the JVM is currently implemented.".

Thanks to all for the constructive comments.

For more info see:

  • http://golang.org/doc/effective_go.html#concurrency
  • http://www.scala-lang.org/api/current/index.html#scala.concurrent.package
  • http://twitter.github.io/scala_school/concurrency.html
  • https://github.com/scala/async
  • http://akka.io/docs/
like image 158
Intermernet Avatar answered Oct 06 '22 20:10

Intermernet


The short answer is no, it is not difficult.

As you know, concurrency by message passing can operate with blocking or non-blocking synchronisation primitives. Go's channels can do both - they can be unbuffered or buffered - you choose.

A lot is said in JVM languages about non-blocking concurrency being always superior. This is not true in general; it's just a feature of the JVM that threads are quite expensive on it. In response, most JVM concurrency APIs provide only a non-blocking model, although this is unfortunate.

For relatively modest concurrency of up to, say, 1000 JVM threads, blocking concurrency can work very effectively even on the JVM. Because this style doesn't involve any callbacks, it is easy to write and then read later.

The excellent JCSP library from the University of Canterbury is a good way to write Java/Scala/... programs using CSP channels. This is the same style used by Go; JCSP channels are very similar to Go channels, giving the option of unbuffered or buffered (or overwriting fixed buffer) sizes. Its select is called Alternative and has been proven correct by the JCSP developers via formal analysis.

But because the JVM cannot realistically support more than 1000 or so threads, this will not be appropriate for some application areas. But then, there's Go...


Footnote: the current version of JCSP is v1.1rc5 in the Maven repos, contrary to what the JCSP website says.

like image 31
Rick-777 Avatar answered Oct 06 '22 18:10

Rick-777