Live data from Hacker News

The Beauty of Concurrency in Go

pragprog.com

51–60 of 95 posts

Re: The Beauty of Concurrency in Go

#51
post #45

Earlier quoted context omitted.

> Something I miss from the language … Does sound like you want to use channels, and break your logic into small independent parts. You will have one goroutine using blocking Read() in a loop and feeding data to some channel. When it's done, you write to another channel that exists only for signaling: defer { doneChannel and then in your other goroutine: for { select { case data := The only things shared here are the…

> but I think " And what looks even better: defer close(doneChannel) (it's also syntactically correct -- you ca't just have a defer block without a function invocation)

Closing the channel is fine, I suppose, although the supervising goroutine now looks a bit odd:

    select {
      case _, _ := 
It's so implicit that you pretty much have to add a comment to the effect of "this will trigger when the channel is closed", whereas the "case Also, I rather prefer the supervising goroutine to "own" the channel, so it should be the one to close it.

> you ca't just have a defer block without a function invocation

Yeah, I was not thinking Go there for a moment. Should have been "defer func() { doneChannel <- true }".

Re: The Beauty of Concurrency in Go

#53
post #8

This article isn't bad... but it misses several important points of Go. I also note the article is 9 months old. In the hope that my criticism will be taken as constructive, with apologies for not writing detailed explanations: 1. Goroutines are not threads 2. type inference allows you to elide types in var declarations: var host = flag.String(... 3. Go's convention is to use camel case, not underscores. 4. Calling o…

> 1. Goroutines are not threads

They are not kernel-level threads, but they are threads in every other meaningful sense; they have their own stack and execution pointer, and data operations in goroutines are not guaranteed to be atomic with respect to other goroutines.

While the current official Go implementation never preemptively schedules goroutines except on I/O and on runtime.Gosched(), nothing in the spec precludes a different, more kernel-thread-like scheduling system.

Re: The Beauty of Concurrency in Go

#54

Earlier quoted context omitted.

How are goroutines not threads? Do you mean because it's possible for them to communicate without shared mutable state? Edit: Oh, apparently you all mean OS threads. So say so. (For example, in Haskell they're called threads without any implication that each one is an OS thread. Haskell's not unusual that way.)

Go schedules its own 'threads' (goroutines) to run on one or many (OS) threads. In this case, threads refer to not-a-process units of execution in an operating system. For whatever its worth, Wikipedia defines threads as: the smallest sequence of programmed instructions that can be managed independently by an operating system scheduler. I think that's also the commonly accepted definition: that threads are related to…

http://en.wikipedia.org/wiki/Green_threads

Re: The Beauty of Concurrency in Go

#55
post #44
post #24

> > Notably, if a package is included but not used, Go treats this as an error and enforces removing unused declarations A good illustration that the Go designers didn't think their ideas through. This is a real pain in the butt when you are writing code and regularly commenting in and out sections of code while you are testing things. And every time you do this, you need to remove or restore the imports. And since G…

> good illustration that the Go designers didn't think their ideas through. This is a real pain in the butt when you are writing code and regularly commenting in and out sections of code while you are testing things. How could it be that bad? It's as simple as a compile, a click on the error message and adding a one line comment. No worse than the standard practice of making sure your c/c++ code compiles without warn…

People develop at different speeds. For me, anything like this that slows me down and interrupts my flow with 3-4 seconds of "click on the error message and add a one-line comment" is incredibly annoying.

Development has several modes. One mode is "hacking", just hashing out what you want until it works and is elegant enough as a solution, perhaps changing your mind frequently when you see how it works in practice. Another is "polishing", carefully annotating, cleaning up, documenting, burning off loose threads, making sure the test coverage is top notch, etc.

The problem is that Go's compile-time strictness lends itself to the "polishing" phase, but not to the "hacking" phase.

Re: The Beauty of Concurrency in Go

#56

The beauty of concurrency in Clojure: ; Rough sketch: def defines a var (pretend it's a reference) ; @ is used to dereference the future and block to wait for the result. (def f (future (Thread/sleep 10000) (println "done") 100)) user=> @f done 100 ;; Dereferencing again will return the already calculated value. => @f 100 http://clojuredocs.org/clojure_core/clojure.core/future Edit: And more importantly, there are wr…

Futures in C++11 are similar: int x = std::async([]()->int{ return 100; }); std::cout Which isn't as nice as closure. Go could probably benfit from having a standard futures tool. I guess something along the lines of: type Future { Wait() interface{} } func newFuture(func interface{}, args ...interface{}) Future

Yep, futures can be done easily in Go with a goroutine that sends a single value on a channel, but: 1) you can't dereference the value multiple times in Go, so you have to manage saving it yourself, and 2) there's no syntactic sugar. Pity.

Re: The Beauty of Concurrency in Go

#57
post #56

Earlier quoted context omitted.

Futures in C++11 are similar: int x = std::async([]()->int{ return 100; }); std::cout Which isn't as nice as closure. Go could probably benfit from having a standard futures tool. I guess something along the lines of: type Future { Wait() interface{} } func newFuture(func interface{}, args ...interface{}) Future

Yep, futures can be done easily in Go with a goroutine that sends a single value on a channel, but: 1) you can't dereference the value multiple times in Go, so you have to manage saving it yourself, and 2) there's no syntactic sugar. Pity.

