Live data from Hacker News

Go hits the concurrency nail on the head

eli.thegreenplace.net

291–300 of 318 posts

Re: Go hits the concurrency nail on the head

#291

Do people really find CSP a good approach to concurrency? I've always thought that channels were a relatively poor choice of fundamental primitive -- channel-based concurrency is tricky to get right and not very composable. Most viable concurrency primitives are in some sense equivalent (you can build condition variables out of channels and vice-versa, say) but that doesn't mean they're equally good. Java has per-obj…

Exactly. I get the feeling that people who claim golang gets concurrency right have not used the much more powerful constructs in the Java standard library. They keep getting better with things like CompletableFuture which was added in Java 8, and coroutines which are going to be added to the JVM sometime down the line by means of project Loom.

Composability in golang concurrency constructs is non-existent. Having to manually manage channels to indicate errors, return values, and completion is error prone and does not compose, and is subject to race conditions. I don't see anything that I can do in golang that I wouldn't be able to do using Java's futures, while still being more composable and easier to reason about in Java.

Re: Go hits the concurrency nail on the head

#292

Or you could just use the Actor model, which I like much better than CSP. (Or at least I think I'll like it better when I finally understand it.)

The Actor model is trivially implementable with CSP.

But not in golang (see generics, or lack thereof).

Re: Go hits the concurrency nail on the head

#293
post #80

Leave aside the extremely interesting engineer behind th go scheduler and goroutine. The abstraction that goroutine provides is a simple, indipendent, isolated unit of execution. You start it, and that is all you can do with it. No way to set priorities, decided when to stop it or inspect it. After the goroutine start the only interface that you get is a channel where to push and pop stuff from. Which is just too lim…

I'm not sure how people can't see that futures (as in Java's CompletableFuture) is much superior to golang's approach exactly due to the reasons you mention.

You can also have the actor approach (e.g. Akka) to set priorities, have monitoring hierarchies, and introspection.

Re: Go hits the concurrency nail on the head

#294
post #98
post #43

This picture is a bit rosey, no? Literally the only deadlock I've come across in years has been in go.

What fraction of the concurrent programming you've done over those years has been in Go?

A language claiming to be designed to solve the concurrency issue needs to have a better story than what golang offers.

Re: Go hits the concurrency nail on the head

#295

I think the author might be overstating how unique Go’s position is in terms of making concurrency easier. Haskell has the best concurrency story of any language I’ve used. Super lightweight green threads, simple concurrency primitives like MVar and STM, good performance (possibly requiring tweaks, but not bad out of the box). Referential transparency (by which I basically mean immutable data) makes sharing data acro…

I think the BEAM languages "pure functions... well except for message passing" is perfect for concurrency. With haskell you have to use monads which are less convenient. And idiomatic BEAM defaults to actor model if you consider OTP to be "out of the box (you should)". Finally, pattern matching function guards are incredibly useful for parsing incoming messages that might be polymorphic. Haskell is kind of designed t…

Well, there are trade offs in both directions. Haskell has a steep learning curve and no clear one choice for concurrency, while Erlang is more approachable, has a built-in answer for concurrency, and well-established patterns for building fault tolerant applications at scale.

On the other hand, Haskell’s system has more flexibility, offering a few powerful primitives which can be used as building blocks for higher level abstractions. On top of that it is a general purpose language capable of implementing traditional imperative patterns, etc, so you only need to use the concurrency when it makes sense, rather than using it for all stateful and IO operations as in Erlang/Elixir. Its performance ceiling is certainly higher. I don’t think monads in Haskell are a problem except in terms of the learning curve.

All in all, which one to use, if either, will depend on the circumstances. But both of them should be a part of any thorough discussion of languages which are “good at concurrency”. ;)

Re: Go hits the concurrency nail on the head

#296

Earlier quoted context omitted.

I think syntax actually matters a lot more then people tend to give credit for in a language's success. I suspect this is why functional languages have struggled to became very popular while languages with C like syntax have added some functional features instead. The learning curve for imperative programming structure just seems easier for people to understand and work with.

Yeah, but is it because people actually like the syntax? Some languages seem to be attractive to people right from the start, like Python. Some take a while to grow on you but then you realise their brilliance and don't want anything else, like Lisp. C isn't either of those.

Really? Python's syntax looks clean at first OK then later I realized that it has no variable declaration (and old memories of time lost in BASIC due to spelling errors start coming back), no static typing, is slow and isn't particularly multicore friendly .. uhm how about using Go instead? (No I don't know Go but I'm quite sure I can learn it without too much difficulties)

Re: Go hits the concurrency nail on the head

#297
post #71

Earlier quoted context omitted.

I think syntax actually matters a lot more then people tend to give credit for in a language's success. I suspect this is why functional languages have struggled to became very popular while languages with C like syntax have added some functional features instead. The learning curve for imperative programming structure just seems easier for people to understand and work with.

The impact of syntax is really undervalued. Syntax matters because many people are exposed to new languages through familiarity with other languages, as opposed to cramming a guide in isolation. And since programming languages are for humans, the cognitive load of understanding through reading and expressing through writing depends on one's ability to map the concepts to the code and vice versa. This is easier when s…

My simple smell test for language syntax readability is whether you can write a conditional statement with a multiline condition in it, without it looking ugly, and with the condition being clearly separate from the body. For example, in Lua or Ruby:

   if
      something()
      or other()
   then
      do_whatever()
   end
It's very easy to read; your eye doesn't "stumble" anywhere it doesn't have a reason to. In C (and Java, C# etc), on the other hand:

   if (something() 
         || other()) {
      do_whatever()
   }
This makes for some confusing indentation, and now it's hard to distinguish what's condition and what's body! Sometimes people indent the entire condition to make it clearer:

   if (  something() 
         || other()) {
      do_whatever()
   }
but now you have holes in the middle which draw attention to that spot for no good reason. Or you can put ){ on a separate line:

   if (
      something() 
      || other()
   ) {
      do_whatever()
   }
but so much punctuation hanging by itself is still an eyesore. And Python is hardly better:

   if (
      something()
      or other()
   ):
      do_whatever()
Go doesn't need the () in condition, so it's slightly more tolerable if you do that (but go fmt will object):

   if
      something() 
      || other()
   {
      do_whatever()
   }
But I'll take the Lua/Ruby syntax any day of the week.

That's just one example. In retrospect, I think that C-style syntax was a bad idea in general, and adopting it as the "default syntax" across a large part of the industry was a monumental mistake. It favored compactness and speed of writing over readability and clarity. I really wish something like Modula or Ada would become the syntactic basis of modern languages today. I'd rather spend a few more keystrokes typing out things like "var" and "end", but end up with code that reads smoothly in a code review, or when debugging some ancient codebase.

Re: Go hits the concurrency nail on the head

#298

Earlier quoted context omitted.

I've found that being mainstream is the most important factor in choosing tooling. Being mainstream has incredible advantages. It means you're going to find lots of help, resources, answers to questions, sample code, and high quality and well maintained libraries.

I'm sorry but that argument does not hold much water. Any developer with [maybe] the exception of people fresh out of school can and should be able to learn new things. Fast. On-the-job. If you really believe that you're going to use X because it's mainstream and really popular and be okay you're kidding yourself. Also, as you grow older, you learn to see the matrix and appreciate new things that come along when/afte…

> If you really believe that you're going to use X because it's mainstream and really popular and be okay you're kidding yourself.

Actually, if there's anything that someone fresh out of school learns in the industry, is that you do use things that are mainstream and really popular (in the particular niche you're targeting), because that's what your colleagues and management expect.

OTOH, when people come and say, "we'll rewrite this in X - it's the hot new thing, and it can do it all so much better, so don't worry about IDE support etc!", and push it through, the usual consequence 3-5 years later is a bit-rotting codebase that is hard to work on and maintain, because the people who pitched it have moved on, the tooling was never great and now doesn't even see bug fixes, and new developers on the team have to undergo a long initial ramp-up process to be able to do anything.

Sometimes it works out, sure. Usually when the hot new thing becomes mainstream eventually. But most of them don't, so unless you like to gamble, the safest bet is to wait and see and then adopt it. Let someone else be the guinea pig. The more immediate productivity gain is very, very rarely worth the pain.

Re: Go hits the concurrency nail on the head

#299

Do people really find CSP a good approach to concurrency? I've always thought that channels were a relatively poor choice of fundamental primitive -- channel-based concurrency is tricky to get right and not very composable. Most viable concurrency primitives are in some sense equivalent (you can build condition variables out of channels and vice-versa, say) but that doesn't mean they're equally good. Java has per-obj…

I think composability especially is the key point. With futures (and async/await sugar on top), everything is naturally composable. It's much trickier with channels.

Re: Go hits the concurrency nail on the head

#300

Earlier quoted context omitted.

And CSP is trivially implementable using the Actor model. What's your point?

My point is that you can program with the actor model in Go, if you want to.

You can program with it in C, if you want to.

But Go is clearly not designed with that in mind. It's a language that is very opinionated about how concurrency should work. And so whether it's a good opinion or a bad opinion becomes very important.

Post reply on HN