6 ms·
> A theme I’m noticing more frequently as Rust gains popularity is people trying to use Rust even though it doesn’t fit their preferred way of coding. I could'
by dwattttt 2y ago
> A theme I’m noticing more frequently as Rust gains popularity is people trying to use Rust even though it doesn’t fit their preferred way of coding.
I could've expressed the sentiment in this blog post back when I started playing with Rust ~2016. Instead, I ended up learning why I couldn't pass a mutable reference to a hashmap to a function I'd looked up via that hashmap (iterator invalidation lesson incoming!).
The kind of bug I was trying to add exists in many languages. We can only speak in general terms about the code the blog post is talking about, since we don't have it, but couching it in terms of "doesn’t fit their preferred way of coding" misses that the "preferred way of coding" for many people (me included) involved bugs I didn't even realise could exist.
- Const-me 2y ago> The kind of bug I was trying to add exists in many languages Any example except C++? BTW, the closest thing possible in C# is modifying a collection from inside foreach loop which iterates over the collection. However, standard library collections throw “the collection was modified” exception when trying to continue enumerating after the change, i.e. easy to discover and fix.
- dwattttt 2y ago> modifying a collection from inside foreach loop This is exactly what the mutable map pointer was for, for the function to be able to modify the collection; C++ would result in potentially iterating garbage, C# it sounds like would throw an exception (and so show the design wouldn't work when I tried to test it), Python definitely didn't do a graceful thing when I tried it just now. And if I had a collection struct in C, I'm sure I could've done some horrible things with it when trying. The best of those outcomes is C#, which would've shown me my design was bad when I ran it; that could be as early as the code was written if tests are written at every step. But it could be quite a bit later, after several other interacting parts get written, and you rely on what turns out to be an invalid assumption. For Rust, the compiler alerted me to the problem the moment I added the code. FTR I ended up accumulating changes to the map during the loop, and only applying them after the loop had finished. EDIT: Python did do something sensible: I didn't expect pop'ing an element from the list to echo the element popped in the REPL, and got a printed interleaved from front to back, which does makes sense.
- dgoldstein0 2y agoPython defined the semantics of modifying lists while iterating over them, which is better than c/c++ just calling it undefined behavior, but I've basically never seen it not be a bug. Either I end up creating a copy of the list to iterate over, or figure out a way to defer the modifications, or write a new list. Imo the c# /Java behavior of detecting and throwing is probably the best option for non borrow checked languages.
- cyberax 2y ago> Any example except C++? Java for sure. > However, standard library collections throw “the collection was modified” Java is similar, but the exception is done on a "best effort" basis, and is not guaranteed.
- nurettin 2y agoPython will raise a runtime exception if you modify the dict you are iterating over. You can work around that by copying a snapshot of the whole thing or just the keys and iterating over that. C++ will laugh in invalidated iterators. Of course you can erase from the container you are iterating over, but you have to make sure to continue the iteration using the iterator returned from the erase function and avoid storing copies of .end()
- AlienRobot 2y agoI'm pretty sure most languages just make the reasonable assumption that you want to map to the object so it uses the pointer for hashing and not actually hash its value.
- deleted 2y ago[deleted]
- o11c 2y agoAnd yet, such mutation is perfectly safe as long as you only change the value of existing keys. But you can't do that in Rust.
- dwattttt 2y agoYou would use interior mutability, putting things in Cells in the map.