Skip to content
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

Deep vs. shallow signal trait implementations #2445

Open
Giovanni-Tably opened this issue Mar 19, 2024 · 0 comments
Open

Deep vs. shallow signal trait implementations #2445

Giovanni-Tably opened this issue Mar 19, 2024 · 0 comments

Comments

@Giovanni-Tably
Copy link
Contributor

This is a tracking issue for traits implemented on signal types, and whether they should be 'shallow' or 'deep', and whether they should be tracking or not.

  • A 'shallow' implementation does not access the value of the signal.
  • A 'deep' implementation accesses the value of the signal.
    • If the value is accessed, we can track the signal or not (call .get() or .get_untracked()).

Considerations:

  • In general, in Rust, 'pointer-ish' containers use the internal value for comparisons and similar traits (or don't implement the trait at all).
  • We can't always avoid a panic in the process of accessing a value, because the signal might be a plain closure which itself may access a disposed signal.
    • In theory we could catch_unwind, but that is problematic because of the risk of running some code midway through and unwinding doesn't work on wasm anyway (yet).
  • A deep Debug implementation is really useful for debugging.
  • Shallow trait implementations will make nested signals less ergonomic.
  • In the case of a deep implementation, the signal is being 'accessed'. That makes it feel like it should subscribe (if a == b {} being equivalent to if a.get() == b.get() {}).
  • If we have a deep implementation which subscribes, then collections which rely on the values themselves (HashMap, BTreeMap, ...) might subscribe to arbitrary value on each access.
    • More generally, stashing things with interior mutability in these collections is already something to be careful with.

Some relevant traits:

  • Debug
    • Arc, Rc, & Box forward to the inner values.
    • RefCell & Mutex do the same but print tags if the value is inaccessible.
  • PartialEq
    • Arc, Rc, Box, RefCell forward to the inner values.
    • Mutex does not implement PartialEq.
    • {Rc,Arc}::ptr_eq are available.
  • PartialOrd
    • Arc, Rc, Box, RefCell forward to the inner values.
    • Mutex does not implement PartialOrd.
  • Hash
    • Arc, Rc, & Box forward to the inner values.
    • RefCell, & Mutex do not implement Hash.
  • Serialize & Deserialize
    • This one essentially has to be deep to work. It is implemented by forwarding to the inner value for every type in serde.

Currently the signals all implement shallow versions of the traits above, with the exception of Serialize and Deserialize.


(This is a follow up to #2384)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant