[HN Gopher] What Are Signals? ___________________________________________________________________ What Are Signals? Author : sanketpatrikar Score : 38 points Date : 2023-03-03 13:38 UTC (1 days ago) (HTM) web link (signia.tldraw.dev) (TXT) w3m dump (signia.tldraw.dev) | revskill wrote: | Signal is a comonad in the category of endofunctors, what's the | problem ? | duped wrote: | At first I thought this was talking about Unix signals | | 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. | tested23 wrote: | Signals are a common term for this. Someone else invented the | term not the people who wrote this. | layer8 wrote: | The terminology of signals (and slots) has been used in Qt [0] | since the 1990s I believe. | | Still, it is unfortunate that the article begins with "Let's | start with an extremely broad definition" (of signals), then | continues with what sounds like signals in general, mentioning | React only as an example, but then turns out wanting to only | talk about signals in the particular reactive UI sense common | in web development, without properly introducing that narrowing | of focus. | | I guess that focus can be expected from a blog on a site about | a TypeScript signals library, but from the way the first few | paragraphs are written, it's certainly confusing when reading | the article without further context, coming from HN. | | [0] https://en.wikipedia.org/wiki/Signals_and_slots | ur-whale wrote: | > The terminology of signals (and slots) has been used in Qt | [0] since the 1990s I believe. | | Was confusing then and is still confusing now. | mananaysiempre wrote: | "Signal" was used for a time-varying value in a reactive system | for a very long time (I thought it was as far back as Fran in | 1998, but I was remembering wrong--I was only able to find | usage in Grapefruit in 2009, older references welcome). One way | or another, in a _functional_ reactive programming system, you | need distinct names for: | | (a) A thing that happens (or might happen but ultimately | doesn't) and is associated with a value of some sort, such as | the mouse coordinates of first left-button click the program | sees; | | (b) A list of the above with monotonically increasing times, | such as all the left-button click coordinates in order; | | (c) The above plus an initial value, representing a piecewise | constant function of time, such as the state of a toggle; | | (d) A (conceptually) piecewise continuous function of time, | such as the position of an animated object. | | [To avoid "time leaks", i.e. accidentally retaining all change | history from the beginning of time, you also need | | (e) A computation that reads the current time, such as the | mouse coordinates of the _next_ left-button click the program | will see; | | but that's not supposed to be obvious--it took more than a | decade to figure out.] | | Possible names include: event occurrence [for (a)], event | stream [for (b)], event [either (a) or (b)]; behaviour [(c) or | (d)--the library may not distinguish them in the API or only | provide (d)]; reactive [Conal Elliot's name for (c) as opposed | to (d)]; signal [(b), (c), or both]. _All of these make sense | in isolation._ I don't think you can win here. | | [Perhaps the worst word to use is "stream", because people | start trying to fit streams with backpressure in there. FRP | only makes sense as far as you can assume any recalculations | happen instantaneously, meaning at the very least before the | next input change happens. If you forget that, you get Rx | instead of FRP, and that's not amenable to human comprehension | --or indeed sanity.] | duped wrote: | I've always referred to and heard these referred to as | "events" and "sequences" with d/e being subtypes of either or | containing additional contexts. | | I'm not sure what you mean by "Rx" in this context. | | My background is much more in the systems (and indeed, | "signals" in the theoretical sense). | | I still think the name "signal" here is quite bad, since it's | the abstract concept of something-that-carries-information | mananaysiempre wrote: | > I'm not sure what you mean by "Rx" in this context. | | From "reactive extensions", a name for a family of | libraries[1] (RxJava, Rx.NET, RxJS), AFAIK one of the first | attempted implementations of mature FRP ideas in the | imperative world and one messy enough that it took React's | success for anything similar to reenter the mainstream. | | Compare the enthusiastic HN reception of "Deprecating the | observer pattern" in 2011[2], mostly by people who heard of | FRP in the functional-language setting, and the vitriol it | received in 2018[3], apparently from people for whom FRP | came to mean Rx (and similarly confused things like | Bacon.js). It is this vitriol that I meant to preemptively | redirect by the mention of FRP [?] Rx, so if you're not | aware of this history it's no big loss to ignore it. | | (Yes, I am very much No-True-Scotsmanning this. That should | not be taken to mean that reconciling FRP with side effects | is a trivial problem, though,--I'm not sure it's even a | solved one. Only that Rx and its ilk suck as a solution.) | | > My background is much more in the systems (and indeed, | "signals" in the theoretical sense). | | > I still think the name "signal" here is quite bad, since | it's the abstract concept of something-that-carries- | information | | I think the intention was to allude to physical wires and | conceptual analog or digital things they transmit, as in | "reset signal", "differential signalling", etc. It does | seem to me to be an apt term for a (continuous-)time- | dependent doodad in a program, given "variable" is taken. | | Your description sounds more like the information-theoretic | "channel" or "transmission medium". | | [1] https://reactivex.io/ | | [2] https://news.ycombinator.com/item?id=2972581 | | [3] https://news.ycombinator.com/item?id=17845341 | valtism wrote: | The term signal was used, because RxJS had already taken the | term "Observable" to refer to their primitives, which are | actually more like streams. | | Because of this, Ryan Carniato of SolidJS referred to his own | observable primitives as "signals" and this has become the | default terminology to talk about this type of pattern within | the context of web development. | | Really, signals should be thought of as a type of observable. | antegamisou wrote: | I felt similarly disappointed, as I was expecting a cool intro | to DSP or something similar. But nope, another BS buzzword from | the magical world of webdev. | blue039 wrote: | Signal isn't overloaded. It's use here is the same as it's use | elsewhere. It just requires contextual information to know what | it means. A Qt programmer might think of signals and slots, a | UNIX programmer might think of UNIX signals, etc. Jargon sure. | Overloaded? I don't think so. Only thing here that bothers me | is how vague the title is. | exclipy wrote: | Why does Signia exist when there's mobx? | c-smile wrote: | Hmmm... attempt to define signals using ReactJS' | useState()/useMemo() vocabulary appears as really bad idea. | | PReact's signal() as a concept is better - more pure. | https://preactjs.com/guide/v10/signals/ | jitl wrote: | It's kinda funny to see "signals" coming round into fashion or | popular discussion in front-end tech Twitter. Mobx is a signals | state management library has been around for 7 years. Notion used | signals internally for state management and often when engineers | joined they'd ask why we use signals over Redux, can we switch to | Redux because it's more modern, etc. Now it's 4 years later and | for some reason this pattern is all the rage. I'm glad I didn't | waste time on Redux just in time for trends to move on. | | 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. | Raed667 wrote: | There is a schism between "JS influencer Twitter devs" and | "Building actual apps devs" | | I have stopped taking seriously people that rely on novelty to | sell you their next training. | mrj wrote: | Same here, I have been spreading mobx everywhere I have gone. | There's usually some resistance but once people got used to | automatic dependency tracking, they never go back. | | I've seen so many projects get bogged down in props hell, then | gobs of context api and performance problems when too many | things react at once. | | Mobx has been solving these problems for a long time now! | satvikpendem wrote: | I don't really understand why people like signals again. I used a | signals-like reactive programming model in VueJS a while ago and | hated that you could never be sure exactly where things were | being changed. Thankfully it seems that the React creators and | maintainers are not hopping on the signals train and are instead | adamant about unidirectional dataflow with explicit mapping of | state to UI, which, as has been the reason for why React had been | invented in the first place, makes reasoning about the | application much easier [0][1]. | | 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 | aatd86 wrote: | Yes, it's more of a design problem of some of these libraries | though. | | Ideally, signalling shouldn't be retrofitted on normal | variables. It assumes then that you overload variable access | (assignment and reads). Then it's hard to knlw which variable | is reactive and which is not. The problem stems from the | overloading of semantics. | | A UI is mutable so it's not about mutable state being wrong but | the unit of variability are not program variables but rendered | props which are basically DOM Element properties. In react, it | just happens that it uses variables whose values are injected | in the DOM elements via jsx but that's an issue (especially | when dealing with exports, prop drilling etc) | | So until a plain variable and a reactive variable are made to | look different everuwhere in _code_ it remains confusing. And | even then, it 's not optimal. | | Disclaimer: I'm currently implementing a cross-platform UI | framework in Go and that's the reason why I had to think about | it since traditional languages do not have reactive variables. | marcosdumay wrote: | My impression is that Javascript is just an horrible language | to create reactive systems, and that default purity with | explicit effects is extremely underrated. (But then, I was | already biased.) | | It is hard to even make sense of the discussion without | imagining the details of how those frameworks are implemented. | And the discussion on the level of normal usage, not something | advanced or development oriented. | uxcolumbo wrote: | What language(s) would you recommend for building reactive | systems? | [deleted] | Existenceblinks wrote: | Because it's nicer. The mental model of reading the functions | using signals is; it's all about initialize|constructor|new | function. And then those off-jsx stuff starts to make sense | since you won't re-initialize those things. They need to exist | somewhere in particular execution model. In Solidjs, it's | effects (compiled from jsx where signals are read). I think | those who are familiar with static type languages, naturally | understand how signals needs to be unwrap/wrap .. like a | monoid, not a big deal. | satvikpendem wrote: | When you have a big app, it becomes a spaghetti mess, and I | speak from personal experience having to untangle that | spaghetti. | rapind wrote: | Elm managed to move away from signals back in 2016 | (controversial at the time, but IMO a great move). | | https://elm-lang.org/news/farewell-to-frp | anon4242 wrote: | I'm not a JS/Vue/React programmer but I would definitely expect | function One to return <div>Count: 4</div> if props.count == 2 | when One is _called_. For function Two I would be more | suspicious and would not be overly surprised if it returned | <div>Count: {props.count * 2}</div> to be evaluated at a later | stage. | fabiospampinato wrote: | That difference in the snippet you mentioned has 100% to do | with how Solid is compiling its JSX, and 0% to do with how | signals must work. | | If you don't like what Solid is doing you may consider it a | self-inflicted wound, nothing is forcing Solid to work that | way. | dustingetz wrote: | signals represent continuous time varying quantities, like an | electrical voltage, an audio signal or the current mouse | coordinates. streams (event streams) represent a sequence of | discrete events, like key presses or network packets or financial | transactions. 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. 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. | | I have no idea if JS projects get the backpressure right, can | anyone confirm? ___________________________________________________________________ (page generated 2023-03-04 23:00 UTC)