[HN Gopher] A proposal to add signals to JavaScript
       ___________________________________________________________________
        
       A proposal to add signals to JavaScript
        
       Author : beeman
       Score  : 149 points
       Date   : 2024-03-31 17:48 UTC (5 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | nullvoxpopuli wrote:
       | Socials:
       | 
       | - Reddit:
       | https://www.reddit.com/r/javascript/comments/1bsgnf5/tc39_pr...
       | 
       | - X/Twitter:
       | https://twitter.com/nullvoxpopuli/status/1774496900915327100
       | 
       | - Masto:
       | https://mastodon.coffee/@nullvoxpopuli/112191605019758002
       | 
       | - Blue Sky:
       | https://bsky.app/profile/nullvoxpopuli.bsky.social/post/3koz...
        
       | senoralligator wrote:
       | Surely it would be better to fix the interoperability issues of
       | the language? "Lets just add a single implementation of
       | everything to the standard!" seems like quite a strange response
       | to "users of the language are having trouble with
       | interoperability due to false coupling."
        
         | jauntywundrkind wrote:
         | I don't think the language hurts or hinders interop much? It
         | has a wide range of tools that can adapt objects between
         | different shapes, for when we do have two similar but different
         | interfaces we are trying to bridge.
         | 
         | I struggle to see what more one could want. Do you have any
         | specific features you think would help a massive ecosystem of
         | packages be able to work together, when for example different
         | packages have different Signal implementations?
        
           | senoralligator wrote:
           | Better ways to describe polymorphism, a better type system in
           | general really. Look to async Rust for a great example of
           | such interoperability.
        
         | nullvoxpopuli wrote:
         | is it strange?
         | 
         | Vue reactivity isn't compatible with Svelte, nor Angular.
         | 
         | As a counter example to your question, what if we all had
         | competing implementations of the object primitive. Libraries
         | would barely work with one another and would need an interop
         | layer between them (just as reactivity layers do today!)
        
           | senoralligator wrote:
           | I'll admit I don't use JavaScript very often, but surely the
           | state of polymorphism could be improved? For example, C++
           | recently added concepts, and most (modern) languages have
           | some way to describe interfaces.
           | 
           | As to your counterexample, I agree with current JavaScript
           | that would be a problem, but with good language support it
           | would certainly be possible. For example, Rust (and C++?)
           | have competing implementations of the global allocator, and
           | must users will never notice.
        
             | zdragnar wrote:
             | The reactivity layers are all pretty tied into the hearts
             | of the frameworks. There's no advantage to any framework to
             | expose such a thing to end users to leverage a competing
             | implementation.
             | 
             | As for polymorphism, even the current class syntax largely
             | operates in the same way as the original prototypal
             | inheritance mechanism, with a few exceptions in constructor
             | behavior to support subclassing certain built-in objects.
             | 
             | You can pretty easily create run-time traits- like
             | functions with prototpyes, the class construct is an
             | expression whose resulting value can be passed around,
             | mutated, etc.
             | 
             | For example, you can write a function that takes a class as
             | an argument, and returns a new class that extends it.
        
         | polynomial wrote:
         | Isn't this similar to small core vs large core debates you see
         | in other projects, often where drivers are concerned? (ie
         | question around where the coupling layer is materialized)
        
       | __s wrote:
       | Promises are a nice success story, but without async/await it
       | wasn't really necessary to standardize
       | 
       | > The current draft is based on design input from the
       | authors/maintainers of Angular, Bubble, Ember, FAST, MobX,
       | Preact, Qwik, RxJS, Solid, Starbeam, Svelte, Vue, Wiz, and
       | more...
       | 
       | Would be interested what existing library authors think of this
       | proposal. Interesting that React is not in that list
       | 
       | Signals are a bit like channels, except they're broadcast instead
       | of single receiver. It'd be neat if this could somehow be
       | leveraged to allow web workers to communicate with channels
       | instead of onMessage callbacks. Specifically being able to
       | `select` over signals/channels/promises like in Go would over a
       | syntactic benefit over having to try manage multiple concurrent
       | messaging mechanism with callbacks (maybe by allowing signals to
       | be included in `Promise.any`)
        
         | watson wrote:
         | > Promises are a nice success story, but without async/await it
         | wasn't really necessary to standardize
         | 
         | One benefit of standardisation that's not tied to async/await
         | is that the JavaScript engines has been able to do performance
         | optimisations not otherwise possible which benefit Promise-
         | heavy applications
        
         | KRAKRISMOTT wrote:
         | Maybe they can call it "EventEmitter"
         | 
         | https://nodejs.org/en/learn/asynchronous-work/the-nodejs-eve...
        
           | __s wrote:
           | That looks like it fits with the theme, but events are
           | difficult to compose & tend to have easy leaks by requiring
           | explicit attach/detach (not that I'm sure the proposal here
           | addresses those issues)
        
         | pavlov wrote:
         | _> "Interesting that React is not in that list"_
         | 
         | Signals are not a part of the core React API, unlike Preact.
         | 
         | My vague gut feeling is that signals are too much like a
         | generalized useEffect() and would only introduce further
         | confusion into React by muddling what happens during the render
         | cycle. For better and worse, React takes a different tack to
         | updates than signals do. But maybe I'm wrong about their
         | applicability.
        
           | whizzter wrote:
           | My feeling is that it's philosophically outside the purview
           | of React whose focus is rendering (and components and their
           | state but not global state), RxJS and and MobX are both
           | usable with React and have signals whilst Redux goes another
           | route and React is "above" that choice.
        
           | Fatalist_ma wrote:
           | There is an interesting debate about React and signals in the
           | comments of this article, between Dan Abramov and Ryan
           | Carniato - https://dev.to/this-is-learning/react-vs-
           | signals-10-years-la...
        
             | pavlov wrote:
             | I read it until the point where he defends the idea that
             | these two functions obviously do something completely
             | different:                 function One(props) {
             | const doubleCount = props.count * 2;         return
             | <div>Count: {doubleCount}</div>;       }
             | function Two(props) {         return <div>Count:
             | {props.count * 2}</div>;       }
             | 
             | It honestly made me wonder whether the article was dated
             | April 1 and I'd been had.
             | 
             | More generously, JS framework design is hard. If you're
             | ambitious at all, you end up fighting the language and your
             | runtime paradigms will hang like ill-fitting clothes on its
             | syntax. The One/Two example above shows how easily
             | expectations break in this world of extensions to
             | extensions. There's no way to know what an apparently
             | simple piece of code will actually do without knowing the
             | specifics of a given framework.
        
         | dclowd9901 wrote:
         | React isn't in this list because its effects are declarative,
         | not imperative (except for props changes and re-renders which
         | you could argue are in fact declarative, just one abstraction
         | removed). UseEffect neatly compartmentalizes imperative
         | behavior.
         | 
         | This looks a lot like ember data binding which becomes an
         | imperative nightmare. Its default state is "foot gun" with tons
         | of cognitive overhead and meta patterns to keep it from getting
         | that way.
        
         | bastawhiz wrote:
         | > without async/await it wasn't really necessary to standardize
         | 
         | Hard disagree.
         | 
         | `x instanceof Promise` simply doesn't work. If my library has a
         | then method that accepts a catch callback and yours doesn't,
         | they're silently non-interoperable, and there's no way to
         | detect it. When does `finally` run? What expectations can you
         | have around how async the callbacks are? Without a standard,
         | every single library that uses promises needs to bring its own
         | polyfill because you can't trust what's there. And you can't
         | actually consume any other library's promises, because you
         | can't trust that they behave in the way you expect them to.
         | 
         | And I'm not just speculating, this was reality for many years
         | and a hell that many of us had to endure.
        
       | lambdaba wrote:
       | This looks very much like mobx, which is my favorite JS effect
       | system.
       | 
       | Here is the mobx version:                 import { observable,
       | computed, autorun } from 'mobx';            const counter =
       | observable.box(0);            const isEven = computed(() =>
       | (counter.get() & 1) === 0);            const parity = computed(()
       | => isEven.get() ? "even" : "odd");            autorun(() => {
       | element.innerText = parity.get();       });            //
       | Simulate external updates to counter...       setInterval(() =>
       | counter.set(counter.get() + 1), 1000);
        
         | kabes wrote:
         | Well, mobx is signals. But signals where the dependencies are
         | tracked implicitly via the proxy ovject, instead of explicitly
         | by a getter.
        
       | alserio wrote:
       | really looking forward to get nice dev tools out of this work
        
       | ivanjermakov wrote:
       | Is dependency tracking problem statically solvable (without
       | calling effect once and subscribing to all .get's)?
       | 
       | I don't think this needs to be a language feature, rather
       | abstraction of existing features. In other words, can't this be a
       | library?
       | 
       | I know that SolidJS is able to figure out dependent signals, but
       | probably doing so on the first execution.
        
         | ivan_gammel wrote:
         | >In other words, can't this be a library?
         | 
         | It is explicitly mentioned in the proposal. The problem with
         | 3rd party libraries is their interoperability and diversity of
         | implementations, which might be unnecessary for this kind of
         | things.
        
         | twiss wrote:
         | I believe Svelte does figure it out at build time.
         | 
         | Which does make me question the mention of Svelte in the
         | proposal, and makes me wonder what the Svelte developers think
         | of it - because IIUC they indeed don't need this (at runtime),
         | if I'm not mistaken.
        
           | Phillippe wrote:
           | The current Svelte version does it at build/compile time. The
           | up and coming Svelte 5 is using signals and the reactivity is
           | moved to runtime
        
         | bastawhiz wrote:
         | > In other words, can't this be a library?
         | 
         | You answered your own question:
         | 
         | > I know that SolidJS is able to
         | 
         | It already is, obviously. But how is SolidJS supposed to work
         | with other non-SolidJS code? It can't. Unless every library
         | builds support for every other library, they can't possibly
         | interoperate.
        
           | ivanjermakov wrote:
           | It's a shame that JS ecosystem is so sparse.
           | 
           | E.g. in Rust it's much more common to rely on existing
           | "building blocks" like futures, tokio, syn, serde even just
           | for basic bindings, favoring interoperability.
        
       | mg wrote:
       | When I need to signal something across my application, I use
       | events:                   window.dispatchEvent(new
       | Event('counterChange'));
       | 
       | And every part of the application that wants to react to it can
       | subscribe via
       | window.addEventListener('counterChange', () => {             ...
       | do something ...         });
       | 
       | Anything wrong with that?
        
         | hk__2 wrote:
         | > Anything wrong with that?
         | 
         | It has all the downsides of the pub/sub architecture
         | highlighted in the proposal.
        
         | ivan_gammel wrote:
         | Did you read the document? They have an example there, which is
         | quite similar to yours, and explain what is the problem.
        
           | explaininjs wrote:
           | No, they don't. In fact, if you search "event" in the
           | proposal you get exactly one result, the prefix of
           | "eventually". This is a serious shortcoming of the proposal
           | that should be addressed.
        
             | throwitaway1123 wrote:
             | I think the comment you're replying to is referring to the
             | pub/sub sections of the proposal. They don't explicitly
             | mention events, but events are a subset of the
             | publish/subscribe pattern.
        
               | explaininjs wrote:
               | But then so are signals.
               | 
               | The only "benefit" signals as proposed here give you is
               | less control over the exact dispatch pattern of the
               | graph, for instance things like debouncing, throttling,
               | batching, etc etc etc. Aka all the things you absolutely
               | must have control over if you want to make something
               | resembling a high performance application.
        
               | naasking wrote:
               | Signals are not a subset of events. Signals combine event
               | subscription with value construction, which promotes a
               | remote declarative model for updates.
               | 
               | > The only "benefit" signals as proposed here give you is
               | less control over the exact dispatch pattern of the
               | graph, for instance things like debouncing, throttling,
               | batching,
               | 
               | Events don't give you any more control over those
               | properties than signals, they just require more
               | boilerplate.
        
             | ivan_gammel wrote:
             | Oh, come on. They do have an example of architecture, not
             | literal example of events. It doesn't matter what trivial
             | implementation of Observer pattern you choose.
        
               | explaininjs wrote:
               | Except one is already built into the language? And it
               | provides all the upsides of signals with none of the
               | downsides? (Modulo proper use of `using` directives)
        
           | ahmedfromtunis wrote:
           | Can you please point to where in the document such an example
           | was mentioned? I rechecked the document and couldn't find it.
        
             | ivan_gammel wrote:
             | Just look for the example of a design pattern (,,Example -
             | A VanillaJS Counter" section), not for a literal
             | implementation of it via events. Conceptually they are the
             | same.
        
         | djbusby wrote:
         | I've been using patterns like this for more than a decade. The
         | thing that's hard is, down the road you could have a listener,
         | which triggers a other event, then another event, which comes
         | back to the first routine and now you got a listen-loop that
         | won't quit.
         | 
         | And it's hard to ensure that all listener don't cause that
         | trigger cascade.
        
           | eddd-ddde wrote:
           | Isn't it possible to define all listeners / publishers in a
           | declarative way which can be compiled to catch for this
           | issues?
        
             | berkes wrote:
             | Yes. It is. And most pub/sub or Observer architectures and
             | design patterns have the "loop" thing solved just fine.
             | 
             | In fact, the GOF spend an entire paragraph on the problem
             | of complex update semantics in "design Patterns" (1995) ch
             | Observer p299.
             | 
             | So, while it is a real problem, it's one that has been
             | solved (for at least 29 years)
        
         | cyanydeez wrote:
         | Mostly the teardown logic and inevitable memory leaks.
         | 
         | A alt proposal would be some kind of auto remove listener if it
         | goes out of context
        
           | explaininjs wrote:
           | The new `using` feature handles RAII just fine. This proposal
           | is entirely unnecessary given the existence of `using` and
           | the already-existing event listeners.
           | https://iliazeus.github.io/articles/js-explicit-resource-
           | man...
        
             | lelandfe wrote:
             | Quite a good link, thanks.
        
           | gray_-_wolf wrote:
           | Maybe a stupid question, but isn't the memory released anyway
           | when I close the tab? So why do memory leaks matter?
        
             | dr_kiszonka wrote:
             | Not a web dev person, but some "tabs" have a very long
             | lifetime, e.g., webmail clients, Whatsapp, etc.
        
             | leptons wrote:
             | The problem is if you don't close the tab, the memory leak
             | can cause that one tab's memory to balloon to 1GB or more
             | because memory isn't being released, when that tab should
             | only be consuming 50MB.
        
             | zdragnar wrote:
             | It depends on how much you're leaking, and how fast.
             | 
             | Best case scenario, it just slows down garage collection a
             | little bit, as you're holding into a lot of references that
             | aren't going anywhere.
             | 
             | On the other hand, I recall a bug in a particular version
             | of AngularJS where component DOM nodes wouldn't get cleaned
             | up when navigating with the router unless you manually set
             | all of the scope values their templates used to null.
             | 
             | We had a data dense application with tables and what not,
             | and you could clearly watch memory jump tens or more
             | megabytes flipping between pages in the chrome dev tooling.
             | 
             | Eventually (this was a SPA intended to be used for upwards
             | of hours at a time) the page would crash.
        
             | Xenoamorphous wrote:
             | Have you ever seen Chrome's "aw, snap!" screen (if you use
             | Chrome)?
             | 
             | More often than not that's due to a memory leak.
        
         | explaininjs wrote:
         | This pattern is precisely what everyone's favorite "look,
         | JS/electron can be high performance!" example uses. (VS Code).
        
         | zdragnar wrote:
         | According to TFA, event emitters / observables cause
         | unnecessary work when called multiple times.
         | 
         | The difference with signals is that the resulting value is only
         | ever calculated when the end consumer reads the value- so you
         | schedule render updates asynchronously from the actual writes
         | to the signal, and whatever chain of computations the watchers
         | perform is done just the one time during the render.
         | 
         | Interim values sent to the signal will get lost, so you really
         | can't do too much interesting work in them. It's really just a
         | fancy abstraction layer to coordinate a rendering cycle.
        
         | _the_inflator wrote:
         | Historically, this example is the reason why the Web evolved
         | into jQuery and from there forked into the world of Angular and
         | React mainly.
         | 
         | Event handling is getting messy very easily. If you want to get
         | deeper into it, have a look at event bubbling and propagation.
         | 
         | Large applications need a robust event handling. This is the
         | nowadays hidden benefit of frameworks like Angular, Vue etc.
         | 
         | Believe me, you don't want to use the standard event handling
         | API without a framework. Adding, deleting, cloning, firing,
         | removing, fire once etc on many elements can have serious
         | unwanted side effects.
        
           | beezlewax wrote:
           | What kind of side effects specifically?
        
             | doomroot wrote:
             | I believe memory leaks to start
        
               | falcor84 wrote:
               | Are you implying that there are memory leaks in browsers'
               | internal implementation of events? Because my take is
               | that the problem is with "user space" scripts not
               | cleaning up after themselves, and I don't see how that
               | would get better by adding yet another API to be mindful
               | of.
        
               | gibbitz wrote:
               | I believe this would be more related to something like
               | memoizing a DOM structure in a "Live" listener that is
               | later removed from the DOM but not garbage collected due
               | to the reference in the event listener. As the poster
               | mentioned, developer error -- not a fundamental language
               | or browser implementation flaw.
        
               | Klonoar wrote:
               | This is one of those points where you need to link to
               | some kind of data or conclusive result actually
               | showcasing this, because you're arguing against a pattern
               | that's been in browser ecosystems for decades. I've done
               | this for larger applications and haven't experienced
               | issues.
               | 
               | Being charitable, the best I can imagine right now that'd
               | cause memory leaks is someone running into the old school
               | JS scoping issues and capturing something in handlers
               | that they shouldn't. That's not the handler itself that's
               | the problem, though - that's the developer.
               | 
               | (Yes, we could rant on and on about the poor design
               | decisions that JS has built in, but that's been beaten to
               | death)
        
               | unemployable wrote:
               | Memory leaks can occur when a component adds events to an
               | element outside of the component (such as the window) and
               | then gets removed from the DOM without removing the event
               | handler from the window. This is solved in native Web
               | Components by the mount/unmount methods where you can run
               | code to remove event listeners when the component has
               | been unmounted.
               | 
               | For other event listeners, they get removed when the DOM
               | element is removed.
               | 
               | The frameworks do not solve this to any greater degree.
               | They also just make everything invisible and behind-the-
               | scenes and hard to debug due to their declarative nature,
               | but that is another topic.
        
           | andrewstuart wrote:
           | I use events extensively in large applications and its never
           | been a problem. In fact they solve complexity.
        
           | unemployable wrote:
           | >If you want to get deeper into it, have a look at event
           | bubbling and propagation.
           | 
           | In this example, the event is on the Window. There is no
           | bubbling. It is already at the top level.
           | 
           | >Believe me, you don't want to use the standard event
           | handling API without a framework. Adding, deleting, cloning,
           | firing, removing, fire once etc on many elements can have
           | serious unwanted side effects.
           | 
           | I don't know what this means. The frameworks do not have much
           | to do with this topic.
        
         | nurple wrote:
         | Welcome to Node.js v21.6.2.       Type ".help" for more
         | information.       > window.dispatchEvent(new
         | Event('counterChange'))       Uncaught ReferenceError: window
         | is not defined
        
           | runarberg wrote:
           | $ node         Welcome to Node.js v20.6.1.         Type
           | ".help" for more information.         > const target = new
           | EventTarget()         undefined         >
           | target.dispatchEvent(new Event("counterChange"))         true
        
             | nurple wrote:
             | tyvm!
        
         | lelanthran wrote:
         | > Anything wrong with that?
         | 
         | Well, don't events only bubble upwards? You need to know the
         | exact element of it is not on a lower level in the DOM tree.
         | 
         | Events were too messy, so I wrote a small pub/sub message queue
         | type of thing. Anyone anywhere in the DOM can subscribe to
         | messages based on subject regexes.
         | 
         | Makes things a lot easier, especially when I added web
         | components to wrap existing elements so that publishing and
         | subscribing is done with attributes, not js.
        
           | everybackdoor wrote:
           | You can also fire events on pretty much any object,
           | essentially creating a channel where the message bus queue is
           | the vm event queue.
        
         | dakom wrote:
         | It's often desirable for UI to be described in a declarative
         | fashion, i.e. instead of where you have "do something" (set
         | button color to red), refactoring so it becomes "is something"
         | (button is red if state is x)
         | 
         | I might not be describing that well, because once you go down
         | that road it really becomes a whole overall approach that
         | infects the whole program (like functional reactive
         | programming), and so it's really about how the whole flow fits
         | together from top to bottom, and that can be very elegant.
         | 
         | I don't think that's the right fit for everything, i.e. in
         | gamedev it might make more sense to just update some object's
         | position imperatively, but for UI it tends to work pretty well.
        
         | LittleDan wrote:
         | LGTM! Smells like Redux (in a good way). But then ultimately at
         | the root you probably want the event to update your "model",
         | and then that leads to an update of the "view". This is the
         | part where signals can be useful.
        
         | briantakita wrote:
         | > Anything wrong with that?
         | 
         | It only works in browser environments.
        
           | lelandfe wrote:
           | Node has EventEmitter:
           | https://nodejs.org/en/learn/asynchronous-work/the-nodejs-
           | eve...
           | 
           | See, for instance,
           | https://www.electronjs.org/docs/latest/api/ipc-renderer
        
         | kabes wrote:
         | Signals are also just pub/sub, but with a more ergonomic api.
         | More ergonomic because listeners are added and released
         | automatically.
         | 
         | It can also be more performant, eg, say you have a computation
         | that depends on 2 values:
         | 
         | `result = a ? b : 0`
         | 
         | Then if a is falsy, we don't need to recompute if b changes.
         | This is achieved automatically with signals, but would require
         | quite some code with classic pub/sub.
        
         | fwlr wrote:
         | If you mis-type 'countenChange' it could be quite frustrating!
        
           | everybackdoor wrote:
           | In 2024 we have linters and other static analysis tools for
           | catching these kinds of things right in the IDE.
        
           | berkes wrote:
           | If that truly is your reason to choose or forego a software
           | design pattern, than what the h. are you doing with
           | JavaScript?
        
       | lloydatkinson wrote:
       | Sorry but I'll be a little bit mad if this Preact/Angular
       | inspired thing is approved and made part of the spec, while
       | Observable was deliberately ostracised.
        
         | troupo wrote:
         | > I'll be a little bit mad if this Preact/Angular inspired
         | thing
         | 
         | Signals predate both and originate in KnockoutJS at least. They
         | were popularized in recent years by SolidJS. And then adopted
         | into Preact, Vue and others. Angular is a very late newcomer to
         | the signals game.
         | 
         | Edit: and this is literally in the introduction section:
         | 
         | --- start quote ---
         | 
         | This first-class reactive value approach seems to have made its
         | first popular appearance in open-source JavaScript web
         | frameworks with Knockout in 2010. In the years since, many
         | variations and implementations have been created. Within the
         | last 3-4 years, the Signal primitive and related approaches
         | have gained further traction, with nearly every modern
         | JavaScript library or framework having something similar, under
         | one name or another.
         | 
         | --- end quote ---
         | 
         | The list of libraries in the README is alphabetized, and
         | doesn't reflect the evolution of signals in the frameworks and
         | libraries.
        
       | ivan_gammel wrote:
       | I like the quality of this proposal, which reminds me of JSRs. It
       | does make a lot of sense.
        
       | andrewstuart wrote:
       | What does this buy me over events?
        
         | troupo wrote:
         | Automatic dependency tracking, guarantees against circular
         | references, improved observability and potentially better
         | devtools
        
           | everybackdoor wrote:
           | And a backdoor in a build tree
        
           | andrewstuart wrote:
           | That's not enough to compete with an existing "good enough"
           | solution.
        
             | troupo wrote:
             | There's no existing "good enough" solution for reactive
             | values in JS.
             | 
             | Also https://news.ycombinator.com/item?id=39887187
        
               | claytongulick wrote:
               | Getters and setters work pretty well.
               | addEventListener("foo", () => {...}, {once: true})
               | 
               | Is a pretty easy way of handling one-shot events.
               | 
               | Those have been "good enough" for me to build large,
               | complex healthcare applications.
        
       | makkesk8 wrote:
       | Looks useful, but what baffles me is.. Why is every framework
       | setting state or their "signals" using "setX" functions? What's
       | wrong with the built in getter and setters that you can either
       | proxy or straight up override?
       | 
       | This feels arguably cleaner: something = "else";
       | 
       | Than: setSomething("else");
        
         | j1elo wrote:
         | For one I can write ".set" and the IDE would auto-complete with
         | all possible somethings that can be set, even without having
         | the slightest idea of which ones there are.
         | 
         | I've very much enjoyed this kind of consistency wherever is
         | found (having a common prefix for common behaviors, in this
         | case, setters)
        
         | dclowd9901 wrote:
         | One big problem is right now they are _tremendously_ slow to
         | use. (At least through the Proxy native class). Not sure if
         | this is an artifact of JITs or the nature of prototypal
         | inheritance.
        
         | notnullorvoid wrote:
         | Some libraries that feature signals style reactivity do use
         | getter and setters (ember.js, and mobx are 2 good examples).
         | However it makes sense for the primitive API to use functions
         | since getter and setters are functions under the hood and get
         | applied to an object as part of a property descriptor. It's
         | also not always desirable to have a reactive value embedded in
         | an object, sometimes you just want to pass around a single
         | changeable value.
         | 
         | As for why some libraries choose the `[thing, setThing] =
         | signal()` API (like solid.js) that's often referred to as read
         | write segregation. Which essentially encourages the practice of
         | passing read only values by default, and opting in to allowing
         | consumer writes on a value by explicitly passing it's setter
         | function. This is something that was popularized by React
         | hooks.
         | 
         | Either way this proposal isn't limiting the API choice of
         | libraries since you can create whatever kind of wrappers around
         | the primitive that you want.
        
         | chuckadams wrote:
         | well to use setters it has to be "foo.something = else",
         | because JS can't override plain old local bindings -- not since
         | "with" was sent to the cornfield anyway. Once you do that, you
         | can indeed have a framework that generates getters and setters,
         | which is exactly what Vue 2 does. Switch to proxies instead of
         | get/set and you have Vue 3 -- the signals API is pretty much
         | identical to the Vue composition API.
        
       | everybackdoor wrote:
       | - They're saying " _the community_ wants less boilerplate"
       | 
       | - They introduce what is effectively a black-box system
       | 
       | - The new system is expected to handle all application state
       | 
       | - They try to push it for frontend folks while also remarking
       | that it would be useful for _build systems_
       | 
       | This has the same red flags the xz saga had.
       | 
       | Have we learnt nothing.
       | 
       | Lots of "users" here vouching for the pattern and hoping it gets
       | adopted. I bet this gets some nice damage control replies because
       | there's social engineering going on here right now and most seem
       | to not be aware of it.
        
       | londons_explore wrote:
       | Can't we just call javascript 'done'?
       | 
       | We keep adding things to the language, and never subtract
       | anything, which means learning it as a language is getting harder
       | and harder.
        
         | troupo wrote:
         | They don't add these to the language. They add these to the
         | (currently basically non-existent) standard library.
         | 
         | Given that almost every single framework under the sun (except
         | React) has converged on signals, it makes sense to move that
         | into the browser. This... this is how the web is supposed to
         | work.
        
         | Waterluvian wrote:
         | I dunno. I sometimes feel the same, but a whole ton of recent
         | features have been incredible at cleaning up code.
         | 
         | ?? Is my favourite.
         | 
         | I also want set functions and possibly a match statement
         | thingy.
        
       | angleofrepose wrote:
       | Off topic, but I'm wondering if anyone attracted to this topic
       | could help me understand why JavaScript doesn't have macros.
       | 
       | I'm aware of much conversation around dismissing macros, often in
       | the context of bad dev experience -- but this sounds like a
       | shallow dismissal to me.
       | 
       | At the end of the day, we have some of the results of macros in
       | the JavaScript ecosystem, but rather than being supported by the
       | language they are kicked out to transpilers and compilers.
       | 
       | Can anyone point me to authoritative sources discussing macros in
       | JavaScript? I have a hard time finding deep and earnest
       | discussion around macros by searching myself.
        
         | hoten wrote:
         | You could start here:
         | https://github.com/search?q=org%3Atc39%20macro&type=code
        
           | angleofrepose wrote:
           | A great resource that I should have found on my own. Thank
           | you. I'll look through this later. Giving it a quick glance
           | now I see some of the same language I see other places; here
           | that macros are "too far."
           | 
           | I don't know why macros are approached with apprehension. As
           | I briefly get at in my first comment, I'm aware of a lot of
           | dismissals of macros as a tool, but those dismissals don't
           | make sense to me in context. I'm missing some backstory or
           | critical mind-share tipping points in the history of the
           | concept.
           | 
           | What could be a good set of sources to understand the
           | background perspective with which TC39 members approach the
           | concept of macros?
        
         | notnullorvoid wrote:
         | Macros don't really make sense in JS runtime spec. Since you
         | can mostly already achieve macro level features by using eval
         | or new Function, but it's not very efficient. Macros make most
         | sense at build time, and there have been a few attempts at
         | generalized build macros with various bundlers / transpiler
         | plugins. I think the space needs more time to mature. I'm
         | optimistic that we'll eventually see some sort of (un)official
         | macro spec emerge.
        
         | bastawhiz wrote:
         | Interpreted languages rarely have macros.
         | 
         | But more importantly, do you really want script tags on
         | webpages defining macros that globally affect how other files
         | are parsed/interpreted? What if the macro references an
         | identifier that's not global? What if I define a macro in a
         | script that loads after some other JavaScript has already run?
         | Do macros affect eval() and the output of
         | Function.prototype.toString?
         | 
         | Sure, you could scope macros to one script/module to prevent
         | code from blowing up left and right, but now you need to repeat
         | your macro definitions in every file you create. You could
         | avoid that by bundling your js into one file, but now you're
         | back to using a compiler, which makes the whole thing moot.
        
       | calebpeterson wrote:
       | Not a bad thing at all... but this is the same mental model
       | provided by the so-called atom-based state management systems in
       | React. I believe Jotai is the most popular.
        
       | kookamamie wrote:
       | Looks bad. It adds what looks like more nonsense complexity.
       | Also, "Signals" as a name is not descriptive to what is proposed
       | (see e.g. Qt Signals).
        
         | tqwhite wrote:
         | Yes. Thank you. I am already tired trying to figure out how
         | this would improve my life and annoyed at trying to read other
         | people's code that has more abstracted crap in it.
        
         | notnullorvoid wrote:
         | I do personally think signal is a bit of a poor naming choice,
         | but it has become probably the most recognizable term used for
         | the concept in the JS ecosystem. There's not a whole lot of
         | short concise naming options either, but maybe "Reactive
         | Values" is better?
        
       | dclowd9901 wrote:
       | Cool. My least favorite, cumbersome and brittle aspect of using
       | Ember becoming a core aspect of JavaScript functionality.
       | 
       | No fucking thank you.
        
       | rblatz wrote:
       | The lack of signals isn't remotely the largest issue with JS, and
       | adding them has minimal impact for most users of JavaScript. The
       | biggest issue is the lack of a standard library, resulting in npm
       | hell in most projects.
        
         | phpnode wrote:
         | JS does have a standard library and this proposal is about
         | expanding it, so that's good, right?
        
           | mrpepka wrote:
           | Unless it's half-assed, clumsy and short-sighted, and we are
           | stuck with it forever, because standard. Until one's
           | implementation becomes a standard thanks to the fact it wins
           | as a library (as jQuery did), it should not be slyly forced
           | into the language.
        
         | alexchamberlain wrote:
         | This is referenced in the proposal:
         | 
         | > JavaScript has had a fairly minimal standard library, but a
         | trend in TC39 has been to make JS more of a "batteries-
         | included" language, with a high-quality, built-in set of
         | functionality available
         | 
         | I think the description "minimal" is fairer than "no" wrt the
         | standard library.
        
         | preommr wrote:
         | Strongly disagree - it's trivial for a project to just add a
         | small std-lib, or add lodash as a single dep, or just add it
         | directly as source code.
         | 
         | JS projects exist in npm hell because people have been taught
         | to use a library to save typing 10 characters. No standard
         | library is going to fix. Because someone can just call in a new
         | lib that just curries something in the standard lib with minor
         | improvements like caching.
        
       | tambourine_man wrote:
       | I've been trying for decades to understand why people find it so
       | hard to keep track of state and update the DOM.
       | 
       | Sure, it requires a bit of discipline, but it's vastly simpler to
       | me than whatever solution comes up every few years (Backbone,
       | Knockout, Angular, React, modifying the language itself, etc).
       | There must be something profoundly different with the way I
       | think.
       | 
       | It even expresses itself in the function naming. They call
       | updating innerText "render". You're not rendering anything. At
       | most, the browser is, but so is everything else it does related
       | to painting. It feels like a desperate attempt to complicate what
       | is one of the simplest DOM functions. It really baffles me.
        
         | duxup wrote:
         | In simple applications it is easy.
         | 
         | More complex it is not easy.
        
           | tambourine_man wrote:
           | I've been writing web apps for easily 25+ years. Never have I
           | reached for React and friends voluntarily. But again, I know
           | I'm in a minority. I'm just not completely sure why.
        
             | duxup wrote:
             | You could work for 50 years and never need those... it just
             | depends on what you're creating / how many devs and so on.
             | 
             | I know some guys who over the years wrote their own
             | framework. It works great... for them.
        
               | tambourine_man wrote:
               | Right, the only thing that convinces me is team and
               | hiring dynamics. But that's not what these tools
               | advertise.
               | 
               | It's always like: you have dozens of interactive controls
               | in this view, it's getting out of hand, you should use
               | this language that compiles to HTML and JavaScript and
               | carry all these dependencies. To which I always reply: no
               | thanks, I rather deal with the dozens of controls.
        
               | duxup wrote:
               | > team and hiring dynamics. But that's not what these
               | tools advertise.
               | 
               | I think that's a given for any proposed standard. We all
               | get a common way we understand things and can even just
               | communicate about a thing.
        
               | tambourine_man wrote:
               | My argument is that it's not their selling point. When
               | you go to React's page you're not greeted with: "React is
               | a great way to hire devs and manage a team".
               | 
               | The solution they sell is technical, like state
               | management, reusable components, etc. Which I don't find
               | convincing.
        
             | pvg wrote:
             | FB's website has settings subpages that are more
             | complicated than an average web app and is an SPA-style-
             | mega-app made of piles of other apps. It typically keeps
             | highly consistent state throughout. There's no doing that
             | sanely by hand, you'll just forget something or, more
             | likely, it will get lost between the dozens upon dozens of
             | people needed to build such a thing.
        
               | tambourine_man wrote:
               | 1) Almost no one is building FB or Gmail, yet act like
               | it. The precise reason why still escapes me.
               | 
               | 2) For other use cases, it's not that hard to manually
               | update some elements in the DOM. You very quickly learn
               | how not shot yourself in the foot. Certainly a lot easier
               | (and faster) than dealing with the mess that is the React
               | ecosystem.
        
               | mardifoufs wrote:
               | You don't need to be building Facebook or Google to have
               | a TON of state in a webpage. Obviously if you are doing a
               | basic dashboard, a blog or something similar, it isn't
               | really needed. But for more complex stuff I think react
               | provides a much better way to handle state changes than
               | just using vanilla js. It's not like using react makes an
               | app more complex, because if you wanted to do the same
               | thing in vanillajs you'd end up with a much bigger mess.
               | 
               | I agree that some web pages don't need any of that, but
               | those don't usually require a lot of development anyways.
        
             | __david__ wrote:
             | Do you just use document.createElement(), getElementById(),
             | and friends? I've written lots of web apps that just used
             | those. But I've also jumped into React a couple times to
             | learn if it's better or faster or whatever. I generally
             | think it's a reasonable approach for a template style web
             | app--ie, when you need to build a whole lot of html nodes
             | that interact with each other in the way a complicated ui
             | does. But I do find I can get stuck trying to reason about
             | some of the weird reactivity stuff with useState() and
             | useEffect(). I kinda chalk that up to me being not an
             | expert, but it also feels like a bit of an impedance
             | mismatch with the language itself.
             | 
             | But I don't think React necessary for _every_ app and it
             | really depends on what kind of apps you are making.
             | 
             | Certainly you can do the original style of app where the
             | templating is on the server and any js is just to hook up
             | already existing nodes. The js community has more or less
             | moved away from that "rails" style of app years ago...
        
         | dclowd9901 wrote:
         | Decades is a long time. You must remember the complexities of
         | updating the DOM between browsers, surely.
         | 
         | Keeping the DOM in sync with a data state isn't too difficult
         | but doing so in a highly performant (60 fps) way _is_
         | tremendously difficult. Especially when it comes to creating
         | APIs that aren't leaky but also not too cumbersome.
         | 
         | It would frankly be easier to just paint pixels to a canvas
         | game-style, than translating changes to a living DOM tree.
        
           | tambourine_man wrote:
           | If you need 60fps you shouldn't use the DOM. It's not a game
           | engine. Like you said, go with canvas.
        
       | beders wrote:
       | I've been enjoying "signals" in the form of re-frame
       | subscriptions for many years now.
       | 
       | They solve a neat subset of problems in front-end developments.
       | But they don't solve all of them.
       | 
       | Adding it to JavaScript as language construct is unnecessary.
        
       | tommiegannert wrote:
       | Hmm, if we can optimize the reactive state management in all web
       | apps, that sounds cool.
       | 
       | If this is to be a base for VueJS, it should handle deep changes.
       | They have a note about support Map and Set, but being able to to
       | control depth is nice in VueJS. (I'd say watch() should be deep
       | by default, since non-deep is an optimization that can lead to
       | accidental inconsistent state.)
       | 
       | Streams. Generally, I find RxJS backwards. Usually you just need
       | "state", so that should be the easiest thing to implement. But I
       | can't deny that the programming model is beautiful. Standardizing
       | "state" without also considering streams seems odd to me. The
       | "computed" creates a pipeline of updates, very similar to one
       | you'd do with a map over a stream. If RxJS didn't already exist,
       | I probably wouldn't have cared about this duality.
       | 
       | Async. Sure, signals can be synchronous, but Computed should
       | definitely play well with async functions. This is a big
       | shortcoming in VueJS (that people work around on their own.) That
       | also implies handling "pending computation" gracefully for
       | debuggability. I see there's a "computing" state, but this would
       | have to be surfaced to be able to debug stuck promises.
       | 
       | Exceptions. I like the idea of .get() rethrowing exceptions from
       | Computed. VueJS is a bit vague on that front, and just stops.
        
         | nullvoxpopuli wrote:
         | > it should handle deep changes.
         | 
         | these can be implemented in userland via proxy -- and I think
         | probably should, as is proven by this collection of utils:
         | https://twitter.com/nullvoxpopuli/status/1772669749991739788
         | 
         | If we were to try implementing _everything_ as reactive
         | versions, there 'd be be no end, and implementations couldn't
         | keep up -- by pushing reactive Map/Set/etc to userland/library
         | land, we can implement what we need when we need it
         | incrementally, built on the solid foundation of the signal
         | primitives.
         | 
         | > since non-deep is an optimization that can lead to accidental
         | inconsistent state.
         | 
         | conversely, deep-all-the-time is a performance hit that we
         | don't want to be default. Svelte and Ember take this approach
         | of opt-in-deep reactivity.
        
       | _heimdall wrote:
       | I don't think signals will help move development away from
       | further complexity, and that's really what we need today.
       | 
       | There's a fundamental question of why modern sites/apps reach for
       | patterns like signals, memorization, hybrid rendering patterns,
       | etc. I wouldn't begin to claim I have all the answers, but
       | clearly there are gaps in the platform with regards to the
       | patterns people _want_ to implement and I 'm not sure that
       | jumping to signals as a standard helps better understand whether
       | its the platform or our mental models that need updating to get
       | back in sync.
       | 
       | Personally I've found code much easier to maintain when the
       | frontend is only responsible for state that truly is temporary
       | and doesn't live on the back end at all. For me any persisted
       | state belongs on the server, as does any rendering that depends
       | on it. This largely makes signals unnecessary, very few apps have
       | such complex temporary state that I need a complicated setup to
       | manage it.
        
       | itsjustme2 wrote:
       | Am I the only one that thinks the vanilla js example is actually
       | easier to read and work with?
       | 
       | - "The setup is noise and boilerplate heavy." Actually the
       | signals example looks just as noisy and boilerplate heavy to me.
       | And it introduces new boilerplate concepts which are hard for
       | beginners to understand.
       | 
       | - "If the counter changes but parity does not (e.g. counter goes
       | from 2 to 4), then we do unnecessary computation of the parity
       | and unnecessary rendering." - Sounds like they want premature
       | memoization.
       | 
       | - "What if another part of our UI just wants to render when the
       | counter updates?" Then I agree the strawman example is probably
       | not what you want. At that point you might want to handle the
       | state using signals, event handling, central state store (e.g.
       | redux-like tools), or some other method. I think this is also
       | what they meant by "The counter state is tightly coupled to the
       | rendering system."? Some of this document feels a little
       | repetitive.
       | 
       | - "What if another part of our UI is dependent on isEven or
       | parity alone?" Sure, you could change your entire approach
       | because of this if that's a really central part of your app, but
       | most often it's not. And "The render function, which is only
       | dependent on parity must instead "know" that it actually needs to
       | subscribe to counter." is often not an unreasonable obligation. I
       | mean, that's one of the nice things about pure computed
       | functions- it's easy to spot their inputs.
        
         | duxup wrote:
         | I agree the initial example is easier to read, but it has
         | problems as stated.
        
         | leononame wrote:
         | Why do you think this is premature memoization? This is an
         | example, boiled down to a simple function. Do you think people
         | just came up with the use case for this without ever having
         | needed it?
         | 
         | I think an effort in standardizing signals, a concept that is
         | increasingly used in UI development is a laudable effort. I
         | don't want to get into the nitty gritty about what is too much
         | boilerplate and whether you should build an event system or
         | not, but since signals are something that is used in a variety
         | of frameworks, there might be a good reason to it? And why not
         | make an effort and standardize them over time?
        
           | 38 wrote:
           | > I don't want to get into the nitty gritty about what is too
           | much boilerplate and whether you should build an event system
           | or not
           | 
           | You're basically saying you want this thing, but you don't
           | want to have to justify it
        
         | briantakita wrote:
         | Since reactivity is not baked into Javascript. Adding
         | reactivity is going to add abstraction overhead. It's meant to
         | be used if it's needed. Not necessarily a default way to work
         | with state.
         | 
         | In my experience, the big benefit is the ability to make
         | reactive state modular. In an imperative style, additional
         | state is needed to track changes. Modularity is achieved using
         | abstraction. Only use when needed.
         | 
         | > Sounds like they want premature memoization
         | 
         | It's a balance to present a simple example that is applicable.
         | Cases where reactivity have a clear benefit tend to be more
         | complex examples. Which is more difficult to demonstrate than a
         | simple, less applicable example.
        
         | LittleDan wrote:
         | I think there is room for improvement in how we explain this.
         | The problems aren't really visible in this small sample and
         | comes up more for bigger things. PRs welcome.
        
           | briantakita wrote:
           | Perhaps mentioning the tradeoffs between a simple easy to
           | explain example vs a more obvious comprehensive example. With
           | links to more complex code bases? With a before & after?
        
         | ksherlock wrote:
         | I agree. But look at Preact's signal documentation -
         | 
         | https://preactjs.com/guide/v10/signals
         | 
         | "In Preact, when a signal is passed down through a tree as
         | props or context, we're only passing around references to the
         | signal. The signal can be updated without re-rendering any
         | components, since components see the signal and not its value.
         | This lets us skip all of the expensive rendering work and jump
         | immediately to any components in the tree that actually access
         | the signal's .value property."
         | 
         | "Signals have a second important characteristic, which is that
         | they track when their value is accessed and when it is updated.
         | In Preact, accessing a signal's .value property from within a
         | component automatically re-renders the component when that
         | signal's value changes."
         | 
         | I think it makes a lot more sense in a context like that.
        
           | andrewstuart wrote:
           | >> In Preact, when a signal is passed down through a tree as
           | props or context,
           | 
           | I have found that passing props makes React-like applications
           | very complex and messy and props are to be avoided as must as
           | practical.
           | 
           | The mechanism for avoiding props is Custom events.
           | 
           | It concerns me to see the concept of signals being passed as
           | props when surely signals/events should be removing the need
           | for props?
        
       | vbezhenar wrote:
       | I didn't understand the example in the linked README.
       | // A library or framework defines effects based on other Signal
       | primitives       declare function effect(cb: () => void): (() =>
       | void);
       | 
       | What library? What framework? I lost here. What's effect?
       | effect(() => element.innerText = parity.get());
       | 
       | How does effect knows that it needs to call this lambda whenever
       | parity gets changed? Will it call this lambda on any signal
       | change? Why this talk about caching then? Probably not.
       | 
       | Anyway I think that signal idea is sound, if I understood
       | correctly what the authors tried to convey. My main issue with
       | those decoupling architectures is that once your application is
       | complex enough, you will get lost trying to figure out why this
       | particular event being emitting. Ideally signals should fix this
       | by modifying stacktrace, so when my callback is being called,
       | it'd already contain a stacktrace of the code which triggered
       | that signal in the first place.
        
         | troupo wrote:
         | 1. effect is any function you want to invoke
         | 
         | 2. with signals the dependency tracking mechanism knows what
         | values need to be recalculated and as a result the system knows
         | which functions to call again
        
         | throwitaway1123 wrote:
         | > What library? What framework? I lost here. What's effect?
         | 
         | There are various libraries that export a function called
         | effect which allows you to run arbitrary code in response to a
         | signal update. The Preact docs have a great primer on signals
         | and effects: https://preactjs.com/guide/v10/signals#effectfn
         | 
         | As I understand it, these effect functions run the callback
         | once initially to see which signals were accessed while the
         | callback was executing, and then call the callback again
         | whenever the signals it depends on update. As long as signal
         | access is synchronous and single-threaded, you know that if a
         | signal was accessed during the callback's execution that the
         | callback should be subscribed to those signals.
         | 
         | > How does effect knows that it needs to call this lambda
         | whenever parity gets changed? Will it call this lambda on any
         | signal change?
         | 
         | You can do this with getters [1], where the effect function
         | tracks which properties of the signal were accessed in a getter
         | method (I believe Vue historically did this in version 2), but
         | you can also track object access using proxies [2]. The example
         | from the proposal simply has a 'get' method that is called to
         | access the value of the signal, and executing this method
         | allows dependencies to be tracked.
         | 
         | [1] https://developer.mozilla.org/en-
         | US/docs/Web/JavaScript/Refe...
         | 
         | [2] https://developer.mozilla.org/en-
         | US/docs/Web/JavaScript/Refe...
        
         | pyrolistical wrote:
         | I suspect the watcher is needed by the implementation of effect
        
         | mondrian wrote:
         | > How does effect knows that it needs to call this lambda
         | whenever parity gets changed?
         | 
         | The call `parity.get()` will register a dependency on the
         | function that is passed to `effect()`. When `parity` is
         | updated, the function is called.
         | 
         | > Will it call this lambda on any signal change?
         | 
         | Only when a dependent signal changes.
         | 
         | In this case, `parity` depends on `isEven` and `isEven` depends
         | on `counter`. So when `counter` is updated, that whole
         | dependency chain is invalidated leading to `parity` getting
         | invalidated, and that callback re-running.
        
           | posix86 wrote:
           | This works well until you accidentally have an if/else
           | branch, then you get hard to track bugs (halting problem in
           | the general case).
           | 
           | I'm guessing this is why they don't propose to add this
           | function to the standard: That fact makes it not very pretty.
        
             | mondrian wrote:
             | Hmm, can you explain how if/else branches cause hard to
             | track bugs?
        
             | __s wrote:
             | if/else isn't a problem. If the condition isn't dependent
             | then update of unused branch doesn't matter
        
       | jupp0r wrote:
       | This is a horrible idea. Instead of building some dependency
       | tracking into this niche feature of the language, JS should come
       | up with a generic way of enabling framework developers to clean
       | up resources without putting the burden on users of their API to
       | manually do this.
        
       | henriquez wrote:
       | "Lets make my random UI state tracking framework part of the
       | JavaScript spec"
        
       | ttfkam wrote:
       | Looks like Svelte 5 only somehow worse?
        
         | bastawhiz wrote:
         | The proposal is very clear that it's not trying to be pretty,
         | it's trying to be sensible and correct so that frameworks like
         | Svelte can build on top of them and work interoperably with
         | other libraries and frameworks.
        
       | artemonster wrote:
       | Easier to port react to vhdl or verilog?
        
       | meindnoch wrote:
       | "let's bake my current framework du jour into the standard
       | library!"
       | 
       | It's a bit like tattooing your girlfriend's name onto yourself.
        
       | nikeee wrote:
       | Back in the days there was an effort to put observables in the
       | language because they were popular (and rxjs was, too).
       | 
       | Glad that didn't happen. And I think everybody else is, too.
       | Maybe we should keep that in mind when standardizing features of
       | frameworks.
        
       | junon wrote:
       | Related is S.js: https://github.com/adamhaile/s
       | 
       | I love signals. I prefer them when making UIs over any other
       | primitive (besides, perhaps, the cassowary constraint algorithm).
       | I try to replicate them in every language I use, just for fun.
       | 
       | I also don't believe they belong in the Javascript language
       | whatsoever. Let the language be for a while, people already
       | struggle to keep up with it. TC-39 is already scaring away people
       | from the language.
        
       | da39a3ee wrote:
       | This article is missing a "What are signals" section. And yes,
       | this does not do the job:
       | 
       | > Within JS frameworks and libraries, there has been a large
       | amount of experimentation across different ways to represent this
       | binding, and experience has shown the power of one-way data flow
       | in conjunction with a first-class data type representing a cell
       | of state or computation derived from other data, now often called
       | "Signals".
        
       | readline_prompt wrote:
       | Curious, what about using Proxies for handling state?
        
       | CanaryLayout wrote:
       | Oh God why.
        
       ___________________________________________________________________
       (page generated 2024-03-31 23:00 UTC)