Earlier quoted context omitted.
You know how a modern language like Rust doesn't have the unstructured control flow with features like "goto"† but only a set of structured control flow features, such as pattern matching, conditionals, loops and functions? Structured Concurrency is the same idea, but for concurrency. Instead of that code to create an appropriate number of threads, parcel out work, and so on, you just express high level goals like "D…
Rust async streams or rayon come very close to what you describe as structured concurrency. Actually much closer than anything I saw in other mainstream languages eg Java or Go.
Go’s race detector has a mutex blind spot
41–50 of 60 posts
Re: Go’s race detector has a mutex blind spot
#42Earlier quoted context omitted.
> and 'f' panics, the program's deadlocked forever I don't see `mu.Lock(); f(); mu.Unlock()` anywhere really. `mu.Lock(); defer mu.Unlock(); f();` is how everyone does it to prevent that possibility.
Trick question: what is the scope of `defer` in go?
Re: Go’s race detector has a mutex blind spot
#43Earlier quoted context omitted.
My guess is that next the language gen will be languages that AI generates, which are optimized to be readable to humans and writable by AI. Maybe even two layers, one layer that is optimized for human skimming, and another layer that actually compiles, which is optimized for AI to generate and for the computer to compile.
> which are optimized to be readable to humans and writable by AI How might a language optimized for AI look different than a language optimized for humans?
Re: Go’s race detector has a mutex blind spot
#44I'm so glad to be out of the dark ages of parallelism. Complaining about Go's race detector or exactly which types of logical races Rust can't prevent is such a breath of fresh air compared to all those other single-core languages we're paid to write with that had threading, async, or concurrency bolted-on as an afterthought. I can only hope Go and Rust continue to improve until the next language generation comes alo…
You know how a modern language like Rust doesn't have the unstructured control flow with features like "goto"† but only a set of structured control flow features, such as pattern matching, conditionals, loops and functions? Structured Concurrency is the same idea, but for concurrency. Instead of that code to create an appropriate number of threads, parcel out work, and so on, you just express high level goals like "D…
Is there a similar proof for structured concurrency - that it can express anything that unstructured concurrency can?
Re: Go’s race detector has a mutex blind spot
#45Earlier quoted context omitted.
Trick question: what is the scope of `defer` in go?
Function body, so no don’t put it in your loop. Just break it out to a helper fn if needed. This isn’t a big problem in practice.
Re: Go’s race detector has a mutex blind spot
#46I'm so glad to be out of the dark ages of parallelism. Complaining about Go's race detector or exactly which types of logical races Rust can't prevent is such a breath of fresh air compared to all those other single-core languages we're paid to write with that had threading, async, or concurrency bolted-on as an afterthought. I can only hope Go and Rust continue to improve until the next language generation comes alo…
You know how a modern language like Rust doesn't have the unstructured control flow with features like "goto"† but only a set of structured control flow features, such as pattern matching, conditionals, loops and functions? Structured Concurrency is the same idea, but for concurrency. Instead of that code to create an appropriate number of threads, parcel out work, and so on, you just express high level goals like "D…
You should have a look at what's going on in Scala-land, with scala-native¹ (and perhaps the Gears² library for direct style/capabilities)
I like this style, though it's been too new and niche to get a taste of it being used at scale.
¹: https://scala-native.org/ ²: https://github.com/lampepfl/gears
Re: Go’s race detector has a mutex blind spot
#47Earlier quoted context omitted.
> Congrats, rustc forced you to wrap all your types in Arc > Also, don’t people know that a Mutex implies lower throughput depending on how long said Mutex is held? Lock-free data structures/algorithms are attempt to address the drawbacks of Mutexes. https://en.wikipedia.org/wiki/Lock_(computer_science)#Disadv...
Lock-free data structures and algorithms access shared memory via various atomic operations such as compare-and-swap and atomic arithmetic. The throughout of these operations do not scale with the number of CPU cores. Contrary, the throughput usually reduces with the growing number of CPU cores because they need more time for synchronizing local per-CPU caches with the main memory. So, lock-free data structures and a…
This is independent of using a mutex, a lock free algorithm or message passing (because at the end of the day a queue is a memory location).
Re: Go’s race detector has a mutex blind spot
#48Earlier quoted context omitted.
OK, but you're not in "Go"-specific problems any more, that's just concurrency issues. There isn't any approach to concurrency that will rigorously prevent programmers from writing code that doesn't progress sufficiently, not even going to the extremes of Erlang or Haskell. Even when there are no locks qua locks to be seen in the system at all I've written code that starved the system for resources by doing things li…
I would say it is a Go specific problem with how mutexes and defer are used together. In rust you would just throw a block around the mutex access changing the scoping and ensuring it is dropped before the slow function is called. Call it a minimally intrusive manual unlock.
Specifically for Go, I'd try to address the problem in CSP style, so as to avoid explicit locks unless absolutely necessary.
Now for the case you mention, one can actually achieve the same in Go, it just takes a bit of prior work to set up the infra.
type Foo struct {sync.Mutex; s string}
func doLocked[T sync.Locker](data T, fn func(data T)) {
data.Lock(); defer data.Unlock(); fn(data)
}
func main() {
foo := &Foo{s: "Hello"}
doLocked(foo, func(foo *Foo) {
/* ... */
})
/* do the slow stuff */
}Re: Go’s race detector has a mutex blind spot
#49I'm so glad to be out of the dark ages of parallelism. Complaining about Go's race detector or exactly which types of logical races Rust can't prevent is such a breath of fresh air compared to all those other single-core languages we're paid to write with that had threading, async, or concurrency bolted-on as an afterthought. I can only hope Go and Rust continue to improve until the next language generation comes alo…
But go-routines!
Well, on .NET land we would be using Task Processing Library, or Dataflow built on top of it, with tasks being switched over the various carrier threads.
Or if feeling fancy, reach out to async workflows on F# with computation expressions, even before async/await came to be.
While on the Java side, we would be using java.util.concurrent, with future computations, having fun with Groovy GPars, or Scala frameworks like Akka.
In both platforms, we could even go the extra mile and write our own scheduling algorithms, how those lightweight threads would be mapped into carrier threads.
Naturally not having some of the boilerplate to handle all of that, or using multiple languages on the same project, makes it easier, hence why now we have all those goodies, with async/await or virtual threads on top.
Re: Go’s race detector has a mutex blind spot
#50Earlier quoted context omitted.
Function body, so no don’t put it in your loop. Just break it out to a helper fn if needed. This isn’t a big problem in practice.
Yes, though I think tooling could be better; if I had more spare time I'd write a linter which flagged defers in loops that didn't come with an accompanying comment.