Live data from Hacker News

Concurrency Models: Go vs Erlang

joneisen.me

21–30 of 46 posts

Re: Concurrency Models: Go vs Erlang

#21

I haven't used Go yet, but love Erlang. Honestly can't imagine a better way to build fault tolerant applications without the help of a supervision tree, errors that bubble up, and fast process restarts. Would love to try out Scala or Go though, but Erlang has served me well so far. Not sure what they offer that's similar to OTP.

There is nothing like the pleasure of using the right tool for the right job.

Using C++, Java or even Python for highly concurrent and fault tolerant systems is a bit like hammering screws into the wall. It can be done with enough effort -- but try a screw driver drill and see what a difference it makes.

The secret sauce is all about fault tolerance, everything else amazingly and logically leads from it: isolation, hot code reloading, distribution (running nodes on multiple machines)

Re: Concurrency Models: Go vs Erlang

#22

I would love to see a comparison between Erlang and Clojure. I do Rails stuff but eventually want to try a functional language in which concurrency isn't an afterthought. I know Erlang achieves concurrency through message passing / message queues, but that's about it. And I have only watched a handful of Rich Hickey talks and have read some introductory material, but I understand that concurrency is achieved through…

The closest thing to Erlang/Otp is (Scala/)Akka. Akka is a library modeled pretty much 1-1 after Erlang/Otp. As a language Scala supports both functional and imperative programming. I recommend you check it out too.

That's not entirely true. Erlang OTP allows for selective receive, and will stash unhandled messages to the side. When a received message is handled, all unhandled messages are retried because the actor may have changed what messages it can handle as a result. This is fine in Erlang - if the actor process crashes for exceeding allocated memory, it has no impact on other actors.

The original Scala Actors did this as well, with predictable results. Scala runs on the JVM, which is a monolithic process. The usage of selective receive meant that over time, actors would accumulate enough unhandled messages to result in a possible OutOfMemoryError, from which there is no recovery on the JVM. Akka does not do selective receive, so it does not entirely follow OTP.

That said, it is inspired by OTP, as evidenced by the original name of the project, Scala OTP. It's just optimized for the JVM.

Re: Concurrency Models: Go vs Erlang

#23

Earlier quoted context omitted.

Check out Akka for Scala/Java - http://akka.io/ I am genuinely puzzled why people embark on building systems which they intend to be massively scalable using languages which don't have a technology like Erlang/OTP or Akka to support distribution across multiple boxes.

This. The fact that, as opposed to to Goroutines, Erlang processes can be transparently running on some other node is the most important difference.

Akka does that as well, and you're right, it's very important for writing declarative, distributed logic. Akka's ActorRef abstracts over the physical location of the actor, just as Erlang's PIDs do.

Re: Concurrency Models: Go vs Erlang

#24

I would love to see a comparison between Erlang and Clojure. I do Rails stuff but eventually want to try a functional language in which concurrency isn't an afterthought. I know Erlang achieves concurrency through message passing / message queues, but that's about it. And I have only watched a handful of Rich Hickey talks and have read some introductory material, but I understand that concurrency is achieved through…

As someone who writes and gives a lot of talks, please don't let them "win you over." A good talk should educate and inspire you, but only your own experience should convince you.

Re: Concurrency Models: Go vs Erlang

#25

Earlier quoted context omitted.

Check out Akka for Scala/Java - http://akka.io/ I am genuinely puzzled why people embark on building systems which they intend to be massively scalable using languages which don't have a technology like Erlang/OTP or Akka to support distribution across multiple boxes.

This. The fact that, as opposed to to Goroutines, Erlang processes can be transparently running on some other node is the most important difference.

In Go, channels can be between boxes, so a channel could be used to trigger or communicate with Go code running on another box.

Re: Concurrency Models: Go vs Erlang

#26
post #3

