Earlier quoted context omitted.
Every programming language has a runtime, even Assembly if the CPU is micro-coded. How do you think that the GC, go-routine scheduler, cgo marshaling get managed?
I assume what people want to say is that Go requires nothing which other languages install via the system package manager. While "runtime" is not the correct term, the desire is real. With Java you first install a JVM. With Python you install the interpreter and batteries. This always leads to version conflicts at some point. In contrast, with Go your CI builds an executable, you transfer that to your server and it r…
Go hits the concurrency nail on the head
181–190 of 318 posts
Re: Go hits the concurrency nail on the head
#182Go concurrency is just threads. It's a particularly idiosyncratic userland implementation of them. There are two claims here I'd like to unpack further: 1. "I've measured goroutine switching time to be ~170 ns on my machine, 10x faster than thread switching time." This is because of the lack of switchto support in the Linux kernel, not because of any fundamental difference between threads and goroutines. A Google eng…
I'm trying to find out what you mean by "switchto support". Do you have a link?
Re: Go hits the concurrency nail on the head
#183Earlier quoted context omitted.
The Actor model is trivially implementable with CSP.
And CSP is trivially implementable using the Actor model. What's your point?
I think the basic Actor definition does only say that Actors need to send messages to others, but not whether they can block on reception of selected responses. So it might be a bit undefined.
Re: Go hits the concurrency nail on the head
#184Earlier quoted context omitted.
> Goroutines are threads This is a thing I have to continually remind newer engs that are using Go. Goroutines have exactly the same memory observability / race conditions / need for locking/etc as any threaded language. Every race bug that exists in e.g. Java also exists in Go. The only real difference for most code is that it pushes you very hard to use channels directly , as they're the only type-safe option. Ther…
> The only real difference for most code is that it pushes you very hard to use channels directly, as they're the only type-safe option. It is, but it is also a super important difference: Go provides inbuilt libraries to make inter-thread synchronization more bearable for the average user, e.g. channels and waitgroups. These are lot harder to misuse than bare mutexes and condition variables. Since those are not avai…
Re: Go hits the concurrency nail on the head
#185Earlier quoted context omitted.
Every programming language has a runtime, even Assembly if the CPU is micro-coded. How do you think that the GC, go-routine scheduler, cgo marshaling get managed?
I assume what people want to say is that Go requires nothing which other languages install via the system package manager. While "runtime" is not the correct term, the desire is real. With Java you first install a JVM. With Python you install the interpreter and batteries. This always leads to version conflicts at some point. In contrast, with Go your CI builds an executable, you transfer that to your server and it r…
it's just dotnet publish with the switch or without and you get a folder that you can copy where you need the runtime or where the runtime + start script is inside the folder.
(Java 9+ has something similar but it's way more complicated than just running java publish, etc..)
Re: Go hits the concurrency nail on the head
#186Earlier quoted context omitted.
> Goroutines are threads This is a thing I have to continually remind newer engs that are using Go. Goroutines have exactly the same memory observability / race conditions / need for locking/etc as any threaded language. Every race bug that exists in e.g. Java also exists in Go. The only real difference for most code is that it pushes you very hard to use channels directly , as they're the only type-safe option. Ther…
> The only real difference for most code is that it pushes you very hard to use channels directly, as they're the only type-safe option. It is, but it is also a super important difference: Go provides inbuilt libraries to make inter-thread synchronization more bearable for the average user, e.g. channels and waitgroups. These are lot harder to misuse than bare mutexes and condition variables. Since those are not avai…
But "futures", "blocking queues", "synchronized maps", and "locked objects" (e.g. a synchronized wrapper around a java object) are extremely common and often higher level than channels and selects and waitgroups[1].
[1]: Waitgroups in particular are covered by normal counting mutexes, marking them as low-level constructs like they are, and are also available nearly everywhere.
Re: Go hits the concurrency nail on the head
#187Go concurrency is just threads. It's a particularly idiosyncratic userland implementation of them. There are two claims here I'd like to unpack further: 1. "I've measured goroutine switching time to be ~170 ns on my machine, 10x faster than thread switching time." This is because of the lack of switchto support in the Linux kernel, not because of any fundamental difference between threads and goroutines. A Google eng…
> Finally, Go doesn't do anything to prevent data races, which are the biggest problem facing concurrent code. It actually makes data races easier than in languages like C++, because it has no concept of const, even as a lint. Race detectors have long existed in C++ as well, at least as far back as Helgrind. While it can't guarantee correctness outside of runtime (and even then, obviously only if whatever you are run…
Re: Go hits the concurrency nail on the head
#188> Mixing threads with event loops is possible, but so complicated that few programmers can afford the mental burden for their applications. Correct me if I'm wrong, but doesn't basically every UI framework from the last 20 years do exactly this?
- Trying to access UI framework elements from the wrong thread
- not understanding that a callback inside one of the included libraries is not running on the UI thread but from somewhere else
- callbacks capturing references to objects which already had been destroyed (but the callback had been queued and can't be cancelled), and accessing those objects later on
- deadlocks, due to mutex locking in both callbacks as well as the "normal" code.
There are ways to minimize the amount of issues, e.g. always deferring asynchronous callbacks to the next eventloop iteration, making sure that callbacks are queued on the main thread instead of an arbitrary one, deferring object deletion behind all other callbacks, etc. But these are on the harder to learn, teach and enforce side.
Therefore I would agree with the author of that article that the mixture of eventloop-based programming and multiple threads is the hardest combination.
Re: Go hits the concurrency nail on the head
#189Earlier quoted context omitted.
Every programming language has a runtime, even Assembly if the CPU is micro-coded. How do you think that the GC, go-routine scheduler, cgo marshaling get managed?
I thought it was pretty obvious that the OP was using "runtime" to refer to an external interpreter program. The significance being the simplicity of deployment.
Re: Go hits the concurrency nail on the head
#190Earlier 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.
Syntax is a crucial component of any programming language. I would disagree, though, that there's anything inherently easier about imperative languages. Could it not be that it's simply more familiar to people today? People don't (IME) learn to program in school. They learn by futzing around with whatever free thing is on their computer. In the 1980's we had BASIC, and today we have JavaScript, and Python/Ruby/Java/C…
I see three major programming styles: imperative, declarative, and functional.
Declarative seems extremely popular these days (see Rails, CSS, Webpack, etc). My guess is it’s because it’s fairly obvious how to design a declarative API. You just think about what you’d want as an application programmer, write that down in English, and then target that with your implementation.
These interfaces are totally unstable, and so they just degrade with time but they’re so easy to stand up they dominate the field.
Imperative interfaces are a bit harder because you need to explicitly pass all of your data through every call. This is laborious at first and you have to do lots of refactoring of the interface as you implement it. API developers generally don’t like this feeling, and would rather have a stable interface to target and only futz with the internals. And it takes longer and requires more pondering when you can’t just reach directly into arbitrary parts of your code base and do whatever TF you want. And since APIs are usually released before they stabilize, application developers also don’t like seeing their interfaces move.
Functional APIs are like the imperative ones but even moreso. Not only do you have to pass around data explicitly all the time, you have to model every intermediate state in your data explicitly too.
This is even more constrictive, which just makes all of the above even worse.
Personally, I think this pain pays off in the end, and I code in a purely imperative style deep in a haunted wood. The suffering over moving interfaces eventually leads to a stable interface that’s actually well thought out and composeable. Code can become “finished” whereas declarative code almost always just rots til it’s replaced.
But in terms of “Don’t make me think” which is most pro developers dominant mode of working, there is a clear declarative > imperative > functional hierarchy.
In theory a purely imperative or purely functional ecosystem could gain a kind of network effect of good code that would eventually outweigh the work slowdown.... your application code would be harder to write, but you’d be writing on top of a richer, more composeable library base.
However we don’t seem to observe this in practice.
My theory is that imperative and especially functional languages tend to attract masochists, who get yakshorn into radical experiments into purism, trying to bend every aspect of an ecosystem into a perfect Q-dimensional prism. This leads to just less effort in churning out pragmatic tools. And it also leads to a kind of dazzling conversation around the languages that turns away people who are just trying to get something done.
With sustained effort these effects could be overcome. Over time I am building a library of pure imperative JavaScript modules. They seem to be reaching “finished” one by one. We’ll see.