-
Notifications
You must be signed in to change notification settings - Fork 114
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Modernizing LazyStatic APIs #111
Comments
Here's the proposes |
I like the direction this is headed in! Ultimately, I'd really like to see something like this in With that said, a dependency on With that said, this is a double edge sword, because I also like the idea of more people using and testing |
That is a valid concern. We need Now, rust-lang/rust#52239 literally just removed the So, two questions:
|
I'm not sure about the In terms of making |
Yep, that is correct. OTOH, if you care about number of deps, your deps are probably caring about that as well, and would use I've pushed updates that make parking_lot optional and default, employ the &'static "polyfill" for Once and remove usages of non-essential new features. That gives use compatibility with Rust 1.24.0 an up, with or without parking-lot, on a somewhat questionable ground that pretending that non-static Once is static is OK :) |
Cool! Do the fields here need to be public? We just finished removing the equivalent from |
Excellent observation @anp! I can't think of a way to make fields private: because we don't create a fresh type for per lazy instance anymore, we need to store the closure inside a struct, and that should work in What we can do, however, is to hide |
No, this doesn't entirely fix the hole unfortunately, the user can just overwrite the state directly :( What we can do is to split the |
Another potential problem with
There's also an extra indirection during intialization, but that probably does not matter, because |
I personally wouldn't mind if |
Status update: now lazy-static can be completely macro-free static HASHMAP: Lazy<HashMap<u32, &'static str>> = Lazy::new(|| {
let mut m = HashMap::new();
m.insert(0, "foo");
m.insert(1, "bar");
m.insert(2, "baz");
m
}); Still contains |
I've just noticed that std's thread local variables also store function pointers: https://github.com/rust-lang/rust/blob/9ebf47851a357faa4cd97f4b1dc7835f6376e639/src/libstd/thread/local.rs#L80-L99 |
Any plans to merge something like @matklad has done into lazy_static? It would certainly reduce the magic. |
Current status: proposing API for stdlib: rust-lang/rfcs#2788 |
lazy_static! has fallen out of favor since better, non-macro ways of accomplishing lazy init have been found. rust-lang-nursery/lazy-static.rs#111
Current status: available in nightly with Tracking issue: rust-lang/rust#74465 |
@matklad Can I use a Also, I'm using this to write a thread local memory allocator as well. If you were to write something like this today, what would you use if you had to optimize for performance? Have you changed your opinion since you published the blogpost last year? |
Context: https://internals.rust-lang.org/t/pre-rfc-lazy-static-move-to-std/7993/36
Rust has progressed enough to make lazy static API less magical. It could look like this (example from
once_cell
):I am creating this issue to discuss what we can do with this exciting possibility :-)
Just to be clear, I am explicitly not suggesting that we should deprecate the current API and switch to the new shiny. There's a ton of code in the wild which uses
lazy_static!
, and that is great.Nevertheless, I think the current API has some problems, and the possible new API has less of them! Specifically, the current
lazy_static!
macro is opaque: it has a somewhat unique syntax, which is Rustish, but is not exactly Rust, it creates a unique hidden type behind the scenes and the implementation is hard to follow. I think this are significant drawbacks, especially from the learnability perspective.When a new rustecean asks "how can I have global data?", the typical answer is: "you need to lazily initialize data on the first access. This is what C++ and Java do at the language level, but Rust this is achieved via the
lazy_static
library". And then a rustecan goes to see howlazy_static
is implemented, sees this and thinks "wow, this is almost as horrifying as STL implementations" (well, at least that was my reaction :D).I'd want to argue that an explicit
Lazy<T>
would be clearer at the call site (no more magical unique types) and much easier to understand (you just Ctrl+B/F12/M-./gD and read the impl).An interesting facet of the new API is that
Lazy
does not need to be static!So, are folks excited about the possibility of getting rid of
lazy_static!
macro? I propose the following plan for this:sync::Lazy
fromonce_cell
and publish it as a separate rust-lang-nursery crate,sync_lazy
, with the following APIsync_lazy
crate usesparking_lot::Once
. That way, we don't need to wait until non-staticOnce
is stable, and we also giveparking_lot
some more testing, as was requested in Replace synchronization primitives with those from parking_lot rust-lang/rfcs#1632 (hence, cc @Amanieu)In the
lazy_static
readme, we point that one might trysync_lazy
instead.The text was updated successfully, but these errors were encountered: