Closed jbednar closed 9 months ago
I fixed linting and added a note in the reactive guide about the API being experimental, since Jim added that note too in the release notes. And it makes sense to me marking it experimental for a little while.
looking it over now
Since https://github.com/holoviz/param/pull/859 has been merged and fixed the ipython module being automatically imported when Param is imported, import param.ipython
must be removed and the explanation about param.ipython
must be adapted a little.
Answering to @jbednar in the main thread about:
I am not sure what you mean about the notebook being required, though; it's required only for the display to update dynamically, not the value.
I meant that the pipeline of a reactive expression isn't executed automatically when the value
of the root is updated. It is only executed if you require the value
on the resulting expression, or if a framework has registered a reactive display hook, like Param does automatically on import when in an IPython context.
The way I would say that is that whenever the value is accessed, it is always up to date, which seems like all you can ask of a reactive framework. It's lazy, yes, but reactive. So in e.g. a REST API, computed values will always be up to date when requested, without needing any special support in the event loop. All this should be explained, but I don't think it's misleading to show how it behaves in ipython since that's how it would behave for anything querying its value.
The way I would say that is that whenever the value is accessed, it is always up to date, which seems like all you can ask of a reactive framework. It's lazy, yes, but reactive.
I don't how other reactive frameworks operate, maybe that's how they all work, but trying to be in the position of a newcomer it seems to me that the combination of "lazy" + "reactive" is a bit strange. Why is it lazy by default, is it a design decision or is it the only way it can be?
We should indeed explain the way it works. Taking your REST example, if I build a reactive expression that returns the number of users in a group (group being the input), the result is going to depend on when the query is made. I.e. If I set group.rx.value
and the result is computed only later when I access nusers.rx.value
or immediately, the number returned can be different.
Generally as a developer I would like to know when the code is executed and how as that's useful for debugging purposes. Questions like the following ones will be asked sooner than later. When is a reactive expression lazy and when is it non-lazy (e.g. watching the reactive expression with .rx.watch(cb)
makes it non-lazy)? Are all intermediate values cached? When a reactive expression has multiple inputs and only one of them is updated, is the whole graph re-executed or just the part that is affected by the updated input?
While it could be improved, the guide is already in a pretty good shape! Thanks all for contributing.
Reactive_Expressions.ipynb previously had three sections depending on these concepts:
rx()
and.value
Parameterized
,Parameter
,bind
.rx
,Parameterized.param.X.rx()
,.value
,rx()
,.rx.*
The first section depends only on two constructs:
rx()
and.rx.value
, which seems nice and clean as an introduction. After that, though, immediately it dived into Parameters and intoparam.bind
, both of which I consider optional for understanding and using reactive expressions. Instead, I've reorganized it into this outline to introduce concepts only as they are needed, to minimize how much people need to learn before they can start writing code:rx()
and.rx.value
(complete basics, i.e. "what it is" and "that it works")Ideally there would also be a section 7 with a technical deep dive, but that's not something I propose to write now, and too much for this single nb.
Hopefully this is an improvement!
We don't necessarily need to address anything about widgets (ipy or Panel) in this release, but we should also keep in mind where those would be introduced, and maybe call them out more than I have so far.
We also may want to split the
bind
stuff into its own page alongside this one; it makes sense on its own and is a simpler story than reactive expressions in some ways, so it would probably be good to make it consumable without having to read about reactive expressions. But I've kept in here for now just because I don't have time to move it out, which I think someone should do but maybe isn't urgent.