Hacker News new | ask | show | jobs
by klodolph 1749 days ago
> Honestly, this is a strange and peculiar situation, although Go programmers have acclimatized to it. To programmers from other languages, such as C or C++, the concept of pointers to dynamically extensible arrays seems like a perfectly decent idea that surely should exist and work in Go. Well, it exists, and it "works" in the sense that it yields results and doesn't crash your program, but it doesn't "work" in the sense of doing what you'd actually want.

In C++, what happens is that the "iterators are invalidated" when you add something to an array. This is CONSTANTLY a source of bugs and frustration for new programmers. In C++, it may yield results or crash your program, and you are never sure quite which will happen. The best you can do (as a senior engineer) is design your software to avoid ever creating this situation in the first place and throw address sanitizer at things to try and catch them when they arise. The difference with Go is that in Go this will never result in a memory error.

Strictly speaking, the situation in Go is way better. I will take "incorrect behavior, but not a memory error" over "memory error" any day of the week.

We may forget what it's like for new programmers, but for those of us who hang out on Discord channels, Stack Overflow, and Reddit giving people help with programming, simple things like iterator invalidation are a major pain point.

"You have a memory error in your program", I say to someone. "Now that you know that you have a memory error, it is probably your highest priority to find and fix this error." And now you start walking someone through the steps of finding and fixing a memory error, which is nontrivial. You'll tell them about Address Sanitizer, GDB, and Valgrind, and you'll wish them luck.

1 comments

I agree that it is better than C and C++ but not much better.

C and C++ are "It is very easy to make this mistake which leads to undefined behaviour and a maybe incorrect program."

Go is "It is very easy to make this mistake which leads to a maybe incorrect program."

Yes, better! But the problem is still there. I much prefer the Rust solution where there is no common mistake.

The catch is that code is hard to translate into Rust.

"I have this code, you see... and it takes a couple mutable references into an array... how do I translate this into Rust?"

There is no one-size-fits-all answer to that question. The code may be correct in C or C++, but the Rust type system may give you one hell of a hard time proving that it is correct to the Rust type system's satisfaction... so you refactor your code completely, or you use integer indexes into arrays rather than references, or you use unsafe code...

I've written some amount of Rust code at this point. About half of the time, when I write a project in Rust, there comes a point at which I'm fighting with the type system. I feel like this should stop happening, at some point.

For sure. The solution has downsides but it does largely solve the problem. It isn't strictly better than go, but it is an important difference.

Mostly off-topic but FWIW "mutable reference into an array" is typically very easy in Rust you just accept a &mut [T]. This also nicely enforces that you don't try to append because that would be wrong 99% of the time.

> Mostly off-topic but FWIW "mutable reference into an array" is typically very easy in Rust you just accept a &mut [T].

I had specifically worded it as "a couple mutable references into an array". How do I take a small number of references into an array, say two or three?

Off the top of my head you do something like https://play.rust-lang.org/?version=stable&mode=debug&editio...

Yeah you gotta write it out per number of times. Luckily this rarely comes up in this specific form.

Wow, that code is as bad as I thought it would be. Yeesh.

> Luckily this rarely comes up in this specific form.

Well, yeah—it would come up rarely because it only solves the problem under very specific circumstances!

Ah, missed that. You are right, in that case you need to start making some decisions depending on the situation.