react

"mulling over state management stuff"
lilactown 2020-06-13T16:38:11.346900Z

alright, here’s been my big WIP for the last month or so: https://github.com/Lokeh/serenity still WIP but is actually pretty close to being release worthy IMO

1👀
lilactown 2020-06-13T16:39:42.348500Z

TL;DR it’s like reagent’s ratom/reaction lib, but a little more disciplined and setup to one day interop with a Concurrent Mode-like scheduler

Aron 2020-06-13T16:41:19.349300Z

what do you think of resuming being disabled in react? For me this feature was the biggest pull to it, without this, I am not sure async rendering is really worth it even.

Aron 2020-06-13T16:41:27.349600Z

i mean concurrent mode by async rendering

lilactown 2020-06-13T16:57:12.350300Z

I haven’t looked at the latest stuff w.r.t. async rendering pausing/resuming in React

lilactown 2020-06-13T16:57:35.350900Z

have they nixed it from their roadmap? or just disabled it while they fix it

dominicm 2020-06-13T17:12:42.352600Z

This is fantastic, I like it. I was expecting to have an immediate desire to shift the api, but it matches really nicely with how something like this should look. I'll have to dig in to how this works with react and local state, but this is exciting!

1😎
dominicm 2020-06-13T17:14:03.353700Z

Is a sink just an action in reaction to a source changing? Any reason to not support add-watch instead of a specific api?

lilactown 2020-06-13T17:17:54.354700Z

that means a lot, thanks for the glowing feedback ☺️

lilactown 2020-06-13T17:18:30.355700Z

yes, a sink is an object that represents an action in response to a source or signal changing

dominicm 2020-06-13T17:19:37.356600Z

It's not actually an action itself then. So it matches the semantics of watch?

dominicm 2020-06-13T17:19:50.357100Z

One upside is the lack of names, but one can solve that other ways.

lilactown 2020-06-13T17:20:51.357900Z

yes, it might be just aesthetics

lilactown 2020-06-13T17:21:33.359700Z

I’ve based a lot of the underlying mechanics of the library on an OCaml library called Incremental, which has separate “observers” that are distinct from computations

lilactown 2020-06-13T17:21:52.360600Z

observers just watch a computation and fire an on-change handler, like sinks

dominicm 2020-06-13T17:22:49.362800Z

While I like your aesthetics, I think it's better to learn less things and copy the language's existing pieces.

lilactown 2020-06-13T17:22:52.362900Z

one benefit (I think) is that this simplifies garbage collection and cutting off computation of nodes

dominicm 2020-06-13T17:23:20.363400Z

I'm lazy, less things to learn :)

lilactown 2020-06-13T17:25:17.364300Z

like imagine if/when an API to hook into the GC for v8/etc. is implemented

lilactown 2020-06-13T17:26:32.365900Z

once a sink goes out of scope and GCd, it can then automatically dispose itself and all connected signals

lilactown 2020-06-13T17:27:00.366500Z

harder to do that with signals because they potentially have many different connections

lilactown 2020-06-13T17:27:34.367500Z

but maybe it doesn’t really matter and it would work with add-watch too, it’s all just theory

lilactown 2020-06-13T17:28:35.368100Z

the other nice think about sinks is that they are always a leaf in the fully connected graph

lilactown 2020-06-13T17:29:53.369500Z

so imagine you had a utility that drew a graph of all the nodes that were connected to the thing that is causing your component to re-render

lilactown 2020-06-13T17:30:33.370900Z

since you have a sink, you can hand it to that utility and be guaranteed to only see the part of the graph that your component depends on

lilactown 2020-06-13T17:31:20.372300Z

actually, that would probably work with signals too since I separate edges to the node and edges from the node...

dominicm 2020-06-13T17:31:25.372500Z

You could do that watch key as well, the distinction is reification through key or reification through var.

lilactown 2020-06-13T17:33:11.373900Z

yeah, i guess it feels a little weird to have add-watch / remove-watch be side-effecting, in that adding or removing watches may cause a signal to come alive or go dormant

orestis 2020-06-13T17:33:50.374500Z

Minor typo at the require in the README [serentiy.core :as s]

lilactown 2020-06-13T17:34:11.375Z

and having specific nodes that are only for side-effects pleases my pure FP architecture astronaut sensibilities

lilactown 2020-06-13T17:34:21.375300Z

but you are convincing me :P

lilactown 2020-06-13T17:34:31.375500Z

oo thx!

dominicm 2020-06-13T17:35:43.376200Z

The lack of remove might be a relevant thing that I've overlooked.

dominicm 2020-06-13T17:36:13.376900Z

But I find it strange that it doesn't have a remove now...

lilactown 2020-06-13T17:36:29.377800Z

there’s a dispose! function which is essentially remove

lilactown 2020-06-13T17:36:40.378400Z

it’s just not in the README. the example is not exhaustive

dominicm 2020-06-13T17:36:44.378600Z

Without looking at the docs, I'd know how to remove it if it was remove-watch 😛

dominicm 2020-06-13T18:06:28.379600Z

@lilactown do you envision this being used in a let or in a global? Thinking wrt to react

lilactown 2020-06-13T18:14:36.379900Z

:thinking_face: is both an acceptable answer?

1👍
lilactown 2020-06-13T18:16:04.380700Z

it's not like recoil, which needs global unique identifiers

lilactown 2020-06-13T18:17:54.382200Z

the primary use case I would expect w.r.t. React is to have serenity sources for things like remote data caching; state that you need to live completely outside of the component tree

lilactown 2020-06-13T18:23:12.385400Z

so you might have some sources/signals/sinks that are defed at the global level, but then inside of components you could use a hook like:

(def dbA (s/source ,,,))

(def dbB (s/source ,,,))

(defnc my-component []
  (let [data (use-signal #(merge @dbA @dbB)) ;; dynamically creates a new signal and subscribes to it
        ,,,]))

dominicm 2020-06-13T18:49:09.386100Z

Both is the best answer. It indicates your thing is simple.

lilactown 2020-06-13T18:52:52.386400Z

yeah it's very much in the same vein as reagent in how dynamic it is

Aron 2020-06-13T19:46:02.386600Z

I believe it's only temporary, but the point is that it was enabled and react was very performant, but now, although it still can (probably, haven't checked) suspend long renders, it can't resume, needs to start over from scratch, throw away intermediary steps. What's the point of fiber then?

lilactown 2020-06-13T19:47:14.386800Z

yeah it sounds like they're working out the kinks!

Aron 2020-06-13T20:44:09.387Z

I have a different sentiment about this. They are having trouble finishing suspend because it's a bad idea and every demo assumes too much knowledge ahead of time, something that React usually avoided so far (small surface API). So suspend works (afaik) like this, but not with resuming, and for branding purposes they are committed with suspend, that's why performance is not an issue. But it is an issue if you want to use react for not-a-website.

lilactown 2020-06-13T20:48:16.387200Z

that's a pretty pessimistic way of looking at it 😛

Aron 2020-06-13T21:55:55.387400Z

could be, but pessimistic doesn't necessarily mean inaccurate 😉

Aron 2020-06-13T21:56:13.387600Z

I want to make that sierpinski triangle demo work, with or without react