diff --git a/docs/blocks.py b/docs/blocks.py index 4b684012f2a..c8fc182c026 100644 --- a/docs/blocks.py +++ b/docs/blocks.py @@ -109,9 +109,12 @@ def on_end(self, block: etree.Element) -> None: # result = self.md.htmlStash.store(self.md.convert(md_text)) # container.text = result - container = etree.SubElement(details, "pre") - container.set("class", "marimo-source-code") - code_block = etree.SubElement(container, "code") + copy_paste_container = etree.SubElement(details, "p") + copy_paste_container.text = "Tip: paste this code into an empty cell, and the marimo editor will create cells for you" + + code_container = etree.SubElement(details, "pre") + code_container.set("class", "marimo-source-code") + code_block = etree.SubElement(code_container, "code") code_block.set("class", "language-python") code_block.text = code diff --git a/docs/faq.md b/docs/faq.md index 1c13aa7e0ae..55a64ae4dd3 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -3,43 +3,6 @@ hide: - navigation --- -# FAQ - -- [Choosing marimo](#choosing-marimo) - - [How is marimo different from Jupyter?](#faq-jupyter) - - [What problems does marimo solve?](#faq-problems) - - [How is marimo.ui different from Jupyter widgets?](#faq-widgets) -- [Using marimo](#using-marimo) - - [Is marimo a notebook or a library?](#faq-notebook-or-library) - - [What's the difference between a marimo notebook and a marimo app?](#faq-notebook-app) - - [How does marimo know what cells to run?](#faq-reactivity) - - [Does marimo slow my code down](#faq-overhead) - - [How do I prevent automatic execution from running expensive cells?](#faq-expensive) - - [How do I disable automatic execution?](#faq-lazy) - - [How do I use sliders and other interactive elements?](#faq-interactivity) - - [How do I add a submit button to UI elements?](#faq-form) - - [How do I write markdown?](#faq-markdown) - - [How do I display plots?](#faq-plots) - - [How do I prevent matplotlib plots from being cut off?](#faq-mpl-cutoff) - - [How do I display interactive matplotlib plots?](#faq-interactive-plots) - - [How do I display objects in rows and columns?](#faq-rows-columns) - - [How do I show cell code in the app view?](#faq-show-code) - - [How do I create an output with a dynamic number of UI elements?](#faq-dynamic-ui-elements) - - [Why aren't my `on_change` handlers being called?](#faq-on-change-called) - - [Why are my `on_change` handlers in an array all referencing the last element?](#faq-on-change-last) - - [Why aren't my brackets in SQL working?](#faq-sql-brackets) - - [How do I restart a notebook?](#faq-restart) - - [How do I reload modules?](#faq-reload) - - [How does marimo treat type annotations?](#faq-annotations) - - [How do I use dotenv?](#faq-dotenv) - - [What packages can I use?](#faq-packages) - - [How do I use marimo on a remote server?](#faq-remote) - - [How do I make marimo accessible on all network interfaces?](#faq-interfaces) - - [How do I use marimo behind JupyterHub?](#faq-jupyter-hub) - - [How do I use marimo with JupyterBook?](#faq-jupyter-book) - - [How do I deploy apps?](#faq-app-deploy) - - [Is marimo free?](#faq-marimo-free) - ## Choosing marimo diff --git a/docs/guides/expensive_notebooks.md b/docs/guides/expensive_notebooks.md index b3035246286..5290e18fecb 100644 --- a/docs/guides/expensive_notebooks.md +++ b/docs/guides/expensive_notebooks.md @@ -16,7 +16,7 @@ mo.stop(condition) expensive_function_call() ``` -Use [`mo.stop()`][marimo.stop] in conjunction with +Use [`mo.stop`][marimo.stop] with [`mo.ui.run_button()`][marimo.ui.run_button] to require a button press for expensive cells: diff --git a/docs/guides/reactivity.md b/docs/guides/reactivity.md index 37998f14ea7..ccd0c3f09d6 100644 --- a/docs/guides/reactivity.md +++ b/docs/guides/reactivity.md @@ -1,158 +1,189 @@ -# Reactive execution +# Running cells -Every marimo notebook is a directed acyclic graph (DAG) that models how data -flows across blocks of Python code, i.e., cells. +marimo _reacts_ to your code changes: run a cell, and all other cells that +refer to the variables it defines are automatically run with the latest data. +This keeps your code and outputs consistent, and eliminates bugs before they +happen. -marimo _react_ to code changes, automatically executing cells with the latest -data. Execution order is determined by the DAG, not by the order of cells on -the page. +??? question "Why run cells reactively?" + marimo's "reactive" execution model makes your notebooks more reproducible + by eliminating hidden state and providing a deterministic execution order. + It also powers marimo's support for [interactive + elements](../guides/interactivity.md), for running as apps, and executing as + scripts. -Reactive execution is based on a single rule: - -!!! important "Runtime Rule" - When a cell is run, marimo automatically runs all other cells that - **reference** any of the global variables it **defines**. + How marimo runs cells is one of the biggest differences between marimo and + traditional notebooks like Jupyter. Learn more at our + [FAQ](../faq.md#faq-jupyter). !!! tip "Working with expensive notebooks" - marimo gives you tools that make it easy to work with expensive notebooks. For - example, the [runtime can be - configured](configuration/runtime_configuration.md) to be lazy, only - running cells when you ask for them to be run and marking affected cells as - stale instead of auto-running them. **See our guide on working with [expensive - notebooks](expensive_notebooks.md) for more tips.** + marimo provides tools for working with expensive notebooks, in which cells + might take a long time to run or have side-effects. -## References and definitions - -A marimo notebook is a DAG where nodes are cells and edges are data -dependencies. marimo creates this graph by statically analyzing each cell -(i.e., without running it) to determine its - -- references, the global variables it reads but doesn't define; -- definitions, the global variables it defines. + * The [runtime can be configured](configuration/runtime_configuration.md) + to be **lazy** instead of + automatic, marking cells as stale instead of running them. + * Use [`mo.stop`][marimo.stop] to conditionally + stop execution at runtime. -!!! tip "Global variables" - A variable can refer to any Python object. Functions, classes, and imported - names are all variables. + See [the expensive notebooks guide](expensive_notebooks.md) for more tips. -There is an edge from one cell to another if the latter cell references any -global variables defined by the former cell. The rule for reactive execution -can be restated in terms of the graph: when a cell is run, its descendants are -run automatically. +## How marimo runs cells -## Global variable names must be unique +marimo statically analyzes each cell (i.e., without running it) to determine +its -To make sure your notebook is DAG, marimo requires that every global -variable be defined by only one cell. +- references, the global variables it reads but doesn't define; +- definitions, the global variables it defines. -!!! important "Local variables" - Variables prefixed with an underscore are local to a cell (_.e.g._, `_x`). You - can use this in a pinch to fix multiple definition errors, but try instead to - refactor your code. +It then forms a directed acyclic graph (DAG) on cells, with an edge from +one cell to another if the latter references any of the definitions of the +former. When a cell is run, its descendants are marked for execution. -This rule encourages you to keep the number of global variables in your -program small, which is generally considered good practice. - -## Local variables +!!! important "Runtime Rule" + When a cell is run, marimo automatically runs all other cells that + **reference** any of the global variables it **defines**. -Global variables prefixed with an underscore (_e.g._, `_x`) are "local" to a -cell: they can't be read by other cells. Multiple cells can reuse the same -local variables names. +marimo [does not track mutations](#variable-mutations-are-not-tracked) to +variables, nor assignments to attributes. That means that if you assign an +attribute like `foo.bar = 10`, other cells referencing `foo.bar` will _not_ be +run. -If you encapsulate your code using functions and classes when needed, -you won't need to use many local variables, if any. +### Execution order -## No hidden state +The order cells are executed in is determined by the relationships between +cells and their variables, not by the order of cells on the page (similar +to a spreadsheet). This lets you organize your code in whatever way makes the +most sense to you. For example, you can put helper functions at the bottom of +your notebook. -Traditional notebooks like Jupyter have _hidden state_: running a cell may -change the values of global variables, but these changes are not propagated to -the cells that use them. Worse, deleting a cell removes global -variables from visible code but _not_ from program memory, a common -source of bugs. The problem of hidden state has been discussed by -many others -[[1]](https://austinhenley.com/pubs/Chattopadhyay2020CHI_NotebookPainpoints.pdf) -[[2]](https://docs.google.com/presentation/d/1n2RlMdmv1p25Xy5thJUhkKGvjtV-dkAIsUXP-AL4ffI/edit#slide=id.g362da58057_0_1). +### Deleting a cell deletes its variables -**marimo eliminates hidden state**: running -a cell automatically refreshes downstream outputs, and _deleting a cell -deletes its global variables from program memory_. +In marimo, _deleting a cell deletes its global variables from program memory_. +Cells that previously referenced these variables are automatically re-run and +invalidated (or marked as stale, depending on your [runtime +configuration](configuration/runtime_configuration.md)). In this way, marimo +eliminates a common cause of bugs in traditional notebooks like Jupyter. -