proposal-signals icon indicating copy to clipboard operation
proposal-signals copied to clipboard

Can we use accessor instead of get/set methods?

Open d8corp opened this issue 1 year ago • 7 comments

I think it looks better. Also you can use JS features like:

counter.value++
counter.value += 2

I changed the example from readme.

const counter = new Signal.State(0);
const isEven = new Signal.Computed(() => (counter.value & 1) == 0);
const parity = new Signal.Computed(() => isEven.value ? "even" : "odd");

// A library or framework defines effects based on other Signal primitives
declare function effect(cb: () => void): (() => void);

effect(() => element.innerText = parity.value);

// Simulate external updates to counter...
setInterval(() => counter.value++, 1000);

You can check my lib watch-state it's so similar. Maybe you can take some from there.

d8corp avatar Apr 07 '24 16:04 d8corp

Signals are designed to enable subclassing to support a .value API. We can consider organizing the signal API to encourage common ergonomics, which could be via this accessor being built-in rather than subclassed on, but that is beyond the initial goals of the proposal.

littledan avatar Apr 07 '24 16:04 littledan

I have a more radical idea:

variable delegated syntax

Add delegated-properties from kotlin for best development experience.

let counter by new Signal.State(0);
const isEven by new Signal.Computed(() => (counter & 1) == 0);
const parity by new Signal.Computed(() => isEven ? "even" : "odd");

// A library or framework defines effects based on other Signal primitives
declare function effect(cb: () => void): (() => void);

effect(() => element.innerText = parity);

// Simulate external updates to counter...
setInterval(() => counter = (counter + 1), 1000);

Since this is a tc39 proposal, it is possible to add additional base syntax for this. kotlin confirms that this syntax is fully working, and it has been applied in Jetpack Compose

xcfox avatar Apr 13 '24 04:04 xcfox

We discussed syntax in the beginning. Folks are interested in that possibility. However, I think we'd like to reserve that for a follow-on proposal, so we don't cause the core signals effort to fail or be significantly delayed based on that. We can easily layer syntax on top of a library capability, once the details are worked out, similarly to how async/await was layered on top of promises.

Of note, when we were designing decorators, we envisioned that they would be usable not only on classes but eventually on functions, objects, and maybe variables. So, I think working on a follow-on proposal for decorators to add more target types could run in parallel to signals and once standardized would provide the syntax not only for signal variables but for all sorts of other things as well.

Here's what a theoretical signal variable decorator would look like:

export function signal(target) {
  const { get } = target;

  return {
    get() {
      return get.call(this).get();
    },

    set(value) {
      get.call(this).set(value);
    },
    
    init(value) {
      return new Signal.State(value);
    },
  };
}

And here's how it could be used:

let @signal counter = 0;

EisenbergEffect avatar Apr 13 '24 14:04 EisenbergEffect

This is very cool, but as it's confusing/incompatible to TypeScript Decorators, it would be great to have another example for TypeScript! (without accessor #)

Phoscur avatar Apr 28 '24 10:04 Phoscur

Let’s keep this thread focused on the question of switching to the .value API (though I am also interested in variable decorators and hope we can go further in developing them).

it seems really possible to me that we could switch this proposal to use the .value accessor instead of get/set methods. I don’t see a ton of downsides (apologies for my dismissive response above).

The main thing I would want to check is whether accessors are slower than methods in current JS interpreters/baseline compilers, and if they are slower, whether this can be addressed. I wouldn’t want to choose an API shape which led to unavoidable suboptimal performance in practice.

littledan avatar Apr 29 '24 00:04 littledan