Erlang's error checking model is a great deal more like Go's than he thinks. Erlang is in the "exceptions are exceptional" camp too, and idiomatic code should not be throwing exceptions around willy-nilly. Go is noticably more fragile with errors. Unhandled exceptions (which are just a fact of life unless you're a perfect programmer) will result in the entire program terminating if you don't have something that handl…

I'm in the same situation as this author. I've used Go a fair bit (and will continue to do so), but have recently been reading "Learn You Some Erlang". So far, I have to say: when it comes to concurrency, hands down, Erlang is better. I don't think many people from the Go side are claiming that Go is better. In fact, I'm pretty sure most just want something similar to Erlang available in a familiar, imperative language. I really hope something similar to OTP emerges for Go; its interface functionality would be useful for that. Process linking and monitoring are absolutely awesome and could only be sloppily hacked into a Go program. However, Go does have some good things: familiarity (syntactically and a lack of surprises), the ability to do some number crunching (something Erlang cannot do), and "structs" that aren't hacked tuples (records).

Honestly, if the author is treading on 'errors vs exceptions', I don't think he has grasped the big picture yet. I'm not even finished with the book and I can tell you that. In fact, I usually hate exceptions, but with how monitoring works, I've found it quite elegant.

One other super important thing to note is that Go's channels don't work over a network. There was an effort to create a "netchan" package to do just this, but so far no one has implemented it cleanly enough to be satisfied.

Re: Concurrency Models: Go vs Erlang

#27
post #11
post #3

Erlang's error checking model is a great deal more like Go's than he thinks. Erlang is in the "exceptions are exceptional" camp too, and idiomatic code should not be throwing exceptions around willy-nilly. Go is noticably more fragile with errors. Unhandled exceptions (which are just a fact of life unless you're a perfect programmer) will result in the entire program terminating if you don't have something that handl…

What's with the "dude" and "totally radical"? The problem with [Char] for bulk text IO was well acknowledged when I wrote bytestring. To quote: "The Haskell String type is notoriously inefficient. We introduce a new data type, ByteString, based on lazy lists of byte arrays, combining the speed benefits of strict arrays with lazy evaluation. Equational transformations based on term rewriting are used to deforest inter…

That sounds cool, and a lot like Erlang's iolists, right? The idea being that lists of byte arrays lets you do IO without all the memcpy that might otherwise be required?

Re: Concurrency Models: Go vs Erlang

#28
post #3

Erlang's error checking model is a great deal more like Go's than he thinks. Erlang is in the "exceptions are exceptional" camp too, and idiomatic code should not be throwing exceptions around willy-nilly. Go is noticably more fragile with errors. Unhandled exceptions (which are just a fact of life unless you're a perfect programmer) will result in the entire program terminating if you don't have something that handl…

> I want a better Erlang than Erlang, but talking yourself into how Go is already better than Erlang isn't going to get you there.

I don't mean to go against this point--it's very true, and I think it's important--but I think this conversation (and most comparisons of Go with Erlang) miss something: Erlang is a platform (it has its own VM, and basically its own OS, just relying on the outer OS as a hypervisor.) Meanwhile, Go isn't a platform, nor is it trying to be. Its designers (Rob Pike and Ken Thompson) already made the platform, first, a long time ago. It was called Unix.

These folks are serious about Unix--they want you to use it. They aren't going to reimplement Unix on top of Unix if they can help it. Unix is already the native set of abstractions they think in terms of[1]. An Erlang "release" (VM + source) should be compared to an entire Unix VM with a disk containing some Go binaries; not just a blob of Go source on its own.

Which is to say, the equivalent of the OTP exists for Go, but it isn't in Go--it's in Unix. OTP services are fundamentally "platform-level" things, and Unix provides them. Where are supervision trees? They're in upstart(8). Where is logging? rsyslog(8) will do it. And so forth.

There's nothing wrong with treating an individual Go process as equivalent to an Erlang process (other than overhead, but that's a problem with your Unix implementation, not with Unix as a platform). Make each Go process (that is, Go binary) have a single responsibility, so it can crash on its own. Then, give it a supervisor who can restart it with the right state. Some processes will still need to be larger, of course--goroutines still serve a purpose--but when the process crashes, you'll lose all of that, so don't put everything in there.

Since you now have multiple Go processes running, you'll need to do IPC. It's Unix: do it with sockets. What do you send on them? You can import a raw struct-specifier header file (or a whole client stub library, like in Erlang) from the include/ directory of each other process that specifies types it will understand, and then speak that "protocol" to it. Or you can use a ProtoBuf spec, to make your process more friendly for third-party use. Or, you can use plain text, like most Unix processes.

A single goroutine in each Go process should manage reads from this socket, deserialize the messages coming from it, and stuff them on channels relevant to their meaning. Then, the other parts of your process that care about external messages can receive on those channels when they wake up. Sounds a lot like an Erlang process inbox, doesn't it?

And so forth.

I think a lot of people are used to languages that provide their own insular inner-platform (Ruby, Python, Erlang, C#, Java, etc.) with its own implementation of everything from process scheduling to message passing to bytecode format to exception-handling, and think that Go is another one of these. Go is not this. Go is, despite all its modern trappings, "better C", and like C, it is heavily bound to Unix for most of the operations stuff that is important to high-availability et al.

Try Go with Unix--it might change your opinion on how many decades of hard-won experience Go is leaning on :)

---

[1] Well, okay, their abstraction-set probably hews closer to Plan 9 these days; Go even uses the term "runes" to refer to Unicode code-points and so forth. Still, all the ideas are backportable without too much of a fight.

Re: Concurrency Models: Go vs Erlang

#29
post #7
post #3

Erlang's error checking model is a great deal more like Go's than he thinks. Erlang is in the "exceptions are exceptional" camp too, and idiomatic code should not be throwing exceptions around willy-nilly. Go is noticably more fragile with errors. Unhandled exceptions (which are just a fact of life unless you're a perfect programmer) will result in the entire program terminating if you don't have something that handl…

> Learn from it, please, I want a better Erlang than Erlang, but talking yourself into how Go is already better than Erlang isn't going to get you there. That's fantastic advice for language advocates everywhere: Rather than pissing on other languages, learn from them, understand what good there is in them, and figure out how to build on that. Sometimes that's difficult: if you're forced to work 10 hours a day with s…

the PHP devs I know really seem to embody a culture obsessed with 'shipping' that I'm not sure can be matched, and I'm really a big fan of it for that, in spite of PHP's huge wackyness.

Re: Concurrency Models: Go vs Erlang

#30

I haven't used Go yet, but love Erlang. Honestly can't imagine a better way to build fault tolerant applications without the help of a supervision tree, errors that bubble up, and fast process restarts. Would love to try out Scala or Go though, but Erlang has served me well so far. Not sure what they offer that's similar to OTP.

A supervisor is easily implemented in Go: http://code.google.com/p/gosup/source/browse/supervisor/supe...
Post reply on HN