Perform implicit clone into closures for variables made with hooks #3464
kirillsemyonkin
started this conversation in
Ideas
Replies: 2 comments 4 replies
-
Last part may be fixed in the ImplicitClone crate with specializations (currently nightly): #![feature(specialization)]
default impl<T: Copy> ImplicitClone for T {
} Since it is a marker trait, there are basically no implementation collisions possible, so I believe it should be a thing even without specializations. Can anyone work a proposal into the Rust language for allowing marker trait implementations to be repeatable (or find an existing proposal for me)? |
Beta Was this translation helpful? Give feedback.
3 replies
-
A workaround to this problem could be to add a macro_rules! clone {
( $($var:ident),* $(,)? ) => {
$( let $var = $var.clone(); )*
};
} Usage let a = use_state(|| 0);
let b = use_state(|| 0);
let c = use_state(|| 0);
let on_click = {
clone!(a, b, c);
Callback::from(move |_| {
a.set(1);
b.set(2);
c.set(3);
})
}; |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
The Problem
One of the main concerns about Yew developer experience is that
.clone()
s take up a significant part of the function component's vertical real estate:The main reason for this is that Rust natively does not support implicit cloning for types like
Rc
, which means clones should happen manually. This means such functionality should either be forced into Rust (good luck), or recreated manually with the №1 tool made for such wishes: (procedural) macros.Macro Brainstorming
If we want to implement macro, ideally it would determine what values are
ImplicitClone
, and transform lambdas intomove
closures (hereinafter closure transforms),.clone()
ing appropriate values first:The main roadblock in front of simply creating this feature is that procedural macros operate on tokens (simple structures of words), not on semantics (types). This means it is impossible to know which variables (variable names) are
ImplicitClone
without recreating the whole type analyzer inside of the procedural macro's logic. This means some variable names (tokens!) need to be marked as implicitly cloneable (hereinafter marked variables) so that we can determine if we can transform the closure creation with cloning those variables.A crate named
clown
(clone + own) does this using thehonk!
macro inside the closure. The problem with it is that it is basically.clone()
that has been moved from before closure to inside the closure, providing barely any boilerplate reduction (same goes for Rust RFC 3512).A similar approach may be doing the marking of the variable during its creation:
This would solve 99% of the problematic code: all the millions of clones that come after the variable declaration would be gone, leaving only one line that is still marked with anything.
Yew's Special Sauce
We could strive for fixing 100% of the problematic code in Yew in particular. Most, if not all, of the
ImplicitClone
values come fromuse_state
, sometimes from other hooks (but usually all hooks return either a()
,Copy
orImplicitClone
value). This means for marking variables, hooks may mark the variable names:Of course, this may not be used as-is. Main issue is that hooks aren't actually limited to be only
ImplicitClone
in its return values, but that can be made a breaking change: during#[hook]
declaration the return type has to be ensured to beImplicitClone
:Beta Was this translation helpful? Give feedback.
All reactions