by sanketpatrikar on 3/3/23, 1:38 PM with 59 comments
by satvikpendem on 3/4/23, 8:14 PM
This is a good thread about their drawbacks [2]. Apparently, both the below examples actually do different things:
function One(props) {
const doubleCount = props.count * 2;
return <div>Count: {doubleCount}</div>
}
function Two(props) {
return <div>Count: {props.count * 2}</div>
}
Like the tweeter says, signals are mutable state. I'll stick with unidirectional data flow in React.[0] https://twitter.com/jordwalke/status/1629663133039214593
[1] https://twitter.com/dan_abramov/status/1629539600489119744
[2] https://twitter.com/devongovett/status/1629540226589663233
by duped on 3/4/23, 7:34 PM
Then I thought for a moment it was talking about a "signal" in the information theoretical sense
All I came away with was that they've invented a new name for event driven architectures and/or data flow programming.
I know naming is hard but we need to stop overloading terms.
by dustingetz on 3/4/23, 10:27 PM
the key difference is in backpressure strategy: signals are canonically lazy, they don’t compute or do work until sampled, and only the latest value is relevant (nobody cares where the mouse was a moment ago when nobody was looking). streams are eager, you can’t skip a keyboard event or a financial transaction, even if the pipes are backed up – instead you have to tell upstream to slow down so you can catch up. The benefit of event streams is the guarantee that you'll see every event, which means streams are suitable for driving sequences of side effects (keyboard event -> network request -> database transaction).
signals are a good fit for rendering because you only want to render at up to say 60fps (even if the mouse updates faster, which it does). and you only want to render what’s onscreen, and only when the tab is focused. rendering (say dom effects) is indeed effectful but not in the discrete way; the dom is a resource, it has a mount/unmount object lifecycle, and due to this symmetry it is a good fit for rendering whereas isolated effects (without a corresponding undo operation) are a terrible fit for signals because backpressure will drop events and corrupt the system state.
You can use streams for rendering too, but it's dis-optimal, and potentially by a lot. If your app chokes on a burst of events, you want to skip ahead and render the final state without bothering to render all the intermediate historical states. Signal laziness is what enables this "work skipping"; a stream would have to process each individual event in sequence.
I have no idea if JS projects get the backpressure right, can anyone confirm?
by jitl on 3/4/23, 7:42 PM
To discuss more specifically TLDraw’s Signia library, I think the ability to do manual diff tracking & incremental updates for computed stores is an interesting “escape hatch”. Docs here: https://signia.tldraw.dev/docs/incremental
Most signal libraries I’ve seen try to lean hard into magic auto-tracking of dependencies which means they make it really easy for the developer to correctly observe a lot of dependencies, cool on correctness, but then have a very limited set of tools to deal with the performance implication of some computation needing to re-run a whole bunch. The differential tracking here means that if you see such a hotspot, you can get really manual optimization of recomputation without needing to squeeze into the libraries pre-packaged observable collection API.
Downside of this API is it seems quite easy to get it wrong.
Another thing I like about Signia is the use of logical time. I saw this first in Jotai internals, then in Starbeam. I haven’t dug into the source of the library yet but I think logical time is a good approach and makes inspecting internals make a bit more sense than inspecting systems (like Notion’s) that rely purely on update notification listeners.
by beders on 3/5/23, 6:03 AM
Subscriptions grow from the leaf up to the root (which is a single app "db") and so computation is minimal. If something writes to the "db", only relevant subscriptions are recomputed and only views subscribing to those are "repainted".
Works like magic.
by c-smile on 3/4/23, 9:46 PM
PReact's signal() as a concept is better - more pure. https://preactjs.com/guide/v10/signals/
by syngrog66 on 3/5/23, 2:04 AM
Nope.
by exclipy on 3/4/23, 8:08 PM
by pictur on 3/5/23, 7:00 AM
by revskill on 3/4/23, 7:49 PM
by LAC-Tech on 3/5/23, 12:58 AM
Now they're back, baby. Happy to see them used again, even if we've had to razzle it up a bit with a new name.