Live data from Hacker News

Data Race Patterns in Go

eng.uber.com

181–190 of 205 posts

Re: Data Race Patterns in Go

#181
post #141

Earlier quoted context omitted.

When printing s1, s2, then s3: It does exactly that, yes: https://go.dev/play/p/rs2FeK_QUjs [a b c] [a b c x] [a b c y] But maybe it doesn't: https://go.dev/play/p/Na-eL0sOV9e [a b c] [a b c y] So... maybe they share the same backing array? Lets try setting s2[0] to "z" after appending with the original code: https://go.dev/play/p/mAB-gUb0shB [a b c] [z b c x] [a b c y] Apparently not. But also apparently yes? https:…

Is there a bug or issue on this in their GitHub cause wtf is this ?

This is expected behavior. It's just an easy thing to screw up by accident.

Re: Data Race Patterns in Go

#182
post #65

Earlier quoted context omitted.

I greatly prefer Rust to Python, but slightly prefer Go to Rust in many situations. Python even with MyPy just feels sloppy, whereas Go does offer decently strong typing at least. As for Go vs Rust, the answer is in the ecosystem, and I blame that on the difficulty of maintaining high quality Rust crates. I know not everyone agrees with this explanation, but I think Rust being complicated makes it hard to offer zero…

There are no gradients of strong typing. Either a language is strongly typed or not. Python is strongly typed. For someone with such strong opinions, you seem to lack certain fundamental knowledge which I suggest you rectify ASAP as it will definitely improve your programming skill.

Huh? What do you mean by 'strongly' typed in this case?

In common parlance, there are definitely gradients.

For example compared to most mainstream languages, Haskell is strongly typed. But compared to Agda, Haskell's types are pretty weak.

For example, typically Haskell programs don't use types to enforce that you can't divide by zero. In Agda it's relatively easy to enforce that.

Re: Data Race Patterns in Go

#183

Earlier quoted context omitted.

Data Race Freedom is, unsurprisingly, Freedom from Data Races. A Data Race is any time when there's concurrent modification of a memory value, on modern hardware with multiple simultaneous execution contexts those modifications could in some sense happen at the same moment. [NB: Data Races are a subset of Race Conditions. Race Conditions are sometimes just a fact about the world and you need to write programs that co…

AFAIK, you still have to be very careful since data races based on data dependencies can never be excluded in general, that is theoretically not possible. What you get is a guarantee that your program is not in an undefined state. There are still plenty of ways to shoot yourself in the foot with incorrect synchronization.

> AFAIK, you still have to be very careful since data races based on data dependencies can never be excluded in general, that is theoretically not possible.

Well, you could always require the programmer to supply a proof that the program is gonna be fine, before you compile anything.

(That means your programming language won't be Turing complete, but you can still code up anything you want in practice. Including Turing machines.)

The likes of Agda and Coq work in this way.

Re: Data Race Patterns in Go

#184
post #161
post #68

A dig against Rust I sometimes hear is "Oh, data race freedom isn't such a big deal, if you really need it, a garbage collected language like Java will give you that guarantee." So now I'm hearing that Go, a garbage collected language, doesn't guarantee data race freedom? I guess it's garbage collected but not "managed" by a runtime or something? Why go to all that effort to get off of C++ just to stop 30% short? The…

If someone is claiming the garbage collection means freedom from data races, they are unambiguously wrong. Garbage collectors solve double-free bugs and usually memory leaks due to cyclic references.

Yes. Though garbage collectors can have an indirect influence on the design of the language, that makes it easier to handle data races.

(As an example, image how much simpler Rust would be, if they went with garbage collection. Or how much more machinery Haskell would need, if they went with Rust's memory management strategies.)

Re: Data Race Patterns in Go

#185

Seems like Rob Pike and co may have failed "The key point here is our programmers... They’re not capable of understanding a brilliant language... So, the language that we give them has to be easy for them to understand"

What’s the relevance of the quote? It makes you feel insulted?

The relevance is that the submitted article shows that you need to be rather smart to avoid Go's pitfalls.

Re: Data Race Patterns in Go

#186

Earlier quoted context omitted.

> Thus, it gets passed by reference instead of by value Everything in Go is passed by value, including slices. Go has no reference types, but a lot of people think it does, and that’s a problem. An example of the much bigger problem of low barrier to entry programming, where lots of folks write code but have no deep understanding of the tools they use. If there’s something that Go proves, it’s that one can’t make a l…

You can't make a language "idiot proof" but by changing how we think about the problem we can make a huge difference. The trick is, what programs do we even want to exist? There's no need to be able to write all the programs you didn't want. In Rust, such programs get consigned to unsafe, which means that yes, sometimes to do general purpose programming (and especially e.g. in Rust's own stdlib) you must use unsafe R…

For anyone curious: https://github.com/google/wuffs

Re: Data Race Patterns in Go

#187

I think the root cause of a lot of these data races is that Go has no way of marking variables/fields/pointers/etc. as immutable or constant. This makes it easy to lose track of shared mutable state. It's not just data races--it's also logical races, which are near-impossible to detect or prevent without something like transactional memory.

Yes, missing immutability is a big part of the problem in Go.

Given that Go eschewed generics for the longest time, I can sort of see why they left out immutability markers:

To keep your sanity, you'd want some functions to take (and return!) both mutable and immutable data, as the situation requires. But some other functions should only take mutable data or only immutable data.

Thus ideally you'd need some kind of 'generic' (im-)mutability handling in your type system.

(Rust's borrow checker is basically one way to really deal with this (im-)mutability genericity.

For example, a function to do binary search on a sorted array doesn't change the array; thus it could take either a mutable or immutable version. But if the array changes (via another thread) while the function is running, then you might get into trouble.)

Re: Data Race Patterns in Go

#188
post #163

Go picked the concurrency ideas of Erlang but then ignored the main safeguard that makes Erlang's concurrency fearless: Immutability. And if you feel that Erlang's lack of type safety is an issue, then Gleam has you covered.

Erlang was fun to use!

But even with Erlang, concurrency is hard. Any single process's data is immutable, but if you split a process in twain, the resulting union can behave as if it had mutable state.

And let's not forget about ETS (term storage), which is basically a mutable hash table that you often have to use to get anything done.

In any case, I agree that Go did _not_ improve on Erlang.

Re: Data Race Patterns in Go

#189
post #70

Earlier quoted context omitted.

Sadly, people get rewarded for what they built (even if makes everyone's lives harder in the long run) than for exercising restraint and saying "no".

There’s a perception that big tech pays longtime employees less than they’re willing to offer new candidates, making promotion or job hopping the best ways to earn the current market rate. And if you copy Google’s promo process, you get promo-driven development, because there aren’t enough projects that actually need that level of complexity.

And sadly, Google isn't even the worst. At least they seemed to allocate quite a few resources for turning off old systems and decommissioning them.

At many other enterprises, old systems never properly die.

It's just as hard, or often harder, to migrate off the last few uses of a system compared to launching a new system. But while you can get promoted for launching a great-enough new system in almost any organisation, good luck getting promoted for your heroic efforts in shutting down obsolete systems.

(I guess it's technically possible. Just unlikely in most places.)

Re: Data Race Patterns in Go

#190
post #109

Earlier quoted context omitted.

For me, Java and MySQL kind of died* when they became an Oracle thing. I just don’t want to go near anything that Oracle touches. The other thing is that I tend to write little programs where simple deployment on a low-resource machine is desirable. Go can handle that. Java kind of does the job with Graal now. The JVM is incredible, though, and I love Clojure. I’m hoping that Loom + Graal helps to kickstart more comp…

> For me, Java and MySQL kind of died* when they became an Oracle thing. I just don’t want to go near anything that Oracle touches. Come on, that’s a cheap reason (for Java, for open source db I would also go with postgre but for different reasons). Java is one of the very few languages with a full specification (not “whatever our compiler does, that’s the spec”), it has plenty of fully independent full implementatio…

Agree that Java is pretty good with records / sealed types / loom, but one nice thing about the Oracle Java team is they do not add half baked features (primarily since they have the last mover advantage) - for (e.g.) Valhalla will have value types, but they'll be immutable so they can be freely copied and used. Loom will have structured concurrency on debut, which IMHO makes vthreads manageable.

But I've my own apprehensions about loom which actually breaks synchronized blocks (by pinning the carrier thread), and are used extensively in legacy libraries and even in the more recent ones (like opentelemetry java sdk).

Post reply on HN