[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)