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
💡 discussion: lazy!
/once!
macros
#189
Comments
Initialization is also Line 194 in eda22ce
Another problem with the macro is that introduces a fresh type per lazy instance, (which also leaks into the API). So, I don't think this shold be included in the library, or in std. But it might be a good fit for the recipes section of the docs! https://github.com/matklad/once_cell/blob/master/src/lib.rs#L27 |
I agree with |
I think I'm in agreement: the patterns implemented by these macros can be documented in the docs and that's sufficient to close this "issue." Providing them as macros is not really necessary (especially given the reliance on TAIT for niceness; having
Is this justification for removing the second generic on Note that a simple Rustc is smart enough to say
This isn't always possible (without just rewriting let big_data = BigData::acquire();
let lazy = LazyCell::new(|| process(big_data));
if maybe() {
observe(&*lazy);
}
if maybe() {
observe(&*lazy);
} The only way to rewrite that with |
Yeah, I think I wouldn't agree with that -- it is sometimes (but rarely) useful to use a Lazy local variable (which is exactly CAD97's example) |
Closing! This is a useful discussion, but I think conclusion is that we don't actually want to change anything! |
The main disadvantage of the
Lazy
type overlazy_static!
is thatLazy<T>
necessarily stores and callsfn() -> T
rather thanimpl FnOnce() -> T
. This means that any inlining of the initialization must happen via devirtualization, rather than coming for free with monomorphization.On the other hand, perhaps this is an advantage; initialization is
#[cold]
and only called once, so inlining the initialization codepath may serve more to make inlining callers more costly than to make initialization less expensive.What doesn't suffer from the (perceived?) virtualization cost is the
fn get_global() -> &'static Global
pattern usingOnceCell
directly rather than throughLazy
. Using a macro interface, we can make this pattern more accessible.Presented for consideration, a potential implementation:
Actually... perhaps
lazy! { fn }
should actually bememoize!
or similar, since that matches the semantics (take the output and cache it) moreso thanlazy!
. But this is how the proof of concept went.Bonus far-future example: if we get function assignment, it would be cool to write
instead of
lazy! { fn }
.I understand that part of the draw of
once_cell
is the macroless API, but providing optional macros with straightforward documented translation1 can help as a documentation point for common-to-the-point-of-generalization patterns for using the API.It probably makes more sense to keep the simple API for the time being (e.g. because the nice impls I provide rely on TAIT in order to be properly nice), but if/when std's version of
OnceCell
is available, it might make sense to wrap some common patterns into simple macros in this (or another) crate.Footnotes
Straightforward in the expository documentation, even if the actual expansion is more complicated.
macro_rules!
always have to do interesting things to achieve proper hygiene when defining items. ↩The text was updated successfully, but these errors were encountered: