Hacker News new | ask | show | jobs
by tkzed49 81 days ago
you continue to contradict yourself by introducing concepts and saying they are not concepts.

I get what you're trying to say, that React hooks have special semantics, and that your abstraction feels more "native".

again, not sure how this is more "native" than Solid signals, just as an example.

1 comments

You are bringing up an important topic. The way I see it is that Gea's Store is a plain old JS class. It's just a native class. There really is no special syntax you need to pay attention to. Whereas Solid signals require you to follow a specific syntax and approach, and has its own gotchas. Like, the language doesn't have a createSignal method by default, and you don't "execute" what look like values in JS as you need to do in Solid, and although I'm looking forward to the official Signal API, Solid isn't following that either.

That's basically how Gea is more native, because stores are plain classes. I hope this clarifies my point a little bit more.

    It's just a native class. There really is no special syntax you need to pay attention to.
Don't confuse syntax with code. Solid has no special syntax (other than JSX of course).

This isn't comparing apples to apples.

Solid has a Store primitive too, and it's a "plain old" proxied object.

How is `createStore` less native than `new Store()`? The `new` keyword didn't even exist in JS until 2015, and the underlying semantics (prototypical inheritance) never changed.

One of Solid's design goals is fine-grained reactivity for very high performance. That's why signals are getter functions, because calling them alerts the system to the precise "scope" that will need to be re-run when the value changes.

Since signals are functions, they can be composed easily, and passed around as values.

I'm not following—the `new` keyword has been with us since JavaScript's inception. You might be confusing it with the `class` syntax, but before that we could always `new` functions.

And yes, Solid has signals that require you to know how to write and work with them. I answered another comment on the thread about Solid stores—they also introduce a couple of gotchas and weird syntax. You just can't do `this.users.push(...)` or `this.users[2].loggedIn = true` in Solid stores.

Therefore `createStore` is less native than `new Store()`, because `new Store()` just gives you a plain (proxied) object you can manipulate in various ways and reactivity will persist thanks to the compiler.

And Gea's design goal is also fine-grained reactivity, which it delivers without getter functions in the code that the developer writes, but rather, the handlers are generated via the compiler.

What is the difference between mobx or solid stores or any of the reactive frameworks that do reactivity on proxy objects?
Solid stores are a great improvement over raw signals, but they still come with their own gotchas. First off, it's an entirely new syntax. You need to learn its documentation. You always have to use setStore, and it has a weird syntax like `setStore("users", 2, "loggedIn", false)` and even pushing items to an array is weird. In Gea it's just regular JavaScript: `this.users[2].loggedIn = false` or `this.users.push(...)`. MobX also comes with its own syntax.

In the end Gea is basically as simple as a plain old JavaScript class, made reactive by its compiler.

> You always have to use setStore

This is a design choice, and explained in their docs:

    Separating the read and write capabilities of a store provides a valuable
    debugging advantage.

    This separation facilitates the tracking and control of the components that
    are accessing or changing the values.

> You need to learn its documentation. You always have to use setStore, and it has a weird syntax like `setStore("users", 2, "loggedIn", false)` and even pushing items to an array is weird.

It's optional, and incidentally quite expressive and powerful. But they also support mutable drafts out of the box.

    import { produce } from 'solid';

    setStore(produce(state => {
      state.users[2]?.loggedIn = false; 
    }))
I understand this bit. The bit that I don't understand is how you compare the two invented concepts like `setStore` and `produce` to just `state.users[2]?.loggedIn = false`. To me it's very clear Gea's syntax requires you to write less code, while also requiring you to know less concepts.
The value judgement implied in "invented concepts" is kind of weird, and maybe gets at a core difference in how you and I think about this.

Frameworks have APIs; they define concepts. Learning concepts isn't a bad thing in and of itself. Especially if they are concepts which let you model your application more succinctly and efficiently.

What you mean is that you are leaving it to the user to learn (or conceive of) additional concepts which are external to Gea to in order to build non-trivial reactive applications.

But "Gea requires you to write less code / know fewer concepts" can be reframed as "Gea opts out of solving some types of vanilla JS boilerplate for you". When you don't give your users "concepts", they're still going to end up writing a lot of code and learning concepts, just not within your API.

Thank you for the discussion, I find it very interesting and I'd love to understand how you think. Why do you think setStore and produce let you model your application more succinctly and efficiently than just a direct assignment?

And what kind of types of boilerplate do you see Gea is opting out of?