4 ms·
Very interesting, thanks. I don't understand the point of the "reactive" cell order, instead of conventionally doing top to bottom. It seems like it goes again
by benhurmarcel 6y ago
Very interesting, thanks.
I don't understand the point of the "reactive" cell order, instead of conventionally doing top to bottom. It seems like it goes against the idea of "the program state being completely described by the code you see".
- ddragon 6y agoEven if you do it completely top down, it doesn't mean all cells need to update if you change something on the top, so you'll still profit from the dependency graph. And notebooks are mostly for exploration, and you don't really have a fixed order. You start getting the data, then you run the model, then you go back and change the data in the import... The order of your internal logic (or how you want to explain it to others) isn't necessarily linear, and of course you can just go back and write like a normal program but you lose the chain of changes that led you to the result (in this case the compromise is that your chain is restricted, like you said you can't define the same thing twice, but in exchange the notebook will provide with you the program order for free).
- vanderZwan 6y agoSo in the context of these notebooks it is actually quite useful to not depend on cell order, because the idea is that notebooks aren't simply programs or scripts, they are (potentially interactive) documents. You can write an article that presents the results of your script, with cells that contain text, interactive widgets and plots at the top, and put the code and data that generates these plots in "appendix" cells below that. Observable, a "JavaScript ancestor" of Pluto.js, has plenty examples of these: https://observablehq.com https://observablehq.com Also, I guess that you haven't used notebook environments like Jupyter before, so a bit of historical context might help. In Jupyter, cells aren't necessarily executed top-to-bottom, they are executed when the user asks it too. The result is then stored in the global state (well, assuming there is a global variable that the data is assigned to). This means that cells that depend on other cells also depend on the order in which those cells were executed. Worse still, if you write your notebook in a sloppy manner, you can end up with a state that you cannot reproduce from the still-remaining code (for example, you can have variables A and B, B is generated from the result of A, then you remove A. Because Jupyter is not reactive this does not update B, so your notebook keeps working just fine... until you decide to edit B). So previously, notebook-like environments made it really easy to introduce bugs like this. With reactive cells you don't have to think of state. It's kind of like pure functional programming: it removes global side-effects. And note how on a technical level, making cells execute top-to-bottom is really just very a simple way to enforce that cells must executed in order of dependency! So either option insists that this global-state-that-does-not-respect-dependencies is a big problem that should be avoided, they just present different solutions for the problem.
- benhurmarcel 6y agoThanks a lot for the write-up.
- uoaei 6y agoReactive notebooks are closer to the idea you mention than other kinds of notebooks, because global state is reflected in the outputs of each cell. The biggest source of bugs when working in Jupyter for instance is that a variable was re-defined somewhere and it's not easy to see that it is changed when you have a cell somewhere above that has the output `foo = x` when the global state claims that foo = y.
- TeMPOraL 6y agoIn reactive notebooks, the program state is still being completely described by the code you see - it's just that it doesn't have to be in top-down order! Instead of forcing you to manually define everything before use, a reactive notebook just looks at the references you make, forms a dependency graph, and then evaluates it in topological order (and, as optimization, only re-evaluates things that depend on the thing you've just changed). This leads to a much nicer code organization, particularly when you're writing something resembling an interactive document (e.g. an "explorable explanation"). Much of the documents I do on ObservableHQ has roughly the following structure: Title Prose Visualization Interactive UI elements (possibly mixed with further visualizations) ------------------------------ All the actual source code powering the implementation, organized in readability order.