You could save the future in the Future implementation

    type future struct {
        completed   bool
        result      interface{}
        ch        
Edit: Or just check if the channel is closed

    func (f *future) Wait() interface{} {
        v, ok := 

Re: The Beauty of Concurrency in Go

#58

Earlier quoted context omitted.

It is really common for Go programmers (I've even seen members of the Go core team do it) to say 'thread' when they mean goroutine. It is important to recognize there is a difference, but calling someone out for saying 'thread' when they mean 'goroutine' is pedantic bullshit on the order of calling someone out for calling a class method in an OO language a function.

Oh I'm not (I didn't meant to?) calling parent out, I was just trying an explanation.

Thanks for explaining -- I really couldn't tell what distinction they meant.

Re: The Beauty of Concurrency in Go

#59
post #43

Earlier quoted context omitted.

Go schedules its own 'threads' (goroutines) to run on one or many (OS) threads. In this case, threads refer to not-a-process units of execution in an operating system. For whatever its worth, Wikipedia defines threads as: the smallest sequence of programmed instructions that can be managed independently by an operating system scheduler. I think that's also the commonly accepted definition: that threads are related to…

The notion that goroutines aren't threads seems to exist primarly because Golang also makes use of OS-native threads in order to schedule goroutines, and so needs to draw a distinction in order to explain how the runtime works. But that's just a detail. In reality, goroutines are threads; they're just userland, non-preemptive threads. Similar constructions have been available, even to C programmers, for well over a d…

> Similar constructions have been available, even to C programmers, for well over a decade (and probably much longer).

Of course they aren't called threads there, either (probably for the same reason as they aren't called threads in Go)

Re: The Beauty of Concurrency in Go

#60
post #43

Earlier quoted context omitted.

The notion that goroutines aren't threads seems to exist primarly because Golang also makes use of OS-native threads in order to schedule goroutines, and so needs to draw a distinction in order to explain how the runtime works. But that's just a detail. In reality, goroutines are threads; they're just userland, non-preemptive threads. Similar constructions have been available, even to C programmers, for well over a d…

> Similar constructions have been available, even to C programmers, for well over a decade (and probably much longer). Of course they aren't called threads there, either (probably for the same reason as they aren't called threads in Go)

Sure they are. For instance, Gnu Pth.

Programming language support for threading predates direct operating system support (at least in mainstream operating systems) by a lot of years, from what I can tell.

Post reply on HN