Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

It's a RWLock. Not a mutex. As long as no one is writing to it, readers are not blocked.


I know, but the RWLock itself also did not work. Complaining about safety and the only solution seemed to wrap the value itself into mutex inside rwlock. If I still had to go back to this, I would just write the function in C and go from there. Rust is productive when you can work with the highest level of abstraction and when it can copy values freely. When you want to work with copy-free or shared memory, is when rust becomes special kind of hell, and you have to dwelve deep into the depths of rust to get it to do what you want. Somehow the meta-programming is even more unreadable than C++.

I also get slight PTSD whenever I have to write `new`, not sure if the method will allocate or not behind the scenes. This is one of the things zig gets right I think:

- No hidden control flow.

- No hidden memory allocations.


I feel your pain as I started to learn Rust recently (again) and found the same problem, coming from C.

In my case, after fighting for literally days, the crate OnceCell did the job (kind of), but I felt awkward retorting to an external crate to deal with a simple static-global-initialize-once-never-touch-again piece of data.


Initializing global, static state isn't simple at all -- C++ is a prime example for how a bad design for static initializers can go horribly wrong.

At the very least, you need some sort of locking mechanism to deal with the potential issue where multiple threads try to initialize the variable concurrently. And you need some poisoning mechanism to prevent panics and reentrancy during initialization. Rust makes you realize "oh, yeah, I need to think about these too".

In any case, OnceCell is a very reasonable way to do this and is on track for stabilization.


I agree, but I have to say that not all the scenarios are the worst case scenario, and sometimes initialization is just "simple", like it was in my case and in other thousand cases I've worked in my life (I do embedded C mostly single-threaded).

This application was also single-thread (a command line utility to parse a text file). I now understand that Rust cannot guarantee the safety of initializing global variables so it makes me take the long road, but it could be great it could infer better about each particular case and enforce only when required.

If I can shoot myself in the foot with C then Rust would be kind-of clamping down on me and nailing my feet to the ground. At the end of the day, it hurts more or less the same.

That was my experience as a rookie with Rust in this particular case.


Yeah, Rust is built from the ground up for programming at scale. One of the consequences is that it makes you think about thread safety from the start. (Imagine if you're on a large team and not everyone is aligned on whether some part of the code is thread-safe or not.) Some things are harder, but the benefit is that you can often make a program multithreaded, and many times faster on real workloads, with just a few minutes of work (an experience that's unmatched in all of programming).

One of the ways Rust is successful at scale is that the intraprocedural analysis is sophisticated, but the interprocedural analysis is deliberately quite basic. It's not quite in keeping with that to do things like selectively enforce bounds on global variables.

For use cases like the one you mentioned, the general strategy Rust wants you to use is to pass around a context with your data inside it (and the data could be in OnceCells if it's lazily fetched). This is also a more testable design. Global state is meant to be used sparingly.


May I suggest you take some time to understand the concurrency and memory management parts of Rust a little more to figure out where your program is falling.

I agree it's not an easy language to pickup, but the use case you mentioned is a pretty common one and there are several ways to solve it. For example, any kind of config reading from a file needs it. Similarly, connection pools for DB etc are shared this way so its not an uncommon use case in day to day usage of Rust.


They need atomic operations which can still stall most of your massivly parallel machine.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: