tc39 / proposal-signals

A proposal to add signals to JavaScript.
MIT License
2.95k stars 54 forks source link

Should it be Signal.Derived rather than Signal.Computed? #20

Open trueadm opened 7 months ago

trueadm commented 7 months ago

This is name bike-shedding but I thought it would be worth bringing up.

I ask this as technically effects are computed signals too. It made sense to use Signal.Computed when we coupled both concepts onto the same class, but given we're breaking them out and they have different heuristics around what can be written and read from, it also makes sense to tailor there naming IMO. Pure derived state has its foundations in many reactive papers and prior work so I feel it lends itself nicely here.

littledan commented 7 months ago

I proposed the name Signal.Computed because computed() seems to be the extremely rough consensus of a name among frameworks that support signals. It didn't really have to do with effects. In general, the idea was to be uncreative here and just go with the existing branding that the community uses. "Derived" makes sense to me, just as much as "Computed" does.

If people like the idea of using rough ecosystem consensus to decide on names, maybe we should try to do a more thorough job of it. Would anyone be interested in doing a survey of the currently used names, both in JS frameworks, reactive papers, and other prior work? We could collect results in a table. There are lots of names to compare, not just this one (especially "signal", "state", "computed", "effect").

benlesh commented 7 months ago

Computed makes the most sense to me. I've seen that idiom for years now in various systems that have signal-like things. This is, of course, anecdotal.

mweststrate commented 6 months ago

Idem. I think Computed will be slightly easier for non-native speakers. Although it is terrible for keyboard autocorrection.

NullVoxPopuli commented 6 months ago

For the pool of options / consideration, Starbeam uses the term Formula, because Computed carries a ton of existing baggage with existing assumptions about how it should work, be configured, etc. Formula is a bit more mathy, but also leans more in to the idea that the value that comes out of it is "derived"

benlesh commented 5 months ago

Computed carries a ton of existing baggage

@NullVoxPopuli Starbeam is Ember adjacent or derived? You're referencing Ember's "computed"? Just gathering context.

NullVoxPopuli commented 5 months ago

You're referencing Ember's "computed"?

yeah -- maybe some extra context/history is needed? -- the whole concept (at least in my circles) just leaves a lot of sour tastes in folks mouths as it was from a time pre-classes and pre "signal"-like behavior, it look like this, which resembles some of React's effects a bit (tho, synchronous, instead of an actual effect):

theProperty: computed('list', 'o', 'stuff', function() {
  return [this.list, this.o, this.stuff];
});

Now it could be that Ember is a small enough community, and most folks who even know about ember's computed are working in large enterprise apps that really struggle with keeping up with things (we're talking 6+ years behind at this point), or used ember 6+ years ago and left the community due to how rough computed and such were (especially since React at the time was really nice by comparison (pre-hooks, but even post-hooks is way better than ember-computed)). (The fancy new framework where you've only seen evergreen projects is always going to be more desirable than a legacy one that hasn't kept up with its own ecosystem)

in Ember, modern code would look like much like it would everywhere else using "signals":

get theProperty() {
  return [this.list, this.o, this.stuff];
}

provided that those 3 properties {list, of, dependencies}, were marked as "tracked".

The system that provides "signals" for ember today is "Glimmer" (in particular @glimmer/tracking)

Starbeam is Ember adjacent or derived?

It's an adjacent project that ember isn't consuming (yet), but currently has integrations with React, Preact, and Vue, with a prototype implementation in Svelte, iirc (somewhere)

It's a reimagining of the reactivity system while solving for some limitations of Glimmer But more imporantly, it's aiming to be universal reactivity, for all frameworks to not just use the same primitives and say "we're using X", but to share the exact same abstractions across frameworks and have them work the exact same with the same timing, invalidation, behavior, etc (tho, using each ecosystem's preferred method of interacting with various concepts). (more on that here: https://www.starbeamjs.com/guides/universal-reactivity.html and https://newdocs-rho.vercel.app/docs/universal/fundamentals/rendering.html)

More detailed information is here: https://newdocs-rho.vercel.app/docs/universal/guiding-principle.html

Starbeam is still very much "pre 1.0" at this point, btw.

But back to Signal.Derived vs Siganl.Comptued, this is the info I'm referring to:

I'd like also recommend aganist "derived", because technically getters and regular functions derive data as well, for example:

benlesh commented 5 months ago

Honestly, if people need to understand how the internals work, we've probably failed no matter what the name of it is. I think Computed is the current well-known conceptual name for computed signals.

(Also, I was a heavy user of Ember back in those days, and I don't think I really dug into how computed worked, because it always worked for my use cases)

littledan commented 5 months ago

Let's conclude on "computed" here, given the lack of support from others for "derived".

NullVoxPopuli commented 5 months ago

For context, copying a message from the Discord:

if people need to understand how the internals work

Well, like, from a framework perspective, when do you let the results of an effect finally render? That won't be the same across frameworks with spec-signals That's mostly what I was trying to get at with starbeam's purpose.

Nothing to do with "internals" <3

benlesh commented 4 months ago

Ugh. I hate myself for even saying this... but I worry that Computed gives people the feeling that this is a lightweight mechanism for doing things like adding two numbers. Where, it's plainly not as "light" as just adding the numbers. There are nuanced use cases, obviously. I feel that Memo probably more accurately describes what this is doing and that it has some overhead implications in the name that people understand in the general sense.

In any case, people will learn over time, I guess.

joakim commented 1 month ago

I'm one of those weird people who spend way too much time on etymology.

I think it's important that the word describes the semantics it represents precisely.

derive | dɪˈrʌɪv | obtain something from (a specified source)
From late Middle English (in the sense ‘draw a fluid through or into a channel’): from Old French deriver or Latin derivare, from de- ‘down, away’ + rivus ‘brook, stream’.

Literally "downstream", or "obtain from downstream". Note the allusion to fluids (dataflow).

compute | kəmˈpjuːt | reckon or calculate (a figure or amount)
From French computer or Latin computare, from com- ‘together’ + putare ‘to settle (an account)’.

Much more general. Happens all the time in code.

memo | ˈmɛməʊ | a written message within a business or organization
Abbreviation of memorandum: from Latin, literally ‘something to be brought to mind’, gerundive of memorare. The original use was as an adjective, placed at the head of a note of a record made for future reference.

Or in this case, memoization, a technique for optimizing functions. Also more general.

So I do prefer derive, although it too is used more generally (in its mathematical sense), as NullVoxPopuli said.

littledan commented 1 month ago

Let the debate recommence!

dakom commented 1 month ago

On the topic of naming things, is Computed not often considered State? I find it a bit clearer to name it for what it is as opposed to how it's used..

For example the Streams API has ReadableStream and WriteableStream. I think Computed (or Derived) similarly makes sense, it's describing what it is (I don't have a strong opinion between those)

But Signal.State doesn't quite feel right to me. I could easily see myself wanting to do this often:

const state = new Computed(() => ...);

How about one of these alternatives?

joakim commented 1 month ago

This proposal is a tough one, it involves both cache invalidation and naming things.

I agree, the word "state" equally applies to Computed.

First thoughts > I think `Mutable` is a good alternative to `State`. Sure, `Computed` does change, but only by reaction to upstream changes. It's not directly mutable like `State` is, it lacks a `set` method. > > **mutable** able or likely to change From Latin **_mutabilis_**, from **_mutare_** ‘to change’. > > - `Signal.Mutable` > - `Signal.Derived`

On second thought, the word "mutable" also applies to both, although indirectly for Computed.

On a general note, while naming things can seem like bikeshedding, I think it deserves proper attention. Names are part of the interface, and a good interface should be intuitive and clear.