Pluto.jl Ends Jupyter State Errors With Reactive Julia Architecture

Interactive notebooks ~ Pluto.jl | Fons van der Plas | JuliaCon 2020 — The Julia Programming Language

The Julia Programming Language

Enforcing topological cell evaluation and disposable module scopes guarantees notebook memory strictly mirrors visible code, eliminating the hidden variables and merge conflicts that plague legacy scientific environments.

AI-assisted summary of Interactive notebooks ~ Pluto.jl | Fons van der Plas | JuliaCon 2020 — original source. Check the original for full context.

Source published:

Key ideas

  • Pluto.jl introduces a reactive programming notebook for Julia where the execution state is guaranteed to match visible code, eliminating hidden workspace bugs caused by stale execution. (9:50)
  • The notebook runtime uses static code analysis to construct a directed acyclic graph (DAG) of cell dependencies, re-evaluating only downstream cells and recycling Julia modules to purge deleted symbols. (11:05)
  • Pluto saves notebooks as standard Julia (.jl) files ordered by dependency topology, enabling clean Git version control, command-line script execution, and headless automated grading. (18:11)
  • Interactive HTML/JavaScript controls can be bound directly to Julia variables using the @bind macro without backend boilerplate, streaming client inputs directly into numerical computations. (14:53)

Detailed notes

## Background Published by The Julia Programming Language YouTube channel on July 30, 2020, this JuliaCon 2020 presentation features Fons van der Plas introducing Pluto.jl, an interactive notebook system for Julia. The video description explains that Pluto automatically tracks global references to reactively re-evaluate downstream cells, cleans up stale workspace state, supports HTML and JavaScript widget bindings, and saves notebooks as clean, Git-friendly plain Julia files.

## TL;DR Addressing the persistent hidden state, reproducibility issues, and merge conflicts endemic to Jupyter and vintage REPL environments, Fons van der Plas and Nick present Pluto.jl, a reactive notebook system written in pure Julia. Pluto uses static code analysis of cell ASTs to construct a directed dependency graph, re-evaluating downstream logic in topological order and isolating state in disposable modules so that runtime memory strictly matches visible code. Through live demonstrations of tidal curve modeling and live webcam SVD compression, the speakers showcase reactive parameter tweaking via the `@bind` macro. Finally, they show how Pluto persists notebooks as standard, executable `.jl` scripts with clean Git diffs, closing with plans for browser-based interactive sharing and classroom education initiatives at TU Berlin and MIT.

## Atmosphere & style The presentation carries an enthusiastic, inventive, and warm energy driven by a genuine passion for educational accessibility and modern interface design. The pacing flows smoothly between Fons's conceptual storytelling and Nick's grounded live data demos, punctuated by a charming, staged phone call interruption from a user questioning reactive performance with long-running cells. It feels like an engaging, approachable tech reveal that balances serious programming language mechanics with delightful visual demonstrations like live-canvas dragging and webcam image compression.

## Bulletin - [09:50](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=590s) Pluto.jl introduces a reactive programming notebook for Julia where the execution state is guaranteed to match visible code, eliminating hidden workspace bugs caused by stale execution. - [11:05](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=665s) The notebook runtime uses static code analysis to construct a directed acyclic graph (DAG) of cell dependencies, re-evaluating only downstream cells and recycling Julia modules to purge deleted symbols. - [18:11](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=1091s) Pluto saves notebooks as standard Julia (.jl) files ordered by dependency topology, enabling clean Git version control, command-line script execution, and headless automated grading. - [14:53](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=893s) Interactive HTML/JavaScript controls can be bound directly to Julia variables using the @bind macro without backend boilerplate, streaming client inputs directly into numerical computations.

## Key takeaways - [01:06](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=66s) Traditional university-level scientific computing remains constrained by 1970s-style environments despite massive leaps in language expressiveness. - [01:47](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=107s) Standard notebooks like Jupyter suffer from persistent global state, non-reproducible out-of-order execution, and merge-hostile bloated file formats. - [09:50](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=590s) Pluto enforces a strict reactive paradigm where session state is entirely and exclusively described by visible code at all times. - [06:00](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=360s) Each Pluto cell is restricted to a single expression, ensuring one discrete output above the cell and encouraging modular code design. - [11:05](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=665s) Static AST analysis maps definitions and references into a directed dependency graph without requiring code pre-execution. - [11:55](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=715s) Workspace hygiene is maintained by swapping out disposable Julia module scopes to delete symbols and reclaim memory via garbage collection. - [13:17](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=797s) Pluto manages heavy computational cells by evaluating strictly downstream dependencies and planning duration-based execution warnings for slow runs. - [14:53](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=893s) The `@bind` macro pairs standard Julia variables with interactive HTML inputs, turning notebooks into dynamic web applications. - [16:44](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=1004s) Custom JavaScript and browser APIs, such as live webcam feeds, can pipe data directly into standard Julia matrices for real-time numerical processing. - [18:11](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=1091s) Notebooks are saved as pure, lightweight `.jl` scripts with cell outputs omitted, ensuring clean Git diffs and native interoperability with standard editors. - [19:40](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=1180s) Saved files re-order cells topologically to ensure valid top-to-bottom script execution via `julia notebook.jl` while preserving visual UUID layout orders in comments. - [21:54](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=1314s) Immediate reactive feedback empowers educational workflows, enabling real-time inline validation alerts and headless automated homework grading.

## Detailed walkthrough ### [00:03](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=3s) Why Pluto Was Created: The Gap in Programming Environments

Fons van der Plas introduces himself and his collaborator Nick, setting up their presentation of Pluto.jl, a new interactive notebook system for the Julia programming language. Reflecting on his background teaching programming in elementary schools, Fons shares the surprising realization that early education tools have made learning code remarkably intuitive. Young students use tactile robots that trace drawn lines as their physical "script," or visual environments like Scratch where drag-and-drop blocks virtually eliminate syntax errors. In those settings, eight-year-olds can master fundamental programming concepts in about a week.

```mermaid flowchart TD accTitle: Evolution of Programming Environments accDescr: Contrast between elementary visual tooling and university-level scientific computing environments.

subgraph Elementary["Elementary School Tooling"] A["Line-following Robots / Scratch"] --> B["Intuitive, Visual, Zero Syntax Errors"] end

subgraph University["University & Scientific Tooling"] C["General & Expressive Scripts"] --> D["Complex Abstractions"] D --> E["50-Year-Old REPL / File Interfaces"] end

B -.->|"The Environment Gap"| E ```

By contrast, learning programming at the university level suddenly becomes arduous. The difficulty stems not from programming being inherently hard, but from the shift toward general-purpose, highly expressive languages built on complex abstractions. While the languages themselves have grown immense in power, developers are stranded using computing environments reminiscent of the 1970s. As Fons describes the disconnect: “programming itself is easy but these languages are so powerful that if you're still using these environments from 50 years ago it feels like are blindly manipulating symbols.” To match modern expressive power, developers need a genuinely friendly, supportive interface.

[01:47](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=107s) The Pitfalls of Jupyter and Modern Alternatives

In scientific computing, Jupyter notebooks became the standard interface because they provide an interactive REPL with inputs, outputs, and rich formatted text combined in a single document. However, prolonged use exposes deep operational flaws: - **Persistent Global Scope**: Variables defined once linger in memory indefinitely, decoupling the actual runtime state from the visible text. - **Bloated File Formats**: Saving execution output directly into the notebook file creates messy, merge-hostile version control diffs. - **Reproducibility Failure**: A notebook authored on one machine frequently fails to run on another due to out-of-order execution and hidden state.

Cloud offerings like Google Colab address certain reproducibility concerns, but Fons laments that they do not rethink the core developer experience: “what bothers me the most is that they still make no improvement to the programmer environment it's still the same concepts.” Meanwhile, the JavaScript ecosystem developed tools like Observable, pioneering the "reactive notebook" paradigm where the editor acts as a proactive collaborator rather than an antagonist. Because JavaScript is not well suited for scientific computing, Fons and Nick set out to create Pluto—bringing reactive, state-consistent computing natively to Julia.

[03:09](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=189s) Live Demo: Exploratory Data Analysis and Reactivity

Nick takes over to demonstrate Pluto in action, beginning with the browser-based interface. In Pluto, users write code inside individual cells, and each cell evaluates a Julia expression. Unlike traditional notebooks that append evaluation outputs underneath, Pluto renders output directly above the code cell. Demonstrating basic variable assignments, Nick changes the value of variable `b` in one cell, causing downstream cells that depend on it to refresh instantly.

```mermaid flowchart LR accTitle: Pluto Basic Reactivity accDescr: Changing an upstream variable triggers an immediate downstream cell re-evaluation.

CellA["Cell 1: b = 10"] -->|"Reactive propagation"| CellB["Cell 2: a = b + 5"] CellB -->|"Displays output above cell"| Out["Output: 15"] ```

To demonstrate a realistic workflow, Nick moves beyond toy arithmetic to model ocean tidal patterns using an external CSV file: - **Integrated Documentation**: Unsure whether the CSV reader accepts a raw path string, Nick relies on Pluto’s built-in live docs, which confirm that a simple filename argument is valid. - **Dataset Loading**: He loads tidal observation data from Cascais (near Lisbon, Portugal), verifying the tabular contents using Pluto's integrated data preview. - **Data Splitting**: Hours and sea-level measurements are partitioned into distinct variables, extracting the first and last columns respectively. - **Visualization**: Nick imports `Plots.jl`, plotting the raw tidal data against time to reveal an oscillating, periodic waveform.

[06:00](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=360s) Single-Expression Cells and Mathematical Modeling

Attempting to overlay a sine wave onto the tidal scatter plot, Nick writes a secondary plotting command inside the same cell and hits an error. Pluto explicitly forbids multiple expressions in a single cell. This design choice guarantees that every cell has exactly one discrete output displayed directly above it, while intentionally nudging the programmer toward cleaner, modular code. Pluto provides a one-click automated action in the UI to resolve the issue.

Nick sets up a sinusoidal model:

$$\sin\left(\frac{2\pi \cdot t}{\text{period}}\right)$$

He assigns `period = 12`, guessing that tidal peaks occur approximately every 12 hours, which produces a remarkably close fit on the first try. Adding an adjustable phase offset variable initialized to zero, he observes that while 12 hours is close, a slightly longer duration like 13 hours might fit the observed peaks better.

[07:50](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=470s) HTML Sliders, Markdown, and Generalizing Data

Rather than manually typing numbers to tweak the fit, Nick utilizes Pluto's HTML binding capabilities to connect variable values directly to browser input elements: - **Binding Sliders**: Using `@bind`, he links the `period` variable to an HTML `<input type="range">` spanning a range of 11 to 14 with fine step intervals, allowing the model curve to stretch and contract smoothly across the plot as the slider moves. - **Dynamic Markdown**: He creates a Markdown cell—which in Pluto is simply a standard code cell returning a Markdown string—to interpolate and display the active numerical value (e.g., `12.38 hours`). - **Phase Control**: A second slider controls the `phase` variable across an interval between -3 and 3. - **Testing Model Portability**: To test if the sinusoidal fit holds across locations, Nick replaces the `"cascais"` file reference with `"catania"`. Pluto’s reactivity cascades across the graph instantly, reloading the Sicilian sea-level data and confirming the model's validity.

[09:50](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=590s) The Reactive Paradigm: State Matches Code

Fons returns to explain the foundational philosophy of reactive notebooks. In Pluto, the state of the session is strictly synchronized with the editor view: “at any instant the program state is completely described by the code you see and this is guaranteed to be true at any point during your process with your notebook.” Unlike standard REPLs or Jupyter workspaces, Pluto guarantees that stale code executed an hour earlier cannot linger in memory to pollute current calculations.

When a user edits any cell, Pluto coordinates two distinct operations under the hood: 1. **Dependency Analysis**: It determines which downstream cells rely on modified identifiers and re-evaluates them in topological order. 2. **Scope Cleanup**: It purges variables, functions, types, and modules created by previous iterations of modified or deleted code.

```mermaid flowchart TD accTitle: Pluto Cell Modification Lifecycle accDescr: How Pluto parses dependencies and cleans up workspace state upon a cell edit.

Edit["User modifies or deletes a cell"] --> Analysis["Static Code Analysis"] Analysis --> Step1["Re-evaluating Downstream Cells"] Analysis --> Step2["Clean Up Old Code"]

subgraph Step1["Step 1: Downstream Execution"] S1A["Identify Defined & Referenced Symbols"] --> S1B["Traverse Directed Acyclic Graph (DAG)"] S1B --> S1C["Re-evaluate downstream cells in order"] end

subgraph Step2["Step 2: Workspace Hygiene"] S2A["Identify deleted symbols"] --> S2B["Discard old module scope"] S2B --> S2C["Transfer active variables to new module scope"] end ```

[11:05](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=665s) Topological Execution and Workspace Hygiene

To establish correct execution order across cells, Pluto uses static code analysis rather than runtime inspection. Before executing a cell, Pluto inspects its abstract syntax tree (AST) to build two lists: the variables defined within the cell and the variables referenced by it. By cross-referencing these lists across all cells, Pluto maintains a directed dependency graph. Whenever a cell changes, the runtime traverses the graph downward from that node, executing affected cells in valid topological order.

Cleaning up old code presents a unique technical hurdle because Julia does not natively support un-defining variables or removing symbols from a global module scope. If a user defines `potato = 10`, uses it downstream, and subsequently deletes the definition, Pluto ensures that downstream cells immediately throw an `UndefVarError: potato not defined`. This cleanup applies uniformly to variables, constants, user-defined functions, and package imports (`using`/`import`).

To achieve this without native un-definition primitives, Pluto isolates runtime state within disposable Julia modules. When variables must be deleted or replaced, Pluto instantiates a fresh module scope, carries forward the surviving, actively defined variables, and abandons the old scope to be reclaimed by the garbage collector.

[13:17](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=797s) Performance, Dependencies, and the Long-Running Cell Dilemma

Just as the talk is transitioning to how reactivity works in practice, an incoming call interrupts the presentation. It is Luka, calling with a pressing concern that often troubles people considering reactive workflows:

> “I'm working on a model at Pluto and I have a few cells that take a really long time to run, so I'm worried that every time I change a variable it will run all those cells again and that seems really inefficient.”

Fons reassures him that Pluto handles this gracefully behind the scenes. Because Pluto computes a dependency graph for every cell, it executes strictly what is downstream of a change: “Pluto figures out the dependencies of each cell and it will only run the cells that actually need to be run.” Furthermore, if an author wants to make multiple edits without re-triggering heavy computations after each keystroke, they do not have to commit them one by one. Pluto permits batching changes together so that everything is processed cleanly in a single execution pass.

When Luka follows up to ask what happens if someone triggers a cell without realizing a massive tree of dependencies will take an enormous amount of time to execute, Fons points out that code execution can always be canceled manually. However, Pluto can also leverage its own history:

> “Pluto knows how long cells take to run, and we're working on some user interface that will also tell you how long all of the dependent cells take to run, and maybe if it takes over a minute or something it can warn you.”

Relieved, Luka thanks him and hangs up so Fons can resume the demonstration.

```mermaid flowchart TD accTitle: Pluto Dependency Analysis and Execution accDescr: Diagram illustrating how Pluto evaluates cells based on directed dependency graphs and warns against slow runs.

subgraph Analysis["Static Code Analysis"] A["Modified Cell"] --> B["Dependency Graph"] end

subgraph Decision["Execution Engine"] B --> C{"Downstream cell?"} C -- "No" --> D["Skip Execution"] C -- "Yes" --> E["Check Past Run Durations"] E --> F["Batch Run Only Affected Cells"] E -. "Long duration".-> G["UI Warning (> 1 min)"] end ```

[14:53](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=893s) Reactivity and Interactivity with `@bind` and PlutoUI

Returning to interactivity, Fons highlights that reactive dependencies turn a notebook into a dynamic application without any complex architectural overhead. When an upstream variable such as `s` is defined in one cell and squared in another cell, modifying `s` immediately forces the dependent cell to re-evaluate.

> “The only thing you do is you take your parameter and define it in a different cell.”

To turn raw parameters into graphical controls, Pluto introduces the `@bind` macro. Instead of hard-coding a variable, `@bind` ties the Julia variable to the current state of a web input element:

```julia @bind s Slider(1:500) ```

Typing into an HTML text field or moving a slider updates the Julia string or numeric variable instantly, driving all downstream computations across the notebook.

- Basic controls are bundled into the companion package `PlutoUI.jl`, providing drop-in elements like range sliders without requiring custom front-end code. - Developers familiar with HTML and JavaScript can build custom input elements; Pluto transmits the emitted values directly back into Julia. - Fons demonstrates an interactive bounding-box tool where dragging a mouse on an HTML canvas instantly streams the rectangle's pixel dimensions back into the notebook environment.

[16:44](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=1004s) Advanced Custom Controls: Live Webcam and SVD Image Compression

To showcase the power of custom JavaScript bindings, Fons opens an educational notebook designed to explain the Singular Value Decomposition (SVD). The notebook embeds a webcam element hooked into the browser:

> “There's my face, and when I take a picture, it actually binds the image data to this array, so it's a 2D array that for each pixel has the black and white value.”

Once the snapshot is captured, Pluto immediately exposes it as a standard two-dimensional Julia matrix. From there, standard linear algebra routines process the matrix. The notebook computes the SVD and lets the user inspect the first ten singular pairs. Fons binds the rank truncation threshold to a slider, making it possible to scrub back and forth to watch low-rank matrix approximations progressively reconstruct the camera portrait in real time.

While building bespoke components like the camera capture tool requires writing JavaScript, Fons explains that users do not need front-end development knowledge for ordinary work: the camera widget is slated for inclusion directly inside `PlutoUI.jl`, and everyday parameter exploration requires nothing more than splitting code across cells.

[18:11](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=1091s) The Minimal `.jl` File Format and Git Integration

Pluto rejects bespoke, bloated JSON formats in favor of plain Julia files. Saving only raw source code—and omitting cell outputs entirely—keeps files lightweight, readable, and perfectly compatible with standard developer tooling.

Fons displays a side-by-side view featuring Pluto on the left and a plain text editor on the right: a running notebook translates into a compact 16-line `.jl` script. Edits in the notebook interface auto-save to disk instantly.

```julia ### A Pluto.jl notebook ### # v0.11.0

using Markdown using InteractiveUtils

# ╔═╡ a1b2c3d4-... potato = melon * 3

# ╔═╡ e5f6a7b8-... melon = 5

# ╔═╡ Cell order: # ╠═e5f6a7b8-... # ╠═a1b2c3d4-... ```

Because the notebook is saved as standard Julia code, it can be executed headless from the command line (`julia notebook.jl`) or brought into another session:

> “It's not just including inside REPL, it's you can include one notebook in the other notebook or if you're students you can test your students' homework one by one just by including those Julia files.”

The file format handles cell ordering gracefully. In Pluto, reactive cells can appear in any visual order on the canvas—such as defining `potato = melon * 3` above the definition of `melon = 5`. To keep the saved file valid for standard Julia linear execution, Pluto re-orders the definitions top-to-bottom according to their dependency graph, appending a list of cell UUIDs at the very end of the file so the visual layout can be reconstructed when reopened in Pluto. This approach ensures version control stays clean: Git diffs reflect only exact source-code alterations, completely free of the noisy diff churn caused by updated plot metadata or serialized base64 outputs.

[20:45](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=1245s) Installation, Future Roadmap, and Web Distribution

Fons summarizes Pluto's core foundation: fully reactive execution, pure `.jl` persistence, built-in interactivity, pure Julia development with minimal dependencies, and a simple installation workflow:

```julia import Pkg; Pkg.add("Pluto") import Pluto; Pluto.run() ```

Looking ahead, Fons highlights two major milestones:

1. **Frictionless Browser Sharing:** While Pluto exports clean static HTML and PDF documents, the long-term objective is frictionless sharing of fully live, interactive notebooks without requiring end users to install Julia locally or configure complex cloud hosting: > “What you really want is to be able to export these fully interactive notebooks, so send someone a link where they can play with your notebook directly in the browser.” Because Pluto is lightweight enough to run on free hosting tiers like Heroku, the team plans to make one-click deployments standard, alongside embedding reproducible package environments directly within the notebook file itself. 2. **First-Class Interactive Education:** Making Pluto the premier tool for teachers and students.

[21:54](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=1314s) Pluto in Education and Future Plans

Education is a central motivation for the project, as beginners benefit enormously from immediate, reactive visual feedback. Fons presents an automated grading exercise where a student is tasked with writing the formula for the golden ratio. When a candidate formula evaluates to a negative number, the notebook reactively triggers an inline validation alert: *“Oops, the golden ratio should be positive.”* Correcting the minus sign to a plus sign satisfies the reactive check and flips the indicator to show that the answer is correct.

- Teachers gain an intuitive environment for producing lively course material, while automated grading pipelines can evaluate student submissions simply by running their `.jl` files as automated scripts. - Pilot programs and classroom trial runs are slated for the upcoming semester at TU Berlin and MIT, with Fons attending directly to collect feedback from both instructors and students. - Insights gathered from these courses will be funneled into documentation, authoring guides, video tutorials, and dedicated education packages containing pre-built interactive components, multiple-choice widgets, and grading helpers.

Fons closes the talk by encouraging the community to reach out via GitHub to contribute, leaving the audience with an inspiring sign-off quote from Matthijs Cox.

## Notable quotes > [09:50](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=590s) at any instant the program state is completely described by the code you see and this is guaranteed to be true at any point during your process with your notebook. — Fons van der Plas

> [13:17](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=797s) Pluto figures out the dependencies of each cell and it will only run the cells that actually need to be run. — Fons van der Plas

> [20:45](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=1245s) What you really want is to be able to export these fully interactive notebooks, so send someone a link where they can play with your notebook directly in the browser. — Fons van der Plas

## Mentioned Pluto.jl, Fons van der Plas, Nick, Julia, Scratch, Jupyter, Google Colab, Observable, Matlab, Plots.jl, Luka, PlutoUI.jl, Heroku, TU Berlin, MIT, Matthijs Cox

## Video description Introducing a fresh, new notebook system for rapid prototyping! Pluto understands global references between cells, and reactively re-evaluates cells affected by a code change. At JuliaCon, we will show how Pluto can liven up your workflow.

Whether you’re a scientist, a finance professional or an engineer, you use notebooks like Jupyter to tell a story. You fiddle a bit with your code, running cells here and there, and when you’re done - you restart the kernel and keep your fingers crossed that it’ll all work together when you press “run all”.

🙋 In Pluto, things work differently. When you change a variable, Pluto automatically re-runs the cells that refer to it. And when you delete a cell, the variables, methods and imports from the old code disappear. Unlike Jupyter or Matlab, there is no mutable workspace, but rather a one-to-one correspondence between variables and code.

🚨 Reactivity is not just fun for mathematical tricks! It guarantees that the code you see exactly matches the variables you're working with, eliminating bugs before you even knew you had them.

⚡ Your notebook becomes interactive by splitting your code into multiple cells! Changing one cell instantly shows effects on all other cells, giving you a fast and fun way to experiment with your model. And to really spice up your notebook, you can use HTML sliders, or even custom JavaScript widgets, to drive your Julia variables. Change λ = 5 to @bind λ Slider(1:10), and all cells that use λ are controlled by a slider.

💾 Notebooks are saved as pure Julia files and can be exported as rich documents with cell output to HTML or PDF. By separating source code and output, you can take full advantage of git for version control and you can import Pluto notebooks as if they are written in a regular editor.

After a live demo, the second part of the talk will unveil some of the tricks that power Pluto. The core concepts are: - static code analysis to find global definitions and references in cells; - directed graph of cells, which tells Pluto which cells to run, in which order; - managed workspace for code to live in, and cleaning the workspace in milliseconds; - responsive connection between JavaScript clients and Julia.

Pluto is written in pure Julia, which comes with two benefits: first, it’s easily installable as a package without requiring Python - you only need Julia and a web browser. Second, it is ready to be improved by Julia developers who we hope to inspire at the conference. Pluto is an exciting project to work on, and we are eager to hear your ideas!

Resources Pluto.jl home page: https://plutojl.org/ Pluto.jl repository: https://github.com/fonsp/Pluto.jl

Contents 00:00 Opening 00:19 Introduction 00:42 Why we made Pluto? 01:06 Programming is easy, programming languages are powerful, but our environments are 70s vintage 01:47 Jupyter notebooks: strong points and pain points 02:23 Alternatives to Jupyter 03:09 Enter Pluto. Live demo 06:00 Pluto doesn't allow multiple expressions in one cell, here is why 07:50 Binding value variable to slider 08:33 Markdown cells in Pluto 09:50 Reactive paradigm 10:35 Taking look behind scene on how reactivity works 11:05 I. Re-evaluating downstream cells 11:55 II. Clean up old code 13:25 Call about re-evaluating cells, which have a long evaluation time 14:53 Interactivity in Pluto 16:22 Using JavaScript you can make any interactive element you want 16:44 Example: using your picture to define matrix (two dimensional array) 17:21 Manipulation picture inside Pluto 17:47 Do you need to know JavaScript and HTML? 18:11 Pluto.jl minimalist file format 20:45 Recapitulation 21:03 What's next? 21:54 Pluto for education 23:23 Thank you!

Want to help add timestamps to our YouTube videos to help with discoverability? Find out more here: https://github.com/JuliaCommunity/YouTubeVideoTimestamps

Interested in improving the auto generated captions? Get involved here: https://github.com/JuliaCommunity/YouTubeVideoSubtitles

[Source](https://www.youtube.com/watch?v=IAF8DjrQSSk)

中文简报

Pluto.jl 以响应式 Julia 架构终结 Jupyter 状态错误 通过强制执行单元格拓扑求值和一次性模块作用域,确保笔记本内存严格对应可见代码,消除困扰传统科学计算环境的隐藏变量和合并冲突。 针对 Jupyter 和传统 REPL 环境中普遍存在的隐式状态、可重现性问题以及合并冲突,Fons van der Plas 与 Nick 介绍了采用纯 Julia 编写的响应式笔记本系统 Pluto.jl。Pluto 对单元格 AST 进行静态代码分析以构建有向依赖图,按拓扑顺序重新评估下游逻辑,并在一次性模块中隔离状态,从而使运行时内存严格与可见代码保持一致。通过潮汐曲线建模和实时网络摄像头 SVD 压缩的现场演示,演讲者展示了利用 `@bind` 宏进行响应式参数调整的功能。最后,他们展示了 Pluto 如何将笔记本持久化保存为具有整洁 Git diff 的标准可执行 `.jl` 脚本,并总结了针对基于浏览器的交互式共享以及在柏林工业大学和麻省理工学院开展课堂教学计划的规划。 Pluto.jl 为 Julia 引入了一种响应式编程笔记本,保证执行状态与可见代码完全匹配,消除了因陈旧执行导致的隐藏工作区错误。 (9:50) 笔记本运行时利用静态代码分析构建单元格依赖项的有向无环图(DAG),仅重新评估下游单元格,并通过回收 Julia 模块来清除已删除的符号。 (11:05) Pluto 将笔记本按依赖拓扑顺序保存为标准 Julia(.jl)文件,支持清晰的 Git 版本控制、命令行脚本执行以及无头自动评分。 (18:11) 交互式 HTML/JavaScript 控件可以使用 @bind 宏直接绑定到 Julia 变量,无需后端样板代码,即可将客户端输入直接流式传输到数值计算中。 (14:53)

Reading summary

At JuliaCon 2020, Fons van der Plas and collaborator Nick introduced Pluto.jl, a reactive notebook system designed to eliminate hidden state and out-of-order execution issues prevalent in traditional scientific computing environments like Jupyter. Addressing the Flaws of Traditional Notebooks (0:03) Fons van der Plas notes a stark divide between early educational programming tools, such as Scratch, and university-level scientific interfaces. While modern languages have become expressive and abstract, computing environments frequently rely on 50-year-old terminal and file paradigms. In scientific workflows, Jupyter notebooks became ubiquitous by combining inputs, outputs, and formatted text, but their persistent global scope decouples runtime memory from the visible document, leading to broken reproducibility and bloated file formats. Deterministic Reactivity and Scope Hygiene (9:50) Pluto enforces strict synchronization where session state is entirely defined by visible code. Each cell evaluates a single Julia expression with output rendered above the input. When a cell changes, Pluto uses static abstract syntax tree analysis to identify defined and referenced symbols, traversing a directed acyclic graph to re-evaluate downstream dependencies in topological order. Overcoming Module Mutation and Execution Overhead (11:05) Because Julia lacks native mechanisms to un-define variables from global module scopes, Pluto isolates state inside disposable modules. When symbols are altered or deleted, active variables are moved into a fresh scope while discarded bindings are garbage collected, immediately raising runtime errors for orphaned downstream references. To address performance bottlenecks in slow-running models, Pluto only re-evaluates strictly dependent cells, permits batched multi-cell updates, and tracks historical run times to warn users before triggering long dependency runs. Interactive UI and Minimal File Persistence (14:53) Interactivity in Pluto requires no complex front-end frameworks. Using the `@bind` macro alongside the companion library PlutoUI.jl, variables can be bound directly to HTML sliders, input boxes, or custom JavaScript components like webcams and canvas selectors. For storage, Pluto rejects bloated JSON files in favor of plain, human-readable `.jl` files that strip serialized outputs to keep Git diffs clean. Educational Impact and Distribution Roadmap (20:45) Education remains a core driver for Pluto's design. The platform supports dynamic grading and inline error alerts, which are slated for classroom trials at institutions including TU Berlin and MIT. Long-term project goals include one-click web deployment on platforms like Heroku, embedded reproducible package environments, and the release of dedicated education packages featuring automated grading helpers. While Pluto provides reproducible state management and clean source control, fully browser-based distribution without local Julia installations remains in active development, alongside planned user-interface enhancements to manage and warn against slow-running dependent cell executions.

精炼阅读摘要

Fons van der Plas 与合作者 Nick 在 JuliaCon 2020 上推出了专为 Julia 打造的响应式交互式笔记本系统 Pluto.jl。演讲指出,传统科学计算工具长期受困于隐藏状态、执行乱序与版本控制臃肿,而 Pluto 通过静态依赖图、状态即时同步与纯 Julia 脚本存储,重塑了科学计算与教育的交互体验。 传统笔记本的环境断层与可复现性缺陷 (0:03) Fons 指出,现代编程环境存在明显断层:初等教育中基于 Scratch 或实体机器人的工具能让八岁儿童在一周内掌握核心概念且极少发生语法错误,而在大学和科研层面,高度抽象且强大的语言却仍依赖 50 年前的 REPL 与纯文本文件模式。Jupyter 等被广泛采用的标准工具虽然集成了输入、输出与富文本,但在长期使用中暴露了持久全局作用域引发的状态残留、执行输出混入文件导致版本控制混乱,以及换机运行失败等可复现性隐患。尽管 Google Colab 等云平台解决了一部分环境配置问题,但未革新开发者环境本身;而 Observable 虽然开创了响应式笔记本范式,其底层 JavaScript 却不契合科学计算需求。 静态依赖分析与干净的作用域隔离 (9:50) Pluto 的核心原则是会话状态在任何瞬间都完全由当前可见的代码定义,杜绝历史执行遗留的陈旧状态。为建立准确的单元格执行顺序,Pluto 并不依赖运行时动态检查,而是在执行前对每个单元格的抽象语法树(AST)进行静态代码分析,提取所定义和引用的符号,维护有向无环依赖图(DAG),并在上游变更时按拓扑顺序自动重算下游单元格。针对长时间运行单元格的性能顾虑,Fons 解释系统仅定向重算下游变更,并支持将多处修改合并批处理;团队还在研发历史耗时预警功能(例如对耗时超一分钟的依赖链给出提示)。此外,针对 Julia 语言本身不支持在全局模块中反定义(un-define)变量的问题,Pluto 采用一次性模块机制隔离状态:一旦变量被删除或修改,系统即创建新的模块作用域并迁移存活变量,交由垃圾回收器清理旧模块,确保删除变量后立即抛出 UndefVarError。 单表达式限制与实时 UI 双向绑定 (6:00) 在交互逻辑上,Pluto 明确禁止在单个单元格中编写多条独立表达式,确保每个单元格仅对应一个显示在其上方的离散输出,引导用户编写模块化代码。为了将纯参数探索转化为动态应用,Pluto 引入了 `@bind` 宏,可直接将 Julia 变量与 HTML 滑块、文本框等控件绑定。演示展示了通过滑动调节拟合海洋潮汐波形的周期与相位,切换数据集时整个可视化图表即时联动更新。配合拓展包 PlutoUI.jl,开发者无需编写复杂的前端代码即可调用常规组件;系统亦支持通过自定义 JavaScript 传递富媒体数据,例如调用浏览器摄像头捕获二维灰度矩阵并联动 SVD 算法进行图像低秩近似重构。 纯脚本存储架构与版本控制优势 (18:11) 与 Jupyter 采用的庞大 JSON 规范相反,Pluto 选择将笔记本持久化为标准的 `.jl` 纯 Julia 文件。文件中仅保存纯源代码,完全剥离绘图元数据与 Base64 编码的单元格运行输出,从而消除了 Git 协作中常见的 diff 冲突。在保存时,Pluto 会根据依赖图将可能乱序摆放的单元格按线性拓扑顺序重新排布,并在文件末尾附带单元格 UUID 列表以在界面中还原视觉布局。这使得 `.jl` 文件不仅能在 Git 中呈现清晰的代码变更,还可直接通过命令行 `julia notebook.jl` 无头执行,或利用 include 直接引入其他脚本与作业批改流程中。 Pluto 团队未来的开发重心在于无缝的浏览器端分发与交互式教学拓展。远期规划包括利用 Heroku 等轻量级托管实现免安装 Julia 的一键在线交互运行,并在柏林工业大学(TU Berlin)和麻省理工学院(MIT)开展教学试点,以完善自动化作业批改工具与配套教学组件库。

Detailed notes — zh

## Background 该视频由 YouTube 频道 The Julia Programming Language 于 2020 年 7 月 30 日发布,主讲人为 Fons van der Plas。视频旨在介绍专为 Julia 打造的全新轻量级交互式笔记本系统 Pluto.jl,展示其如何通过响应式计算、全局引用解析以及极简存储模式重塑科研与教育的工作流。 ## TL;DR 演讲首先剖析了传统 Jupyter 笔记本在全局状态污染、版本控制冲突以及可复现性上的核心痛点,并正式推出了纯 Julia 编写的响应式笔记本 Pluto.jl。通过潮汐建模与 SVD 图像压缩等现场演示,演讲者展示了单表达式约束、依赖拓扑自动重算以及利用 @bind 机制双向绑定 HTML/JavaScript 交互组件的特性。底层架构上,Pluto 利用静态代码分析构建有向依赖图,并通过动态作用域置换彻底抹除废弃代码的副作用。最后,演讲重点展现了 Pluto 基于纯 .jl 文本存储对 Git 版本控制的极致友好性,以及其在 MIT 等高校重塑数学与编程教育的广阔前景。 ## Atmosphere & style 整场演讲充满极客式的热情与平易近人的教学亲和力,氛围轻松而富有启发性。从回忆小学 Scratch 教学的生动开场,到穿插合作者连线提问的幽默插曲,两位讲者配合默契,节奏明快紧凑。实机演示中滑块拖拽与代码拓扑即时响应的丝滑效果令人惊艳,既有扎实硬核的底层编译与作用域原理解析,又洋溢着致力于降低大众编程门槛的教育情怀。 ## Bulletin - [00:19](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=19s) Fons van der Plas 与团队推出专为 Julia 打造的轻量级响应式笔记本 Pluto.jl,旨在彻底解决 Jupyter 常见的持久全局作用域残留、执行顺序混乱与版本控制困难等痛点。 - [09:50](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=590s) Pluto 确立“程序状态完全且仅由屏幕当前代码决定”原则,通过静态分析提取定义与引用构建有向依赖图(DAG),精准重算受影响的下游单元格,并通过模块作用域置换抹去已删除代码的隐式变量。 - [14:53](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=893s) 通过 `@bind` 宏与 PlutoUI,Julia 变量可直接双向绑定 HTML 原生表单及自定义 JavaScript 控件,实现从滑块调参到本地摄像头实时灰度矩阵 SVD 分解的平滑交互。 - [18:11](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=1091s) 笔记本原生保存为仅含代码的纯 `.jl` 文本文件,按依赖拓扑排序存储且不混杂输出结果,支持终端直接运行、`include` 引入以及极度干净的 Git 版本比对。 ## Key takeaways - [01:06](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=66s) 现代高级编程语言表达能力强大,但主流交互环境仍停留在 1970 年代的古老交互逻辑,导致复杂的抽象概念在割裂的环境中极难驾驭。 - [01:47](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=107s) Jupyter Notebook 的持久全局作用域容易潜伏已删除的游离变量,且乱序执行严重破坏了科学计算文档的可复现性。 - [02:23](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=143s) Pluto.jl 汲取了 Observable 等现代响应式前端环境的设计理念,将响应式范式引入高性能科学计算语言 Julia 中。 - [03:09](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=189s) 在 Pluto 界面中,单元格执行输出默认置于代码上方,且严格限制单个单元格只包含一个顶级表达式以强制代码模块化(支持用 `begin... end` 包裹多行代码)。 - [11:05](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=665s) 响应式核心机制:基于静态代码分析提取各单元格的变量定义(Defs)与引用(Refs),构建有向依赖图(DAG)实现下游按拓扑序自动化重算。 - [11:55](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=715s) 针对 Julia 全局作用域无法主动删除变量的语言约束,Pluto 巧妙利用轻量级动态 Module 置换机制,在代码删改时丢弃旧模块并迁移存活变量以实现无污染清理。 - [13:17](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=797s) 对于耗时较长单元格的重算担忧,Pluto 仅执行真正受依赖链影响的节点,支持批量修改合并提交,并规划了针对耗时超过一分钟长任务的运行前预警机制。 - [14:53](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=893s) 无需复杂的前端框架,只要将关键变量拆分至独立单元格,再配合 `@bind` 机制即可将 Julia 内部状态与 HTML/DOM 节点建立双向实时响应。 - [16:22](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=982s) 支持自定义 JavaScript 交互扩展:现场演示了调用本地摄像头拍摄头像实时生成二维灰度矩阵,并通过滑块动态调节 SVD 奇异对重构过程。 - [18:11](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=1091s) 存储格式采用极简主义,仅保存纯 `.jl` 脚本代码而坚决不持久化渲染输出,使得文件体积微小且 Git diff 极为清晰。 - [18:55](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=1135s) 生成的 `.jl` 文件内部按依赖拓扑排序存储代码段,在尾部通过 UUID 记录界面显示顺序,兼顾了命令行直接运行(`julia file.jl`)与前端排版还原。 - [21:03](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=1263s) 团队将进一步拓展一键轻量化云端交互分享功能,并把 Pluto 深度融入柏林工业大学(TU Berlin)与麻省理工学院(MIT)的教学实践中以降低初学者的挫败感。 ## Detailed walkthrough ### [00:19](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=19s) 创立 Pluto.jl 的初衷与现有编程环境的痛点 Fons van der Plas 与 Nick 共同登台介绍了为 Julia 语言全新打造的交互式笔记本系统 Pluto.jl。在深入技术细节之前,Fons 首先分享了他此前在小学教授编程的经历。当时他们使用了许多有趣的工具,比如让能够沿黑线行进的机器人依据纸上绘制的线条执行指令,此时纸上的线条本质上就是“代码”;他们还使用了 Scratch 这类图形化积木编程语言,用户通过直观的视觉交互来拖拽逻辑,从根源上杜绝了语法错误。教学实践表明,编程的思维本质并不困难,一个八岁的儿童大约只需要一周时间就能学会编程。 然而令人困惑的是,到了大学阶段,编程却突然变得异常艰难。Fons 解释道,大学阶段的通用编程需要更高的代码表达力,程序员需要不断构建和传递抽象概念;编程本身并非不可逾越,但语言极其强大,如果开发者依然使用着源自半个世纪前(1970年代)的古老开发环境,就会产生严重的割裂感。正如 Fons van der Plas 所指出的那样:“编程本身其实很简单,但这些语言如此强大,以至于如果你还在使用 50 年前的环境,就会感觉自己是在盲目地摆弄符号。”(“Programming itself is easy, but these languages are so powerful that if you're still using these environments from 50 years ago, it feels like you are blindly manipulating symbols.”)因此,强大的现代语言亟需一个更加友好、智能的环境相匹配。 在科学计算领域,目前广泛采用的环境是以 Jupyter Notebook 为代表的交互式笔记本。Jupyter 的核心优势在于交互性:它将 REPL 的输入和输出以单元格(Cell)的形式延展在整个页面上,代码、执行输出和富文本排版融于同一份文档中。然而,深入使用后一系列痛点便暴露无遗: - **持久化的全局作用域(Persistent Global Scope)**:变量一旦在某个单元格中被定义,便会永久驻留在内核中,哪怕删除了该单元格,旧变量依然潜伏在内存里。 - **版本控制极其困难**:文件格式(如 `.ipynb` JSON)中混杂了代码输出与二进制结果,导致 Git diff 杂乱不堪,极易产生合并冲突。 - **可复现性(Reproducibility)缺失**:在一台机器上编写并调试好的 Notebook,由于单元格执行顺序随意,换到另一台机器上很可能根本无法按预期跑通。 虽然 Google Colab 等基于云端的笔记本解决了部分技术配置和环境复现问题,但 Fons 强调,这类工具并没有对程序员的实际开发环境理念做出实质性改进,依然沿用着数十年前的老套逻辑。反观 JavaScript 生态,诸如 Observable 等新型开发环境引入了“响应式笔记本(Reactive Notebook)”范式。在这种智能编辑器中写代码,人机交互的体验变成了协同合作,而非像传统环境那样“人和电脑对着彼此大吼大叫”。遗憾的是 JavaScript 并不适合密集的科学计算,这促使团队决定打造 Pluto:一个汲取现代化交互理念、专为 Julia 量身定做的响应式笔记本系统。 --- ### [03:09](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=189s) 现场实机演示:潮汐数据建模与 Pluto 的响应式体验 随后,演讲交由 Nick 进行 Pluto 的现场功能演示。Nick 打开浏览器展示了 Pluto 的用户界面,其基础布局依然符合笔记本的直观认知——代码写在单元格中,每个单元格代表一个表达式。但 Pluto 拥有一个醒目的特征:表达式的计算结果默认显示在单元格的**上方**,而不是传统 Jupyter 的下方。 Nick 随手定义了变量 `a` 和 `b`,并演示了最核心的响应式特性:当在下方修改变量 `b` 的数值时,上方引用了 `b` 的单元格瞬间自动更新。Nick 解释说,这种“响应式(Reactivity)”是 Pluto 的灵魂,能够让研究人员以极高的效率实时探索想法。 ```mermaid flowchart TD accTitle: Pluto 的潮汐数据分析与响应式计算流程 accDescr: 展示从加载 CSV 数据、提取时间与水位,到通过交互式滑块驱动正弦波模型拟合的整体依赖流程。 subgraph DataIngestion ["数据输入与提取"] CSV["CSV 数据源: data.csv<br/>(Cascais / Catania 潮汐)"] Hours["时间序列 (hours = data[1])"] SeaLevels["水位序列 (sea_levels = data[end])"] CSV --> Hours CSV --> SeaLevels end subgraph Modeling ["参数绑定与建模"] SliderPeriod["HTML Range 滑块: period (11:0.01:14)"] SliderPhase["HTML Range 滑块: phase (-3:0.01:3)"] Model["正弦拟合模型: sin(2π / period * t + phase)"] SliderPeriod --> Model SliderPhase --> Model end subgraph Visualization ["响应式可视化输出"] Plot["Plots.jl 渲染曲线与散点图"] Markdown["Markdown 说明: 当前周期数值展示"] Hours --> Model SeaLevels --> Plot Model --> Plot SliderPeriod --> Markdown end ``` 为了避免纸上谈兵,Nick 随后通过一个真实案例进行演示:探索葡萄牙里斯本附近的卡斯凯什(Cascais)潮汐规律。在加载外部数据时,Nick 借助 Pluto 内置的实时文档(Live Docs)快速确认了加载 CSV 文件的具体参数形式,直接以文件名加载了该数据集。Pluto 能够实时展开数据表格的完整预览,确保数据正确读入。 接着,Nick 展开了数据处理与建模流程: - 分别提取数据第一列的时间(`hours`)和最后一列的实际水位(`sea_levels`)。 - 引入 `Plots.jl`,利用开箱即用的绘图支持绘制水位散点图,观察发现潮汐变化具有显著的周期性,适合用正弦波拟合。 - 在尝试将绘图与正弦函数调用塞进同一个单元格时,Pluto 抛出了提示:**Pluto 严格限制一个单元格内只能包含一个顶级表达式**。Nick 解释这是因为单元格结果展示在代码上方,若存在多个表达式会导致视觉与语义混乱;更重要的是,单表达式约束天然地迫使开发者编写更为清晰、解耦的模块化代码。对此,用户只需点击 Pluto 界面上的修复按钮,系统就会自动将多行逻辑用 `begin... end` 代码块进行包裹。 为了调整正弦模型的周期(`period`,初设约为 12 小时)与相位(`phase`),Nick 展示了 Pluto 的原生交互黑科技:利用 `@bind` 机制将 Julia 的数值变量直接绑定到纯 HTML 的 `<input type="range">` 滑块组件上。 - 用户通过拉动滑动条(例如将周期范围设在 11 到 14 小时之间,步长极细),Julia 端变量实时接收变动,下游依赖该参数的正弦曲线和绘图便会如行云流水般平滑重绘。 - 单元格在 Pluto 中还可无缝充当 Markdown 文本单元,通过在 Markdown 中插值注入变量,直接在文档段落里显示“当前周期为 12.38 小时”。 - 当把数据源文件名从葡萄牙的 `Cascais` 动态改成意大利的 `Catania` 时,全局依赖链瞬间触发更新,新的潮汐数据即刻被读入并应用现有正弦模型渲染出来,直观验证了模型的泛化拟合能力。 --- ### [09:50](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=590s) 响应式范式解析:代码即状态与依赖图执行 演示结束后,Fons 接过话茬,从理论与底层架构层面深度拆解 Pluto 的“响应式范式(Reactive Paradigm)”。在宏观层面上,Pluto 确立了一条不可动摇的设计底线:“在任何时刻,程序的运行状态完全且仅由当前屏幕上所见的代码所决定。”(“At any instant, the program state is completely described by the code you see.”)Fons 进一步阐明,这保证了程序状态绝不会被一个小时前曾存在过、现在却已被删改的代码所污染;之前定义过的游离变量绝不可能永远苟活在后台内存中。这种机制绝非为了炫技,而是能从根本上杜绝绝大多数由于执行顺序颠倒、隐式状态残留而导致的难以察觉的隐蔽 Bug。 每当用户修改笔记本中的任意一个单元格时,Pluto 底层会自动并发执行两项关键操作: 1. **静态代码分析与下游单元格重算**:推导依赖图,找出所有受影响的下游单元格并按正确顺序触发更新。 2. **清理旧代码的隐式作用域副作用(Cleanup Scope Effects)**:彻底抹去被删除或修改的代码在运行环境中留下的一切痕迹。 ```mermaid flowchart TD accTitle: Pluto 的单元格变动处理流水线 accDescr: 当单元格代码发生变化时,Pluto 通过静态分析提取定义与引用,更新有向无环图,并同时处理旧作用域清理与拓扑重算。 Change["用户修改或删除了某个单元格代码"] --> StaticAnalysis["静态代码分析 (Static Code Analysis)"] subgraph DependencyAnalysis ["第一阶段:依赖推导与执行"] StaticAnalysis --> ExtractVars["提取每个 Cell 的定义变量 (Defs) 与引用变量 (Refs)"] ExtractVars --> GenDAG["构建/更新单元格有向依赖图 (Cell Dependency Graph)"] GenDAG --> TraverseDown["从修改节点沿依赖边向下游拓扑遍历"] TraverseDown --> RunCells["按拓扑序依次重新计算相关单元格"] end subgraph ScopeCleanup ["第二阶段:环境清理与作用域迁移"] StaticAnalysis --> TrackOld["比对旧代码提取需注销的符号<br/>(变量、常量、函数、模块导入)"] TrackOld --> ModuleMigration["放弃包含旧状态的旧 Module 作用域"] ModuleMigration --> RecreateScope["在全新的轻量级 Module 作用域中保留存活符号"] end ``` 在执行下游重算时,Pluto 面对多个单元格并不会盲目从上到下执行,而是先对代码进行静态语法分析,为每个单元格提取出两个关键集合:该单元格**定义了哪些变量**(Definitions)以及**引用了哪些变量**(References)。通过交叉比对全量单元格的定义与引用列表,Pluto 建立起一个精准的有向依赖图(Directed Dependency Graph)。一旦某单元格被触发修改,Pluto 便顺着依赖图从该节点自顶向下拓扑遍历,从而严格按照数据流的依赖顺序精准重新执行下游单元格。 --- ### [11:55](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=715s) 作用域清理:如何解决 Julia 无法删除变量的语言限制 Pluto 解决的另一个棘手挑战在于彻底清理“幽灵变量”。Fons 演示了一个经典场景:在一个单元格中定义 `potato =...` 并在另一个单元格中使用它;一旦删除了定义 `potato` 的代码,依赖它的单元格立即报错提示 `potato` 未定义。在 Pluto 中,这种清理能力不仅限于普通变量,还涵盖了常量(Constants)、多重分派函数定义(Functions),甚至通过 `using` 或 `import` 引入的外部模块——只要删除了对应的导入代码,该模块在当前笔记本命名空间中便不复存在。 从底层实现来看,这面临着 Julia 语言本身的设计限制:Julia 运行时的全局命名空间在设计上**不支持主动删除已定义的变量或符号**。为了绕过这一语言级约束,Pluto 巧妙地设计了一套作用域置换技巧: - Pluto 并不会将用户代码直接投掷在标准的全局 `Main` 作用域中,而是在底层动态创建一系列轻量级的工作区模块(Modules),所有用户变量和执行逻辑实际寄宿在这些受控模块内部。 - 当用户删除代码或更改定义、需要“销毁”某些变量时,静态代码分析系统首先比对出哪些符号已不复存在。 - Pluto 随后直接丢弃旧的宿主模块,平滑迁移到一个全新的模块作用域(New Scope)中,仅把当前屏幕代码所保留的有效变量迁移过来,将被废弃的变量和方法留在旧模块中,从而使失去引用的废弃变量自然被垃圾回收机制清理出有效作用域。 ### [13:17](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=797s) 响应式机制应对耗时单元格的插播答疑 演讲正要进入下一个主题时,一段幽默的插播对话打断了现场演示:一位名叫 Luka 的合作者带着担忧发来语音询问。Luka 表示自己在 Pluto 中建模时遇到了一些执行时间特别长的单元格,他非常担心一旦修改某个上游变量,Pluto 会盲目重新运行所有耗时单元格,从而导致极低的运行效率。 演讲者耐心地打消了他的顾虑,解释道 Pluto 具备精细的静态依赖分析能力:“No, don't worry about that, so Pluto figures out the dependencies of each cell, and it will only run the cells that actually need to be run.”(“不用担心这个,Pluto 能解析出每个单元格的依赖关系,并且它只会运行那些真正需要运行的单元格。”)如果用户有一连串细微修改要做,完全可以不逐一即时提交,而是将修改积累起来批量提交,Pluto 会智能地将其合并在单次运行中处理。 Luka 紧接着抛出了另一个常见场景:如果一个单元格被大量下游逻辑依赖,而用户事前并不清楚这一点,贸然运行导致长时间卡住怎么办?演讲者指出,用户随时可以手动中断执行。更进一步,Pluto 内部会记录每个单元格的耗时数据,团队正在开发针对依赖链的运行预估界面;一旦检测到所有下游单元格的总执行时间可能超过一分钟,系统便会在运行前主动弹出警告。 ```mermaid flowchart TD accTitle: Pluto Dependency Analysis and Execution Strategy accDescr: 流程图展示了当用户修改单元格时,Pluto 如何判断依赖链并选择性执行或预警 A["代码变更 / 单元格修改"] --> B{"静态依赖解析"} B -->|"非相关单元格"| C["跳过执行 / 保持缓存"] B -->|"下游依赖单元格"| D{"评估执行耗时"} D -->|"预估耗时较长 (>1分钟)"| E["发出 UI 耗时预警 / 支持中断"] D -->|"正常耗时 / 批量变更"| F["单次合并运行 (Batch Run)"] ``` --- ### [14:53](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=893s) Pluto 的交互模型与绑定机制(@bind) 演讲者将话题转回 Pluto 核心的交互能力。在 Pluto 中,单元格之间的响应式级联天然构成了一套交互环境。比如在一个单元格中定义变量 `s`,在下游单元格中计算 `s` 的平方;只要上游修改了 `s` 并执行,下游就会自动重新运算。创建这类交互式文档完全不需要掌握复杂的新编程范式,核心动作仅仅是把关键参数拆分到独立的单元格中定义。 为了让这种响应式能力无缝对接前端网页控件,Pluto 引入了 `@bind` 机制。其核心逻辑不再是将变量静态赋值为一个死数据,而是将变量绑定到某个 HTML 节点的最新状态。演讲者现场演示了一个文本输入框:在前端文本框中输入任意字符串,Julia 环境内部的变量 `s` 就会立刻更新为对应的字符串,所有用到 `s` 的下游单元格也会立即重新求值。 除基础文本框外,用户还可以绑定滑块(Slider)等各类表单输入。为了降低普通用户手写 HTML 标签的门槛,官方推出了 `PlutoUI` 工具包,将常用的交互控件(如范围在 1 到 500 的数值滑块)封装为开箱即用的 Julia 函数。 - 交互逻辑无需专用框架:拆分参数到独立单元格即获得天然交互性。 - `@bind` 核心语法:将 Julia 变量与 HTML DOM 节点的当前值建立实时双向数据流。 - 官方生态组件:通过 `PlutoUI` 提供标准化的输入框、滑块等前端交互部件。 --- ### [16:22](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=982s) 自定义 JavaScript 控件与 SVD 图像压缩演示 Pluto 的交互能力不仅限于标准的 HTML 控件。只要开发者掌握基础的 JavaScript,就可以在单元格中实现任何天马行空的自定义交互元素。演讲者首先展示了一个可手动画矩形选区的组件,当鼠标在画布上拖拽绘制时,`@bind` 会将矩形的实时尺寸数据回传给 Julia 会话。 为了进一步展示这种混合编程的魅力,演讲者展示了一个用于讲解奇异值分解(SVD, Singular Value Decomposition)的教学笔记本。他在笔记本中嵌入了一个调用本地摄像头的控件: 1. 点击拍照按钮后,前端图像数据被直接 `@bind` 映射为一个 Julia 二维数组,每个元素对应一个像素的黑白灰度值。 2. 在下游单元格中,直接对该矩阵做矩阵切片或调用 Julia 标准线性代数库执行 `svd()` 分解。 3. 紧接着,演讲者将前 $k$ 个奇异对的重构过程绑定到了一个动态滑块上。 随着滑块从 1 滑动到 10,文档中的图像从模糊的低秩近似逐渐过渡到清晰的人脸轮廓,直观呈现了 SVD 图像压缩的数学本质。演讲者提到,虽然编写该摄像头组件需要写一些 JavaScript 代码,但他已经将该功能打包进了 `PlutoUI`,普通用户无需了解 JavaScript 或 HTML 细节也能直接调用。对于绝大多数日常交互,用户只需将参数抽离为独立单元格即可。 --- ### [18:11](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=1091s) 极简的文件格式(.jl 纯文本)与版本控制优势 在文件存储格式的设计上,Pluto 采取了与传统 Notebook 系统截然不同的哲学:追求极致的轻量与极简,只保存单元格的源代码,坚决不持久化输出结果。在分屏演示中,左侧是运行中的 Pluto 笔记本界面,右侧是用普通文本编辑器打开的底层存储文件。整个示例笔记本在文本编辑器中仅仅占用 16 行代码,并且支持编辑过程中的实时自动保存(Auto-save)。 由于存储文件本质上就是一个标准的 `.jl` 纯文本 Julia 脚本,它具备了一系列强大的工程特性: - **终端与脚本直跑**:无需任何预处理,直接在命令行执行 `julia notebook.jl` 就能正常跑完。 - **REPL 与跨文档复用**:可以直接在 Julia REPL 或另一个笔记本中通过 `include("notebook.jl")` 载入代码,并直接访问其中定义的变量与函数;在教学场景下,教师可以写一个批改脚本,用循环 `include` 的方式逐个评测学生的作业文件。 - **拓扑排序保存**:因为 Pluto 允许用户在界面上按任意顺序排布单元格,在落盘为 `.jl` 文件时,Pluto 会根据依赖图谱自动将上游单元格排在前面(拓扑排序)。同时在文件末尾通过一个 UUID 列表记录前端的展示顺序,兼顾了脚本执行的依赖正确性与界面的排版还原。 - **干净的 Git Diff**:由于不保存图表、富文本和渲染输出,在执行 `git diff` 时,用户看到的每一行变动都精准对应实际修改的代码本身,彻底告别了传统笔记本在版本管理中动辄几千行 JSON 输出变动的噩梦。 ```mermaid flowchart LR accTitle: Dual Structure of Pluto jl Storage File accDescr: 流程图展示了 Pluto jl 文件内部如何兼顾执行依赖拓扑与界面 UI 顺序 subgraph File[".jl 单文件存储"] direction TB subgraph Topo["按依赖拓扑排序的代码段"] C1["Cell A (无前置依赖)"] C2["Cell B (依赖 Cell A)"] end subgraph Meta["尾部元数据"] Order["Cell UUID 界面显示顺序映射表"] end end Topo -->|"支持无依赖执行"| CLI["julia runner.jl / REPL include"] Meta -->|"还原用户编排视图"| UI["Pluto 前端界面"] ``` --- ### [20:45](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=1245s) 总结与未来展望:云端免配置分享与教育实践 演讲者对 Pluto 的核心特质进行了总结:一个纯 Julia 编写的、天生响应式的轻量级笔记本系统,代码直接保存为标准 `.jl` 文件,开箱即具备全响应式交互能力。它零繁琐依赖,用户只需在 Julia REPL 中执行 `using Pkg; Pkg.add("Pluto")`,随后 `import Pluto; Pluto.run()` 即可在浏览器启动。 关于项目后续的演进路线,演讲者重点分享了两个核心规划: 1. **零门槛的一键交互式 Web 分享**:目前 Pluto 支持将笔记本静态导出为 PDF 和 HTML,但团队的终极目标是导出可在线运行的交互式笔记本。用户无需具备复杂的云计算或容器编排技能,就能一键将笔记本部署到免费的轻量服务器(如 Heroku)并生成分享链接。为了实现这一目标,团队正在将环境管理(Package Environment)与笔记本文件本身进行内聚绑定。 2. **重塑编程与数学教育工作流**:“So next I want to make Pluto a very accessible tool for students and teachers. I think especially new programmers can benefit the most from an accessible programming environment.”(“接下来我想让 Pluto 成为面向学生和教师的极易上手的工具。我认为尤其是编程初学者,能从一个易于访问的编程环境中获益最多。”) 在教育场景的实际演示中,演讲者展示了一个求解黄金分割比例的练习单元格:当学生尝试输入公式时,下游单元格立刻响应式判断并给出提示“Oops, the golden ratio should be positive”(“哎呀,黄金分割比应当为正数”);当学生将减号修正为加号后,界面随即判定正确。这种实时反馈极大地降低了学习挫败感。对于教师而言,基于纯 `.jl` 文件的特性编写自动化评分(Autograding)脚本也变得极其简单。 在接下来的学期中,团队计划在柏林工业大学(TU Berlin)以及麻省理工学院(MIT)开展实地教学试点,演讲者本人也会亲临现场收集师生反馈。试点经验将进一步沉淀为编写教学材料的最佳实践指南、示例库、视频教程,以及包含选择题组件与自动批改支持的教育辅助扩展包。演讲在观众的掌声与引用致谢中圆满结束。 ## Notable quotes > [09:50](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=590s) At any instant, the program state is completely described by the code you see. — Fons van der Plas > [00:19](https://www.youtube.com/watch?v=IAF8DjrQSSk&t=19s) Programming itself is easy, but these languages are so powerful that if you're still using these environments from 50 years ago, it feels like you are blindly manipulating symbols. — Fons van der Plas ## Mentioned Pluto.jl, Fons van der Plas, Nick, Luka, Julia, Jupyter Notebook, Observable, Google Colab, Scratch, Plots.jl, PlutoUI, Git, Heroku, 麻省理工学院 (MIT), 柏林工业大学 (TU Berlin) ## Video description Introducing a fresh, new notebook system for rapid prototyping! Pluto understands global references between cells, and reactively re-evaluates cells affected by a code change. At JuliaCon, we will show how Pluto can liven up your workflow. Whether you’re a scientist, a finance professional or an engineer, you use notebooks like Jupyter to tell a story. You fiddle a bit with your code, running cells here and there, and when you’re done - you restart the kernel and keep your fingers crossed that it’ll all work together when you press “run all”. 🙋 In Pluto, things work differently. When you change a variable, Pluto automatically re-runs the cells that refer to it. And when you delete a cell, the variables, methods and imports from the old code disappear. Unlike Jupyter or Matlab, there is no mutable workspace, but rather a one-to-one correspondence between variables and code. 🚨 Reactivity is not just fun for mathematical tricks! It guarantees that the code you see exactly matches the variables you're working with, eliminating bugs before you even knew you had them. ⚡ Your notebook becomes interactive by splitting your code into multiple cells! Changing one cell instantly shows effects on all other cells, giving you a fast and fun way to experiment with your model. And to really spice up your notebook, you can use HTML sliders, or even custom JavaScript widgets, to drive your Julia variables. Change λ = 5 to @bind λ Slider(1:10), and all cells that use λ are controlled by a slider. 💾 Notebooks are saved as pure Julia files and can be exported as rich documents with cell output to HTML or PDF. By separating source code and output, you can take full advantage of git for version control and you can import Pluto notebooks as if they are written in a regular editor. After a live demo, the second part of the talk will unveil some of the tricks that power Pluto. The core concepts are: - static code analysis to find global definitions and references in cells; - directed graph of cells, which tells Pluto which cells to run, in which order; - managed workspace for code to live in, and cleaning the workspace in milliseconds; - responsive connection between JavaScript clients and Julia. Pluto is written in pure Julia, which comes with two benefits: first, it’s easily installable as a package without requiring Python - you only need Julia and a web browser. Second, it is ready to be improved by Julia developers who we hope to inspire at the conference. Pluto is an exciting project to work on, and we are eager to hear your ideas! Resources Pluto.jl home page: https://plutojl.org/ Pluto.jl repository: https://github.com/fonsp/Pluto.jl Contents 00:00 Opening 00:19 Introduction 00:42 Why we made Pluto? 01:06 Programming is easy, programming languages are powerful, but our environments are 70s vintage 01:47 Jupyter notebooks: strong points and pain points 02:23 Alternatives to Jupyter 03:09 Enter Pluto. Live demo 06:00 Pluto doesn't allow multiple expressions in one cell, here is why 07:50 Binding value variable to slider 08:33 Markdown cells in Pluto 09:50 Reactive paradigm 10:35 Taking look behind scene on how reactivity works 11:05 I. Re-evaluating downstream cells 11:55 II. Clean up old code 13:25 Call about re-evaluating cells, which have a long evaluation time 14:53 Interactivity in Pluto 16:22 Using JavaScript you can make any interactive element you want 16:44 Example: using your picture to define matrix (two dimensional array) 17:21 Manipulation picture inside Pluto 17:47 Do you need to know JavaScript and HTML? 18:11 Pluto.jl minimalist file format 20:45 Recapitulation 21:03 What's next? 21:54 Pluto for education 23:23 Thank you! Want to help add timestamps to our YouTube videos to help with discoverability? Find out more here: https://github.com/JuliaCommunity/YouTubeVideoTimestamps Interested in improving the auto generated captions? Get involved here: https://github.com/JuliaCommunity/YouTubeVideoSubtitles [Source](https://www.youtube.com/watch?v=IAF8DjrQSSk)

Source quotes

[9:50] Fons van der Plas: At any instant, the program state is completely described by the code you see. [0:19] Fons van der Plas: Programming itself is easy, but these languages are so powerful that if you're still using these environments from 50 years ago, it feels like you are blindly manipulating symbols.

Source quotes

[9:50] Fons van der Plas: at any instant the program state is completely described by the code you see and this is guaranteed to be true at any point during your process with your notebook. [13:17] Fons van der Plas: Pluto figures out the dependencies of each cell and it will only run the cells that actually need to be run. [20:45] Fons van der Plas: What you really want is to be able to export these fully interactive notebooks, so send someone a link where they can play with your notebook directly in the browser.

Original transcript

[0:03] [Music] [0:19] hi [0:20] my name is fonz this is nick and we are [0:22] working on [0:24] one second [0:27] let's make this zero [0:30] there we go we are working on pluto it's [0:34] a new interactive notebook system for [0:36] julia [0:37] today you'll get a demo a look behind [0:39] the scenes but first [0:40] why did we make this so one thing i [0:44] worked on [0:44] is teaching programming at elementary [0:46] schools we used a bunch of cool tools [0:48] like on the left you have this [0:50] robot that can follow a line and your [0:52] script is essentially the line that you [0:54] draw on paper [0:56] we also use scratch where you have these [0:59] visual programming languages [1:00] that you interact with and there are [1:02] basically no more syntax errors in this [1:04] language [1:06] so what we found is that teaching [1:08] programming is actually easy you can [1:10] teach programming to an age world in [1:12] about a week [1:13] but then at university programming is [1:16] hard [1:17] how come well the programming that we do [1:20] is more general we use [1:21] scripts that are more expressive and we [1:24] create abstractions and that's how we [1:25] share [1:26] our programming so [1:29] programming itself is easy but these [1:31] languages are so powerful [1:34] that if you're still using these [1:36] environments from 50 years ago it feels [1:38] like [1:39] are blindly manipulating symbols [1:42] so we need a friendly environment to [1:44] help us with this powerful language [1:47] in scientific computing one such [1:49] environment is jupiter notebooks [1:52] so the strong points here is that it's [1:54] interactive [1:55] you basically have a rebel with the [1:57] input and output stretch across the page [2:00] and you have your code your output and [2:02] format attacks all in the same document [2:05] once you start using it more you find [2:06] these pain points like [2:08] the persistent global scope variables [2:10] you define once live on forever [2:12] and the file format includes output [2:14] which makes versions [2:15] a little difficult to use and if you [2:18] write a notebook on one machine [2:19] it will probably not work on another [2:21] machine [2:23] so what are the alternatives well you [2:26] have these cloud-based notebooks i [2:27] google colab [2:29] and they do solve technical problems [2:31] like reproducibility [2:33] but what bothers me the most is that [2:35] they still make no improvement to the [2:37] programmer environment [2:38] it's still the same concepts now [2:42] when you look at other areas for [2:44] javascript [2:45] you have all these new environments [2:47] including observable [2:49] which introduces this new paradigm the [2:51] reactive notebook [2:53] and there you see that these very smart [2:54] editors they [2:56] it feels like you're working together [2:57] with your computer instead of shouting [2:59] at each other [3:01] but now the problem here is that you're [3:03] using javascript [3:04] which is not a scientific language so [3:09] this is why we decided to make pluto a [3:11] new notebook system [3:12] that's based on these new concepts but [3:15] now applied to julia [3:16] let's go over to nick who has a cool [3:18] demo [3:20] alright let's get started with a demo so [3:23] the first thing you're going to want to [3:24] do is download pluto so let me just [3:26] quickly do that now [3:32] all right we're here so what you're [3:34] seeing right now is the [3:35] pluto ui you have a browser um the very [3:39] basics [3:39] are quite typical for any notebook [3:42] system [3:42] uh so you write your code in cells [3:47] and each cell should be an expression [3:50] which is then displayed [3:54] in pluto's case above cell [3:57] but watch what happens when i change the [4:00] value of b [4:00] over here bam [4:04] the dependent cells are automatically [4:06] updated this is our main [4:07] point of pluto we're going to be talking [4:09] about it a lot later it's called [4:11] reactivity [4:12] and we believe that it helps you uh [4:16] explore your ideas quicker [4:19] but uh we're not here to be talking [4:22] about [4:22] a's and b's we are actually here to be [4:25] exploring [4:26] title patterns um so let's load up [4:29] a csv file that's i've preferred earlier [4:36] it's actually can you load up a csv file [4:40] just by the name well [4:43] let's find out pluto has built in live [4:46] docs [4:47] which can answer this question for us [4:49] and in this case [4:50] the source can be just a file name all [4:53] right [4:54] let's go so we've gotta get data for [4:56] cache cache [4:57] uh which is near lisbon portugal [5:01] and with pluto's preview we can see that [5:04] our data has been loaded correctly [5:06] all right great um maybe let's put that [5:09] in a variable [5:12] um now that we have a variable we can [5:15] start playing with it so [5:16] um let's extract the hours and c levels [5:20] into [5:20] separate variables so the hours are [5:22] going to be the first [5:24] um the c levels [5:28] are going to be last [5:35] here we go um [5:38] alright it's great uh maybe it would be [5:40] appropriate to plot it [5:41] um so pluto works out of a box [5:45] with plots jl um as one would expect [5:49] indeed from a notebook system [5:54] um oops thankfully [5:58] yay okay um so you can see that our data [6:01] is loaded [6:02] in indeed it looks quite periodic so [6:05] maybe we could try modeling that's with [6:07] a sine wave [6:08] well let's find out [6:12] um let's add another plot with the sine [6:16] of times [6:19] oops so pluto doesn't allow for [6:23] multiple expressions per cell the reason [6:26] for that being that we're displaying [6:28] of the results of evaluating the [6:30] expression that is in a cell [6:32] above that cell so it wouldn't make much [6:33] sense with multiple expressions [6:35] also we just think that leads to cleaner [6:38] code but [6:39] i can just click this and pluto will fix [6:41] it for me [6:43] alright so this isn't exactly perfect [6:47] model but maybe [6:48] if we add a [6:52] period um it's going to be better [6:56] so if i know my mathematics that's going [6:58] to be 2 [6:59] times pi divided by period [7:03] but of course period is not defined [7:06] let's define it over here [7:07] periods is uh it looks like [7:11] 12 ish hours hey that's [7:15] that's actually quite a good guess i [7:16] would say i'm proud of myself [7:19] um all right all right uh we're also [7:22] going to need a phase [7:24] if we're uh planning to model anything [7:28] so same thing goes for the face [7:31] phase equals i'll let it make it zero [7:35] for now [7:36] all right um i think the beard should be [7:41] slightly [7:43] higher maybe 13. ooh this is quite close [7:47] but it's not perfect it's not perfect [7:49] actually [7:50] something we can do something that pluto [7:52] lets us do is bind the value of periods [7:55] to an html input element [8:00] let me show you how to do that right now [8:02] uh [8:03] inputs uh type range [8:08] for minimum well i guess [8:11] let's make it 11 from maximum let's make [8:14] it [8:15] 14 and the step should be rather small [8:20] and here we go we have a slider for [8:23] periods [8:24] um we can [8:27] experiment with our data live isn't that [8:30] cool [8:31] um but something more we can do uh let's [8:34] for prettiness uh just make a markdown [8:37] cell which in pluto is just a regular [8:39] cell [8:40] aspecting markdown um [8:43] which is going to tell us what the [8:44] period is [8:47] periods hours here we go [8:51] 12.38 hours and let's do a similar thing [8:55] for [8:55] face [9:00] face maybe between negative three and [9:04] three [9:05] that should be fine [9:12] and here we go we have a quite good [9:14] model for our data [9:16] but is it universally good well [9:20] there is a way to find out uh thanks to [9:23] pluto's reactivity we can just [9:25] replace kashkaish over here with [9:28] catania and [9:32] live updated the data for catania [9:35] appears [9:36] we see that our model is actually doing [9:38] really well [9:39] but i think we should add uh [9:43] an amplitude in a later episode [9:47] thank you for being with me [9:50] right so there was a lot going on in the [9:52] demo but one of the most important [9:54] things about pluto is this reactivity [9:57] and pluto is this reactive notebook and [10:00] what it means at a higher level is that [10:03] at [10:03] any instant the program state is [10:05] completely described by the code you see [10:07] and this is guaranteed to be true at any [10:10] point during your process with your [10:11] notebook [10:13] in particular it means that the program [10:14] state is not described by the code you [10:16] had on your screen an hour ago [10:19] variables that you defined before they [10:21] don't live on forever [10:23] so we think it's not just cool for [10:26] nice demos but it's actually it will [10:29] help you prevent a lot of bugs from [10:31] happening in the first place [10:34] so most people will never have to think [10:36] about how this works [10:37] but today we'll take a look behind the [10:39] scenes so whenever you change a cell [10:42] pluto does two things [10:43] so first it figures out which cells also [10:46] need to run [10:47] and it does so using a dependency graph [10:49] between your cells of the notebook [10:52] and the second thing is that it cleans [10:54] up scope effects [10:55] from your old code so if you define a [10:57] variable x [10:58] and then you delete that code or change [11:00] that code then the variable x will also [11:02] get deleted [11:06] so the first thing is this reactive [11:08] reevaluation [11:10] and say that you are pluto and you have [11:12] these three cells [11:14] and now the question is in which order [11:16] do these three cells need to run [11:19] and so they have dependencies between [11:21] them so [11:22] not any order is correct so the first [11:25] thing we do is we do static code [11:27] analysis [11:28] and for each cell we figure out which [11:30] variables are defined [11:31] and which variables are referenced in [11:33] that cell and we make these [11:35] lists and next by comparing these lists [11:38] you get the dependency graph between [11:40] your cells and [11:42] now step two is whenever you change the [11:44] cell pluto will go [11:47] from that cell down the graph and that's [11:48] how it figures out which cells are [11:50] dependent and in which order to run them [11:56] so next pluto cleans up old codes [11:59] for example if i define potato [12:04] and use it here now when i delete this [12:06] code [12:08] you see that potato is actually not [12:10] defined anymore [12:12] and so it's not just variables it's also [12:16] constants that it can delete [12:19] or functions [12:26] and even when you import a module [12:34] and you take away that imports the [12:37] module is no longer defined in your [12:38] notebook [12:40] and so um how does this work it's [12:43] actually the same code analysis as [12:45] before that tells us [12:46] which variables used to be defined and [12:48] so which variables do delete [12:51] and julia you cannot delete variables [12:54] in julia but what you can do is kind of [12:58] trick you so there's a number of ways to [13:01] do it but what we do right now is we [13:03] create a bunch of modules and variables [13:05] actually live inside those modules [13:07] and whenever we need to delete something [13:09] we move over to a new scope [13:12] and leave some variables behind and [13:14] actually [13:15] variables get the reference when they're [13:17] left behind so that they can be garbage [13:19] collected [13:21] right so that's how reactivity works [13:24] and next we'll actually take a oh wait [13:28] [Music] [13:30] oh hey luka uh i'm kind of in the middle [13:32] of something but what's up [13:34] uh it's fine i just have a quick [13:36] question i'm working on a model at pluto [13:38] and uh i have a few cells to take a [13:41] really long time to run [13:43] so i'm worried that every time i change [13:44] a variable it will run all those cells [13:46] again and that seems really inefficient [13:49] um [13:50] no don't worry about that so pluto [13:53] figures out the dependencies of each [13:55] cell and it will [13:56] only run the cells that actually need to [13:59] be run [14:00] and also if you have a cell which takes [14:02] a long time to run [14:04] um then you can do all your mini changes [14:07] uh and just not commit them immediately [14:09] instead of um [14:10] commit them all at once and pluto is [14:12] smart enough to figure out that it [14:13] should run it all in one batch [14:16] oh okay that's nice um so what if i have [14:19] a cell [14:20] and a lot of stuff depends on it but i [14:21] didn't know that so i run it and it [14:23] takes really long time [14:25] right so you can always stop execution [14:28] of course but um [14:29] so so pluto knows how long cells take to [14:32] run [14:33] and we're working on some user interface [14:35] that will [14:36] also tell you how long all of the [14:37] dependent cells take to run [14:39] and maybe if it takes over a minute or [14:41] something it can warn you [14:44] okay oh that's awesome thank you now i [14:46] can get back to work [14:48] cool see you ciao [14:53] right so that's how reactivity works now [14:55] let's have a look again at [14:57] interactivity in pluto cells react to [14:59] each other [15:00] and this actually makes it this [15:02] interactive environment [15:04] for example here i'm defining s and then [15:06] here it says s has a squared square of [15:08] square square s so whenever i change s [15:11] and run the cell [15:13] the second cell runs as well because of [15:14] this reactivity [15:16] and this makes it very easy to create [15:18] these interactive [15:20] fun documents without needing to know [15:22] any [15:23] new programming techniques the only [15:25] thing you do is you take your parameter [15:26] and define it in a different cell [15:28] and so with this idea pluto has one [15:31] feature which is binds [15:33] instead of defining s to be something [15:35] you say [15:36] i'd find has to be the latest value of [15:41] this html node and so now we're taking [15:44] an [15:44] input node and whenever i type something [15:47] here [15:48] you see that it runs the second cell as [15:50] well with this value of s [15:51] and so s is now available inside julian [15:54] when we look at s it's the string and it [15:57] updates whenever we type [15:59] you can also use different types [16:03] here's the slider [16:08] and to make all this html stuff a bit [16:11] easy we have a package called pluto ui [16:14] and it has all of these which it's like [16:16] the slider [16:17] from one until 500. and so it's not just [16:22] these basic html elements [16:24] and you can actually like if you know [16:26] javascript you can actually make [16:27] anything you want for example here i [16:30] made a thing where you can draw a [16:31] rectangle [16:33] and what it sends back with this bind is [16:37] the dimensions of the rectangle that you [16:39] were drawing you can see that it updates [16:40] well [16:41] while i do this for a more fun example [16:46] i'm writing this notebook where i'm [16:48] trying to explain the singular value [16:50] decomposition [16:51] and so there's my face and when i take a [16:54] picture [16:57] it actually binds the image data to [17:00] this array so it's a 2d array that for [17:03] each pixel has the black and white value [17:06] and so i can use it like to be arrayed [17:09] like take [17:10] take top corner of it and i can do the [17:13] singular value decomposition of that [17:14] array [17:17] don't worry if you don't know what the [17:18] svd is [17:20] um so here um you [17:23] see the first 10 singular pairs [17:26] added together and actually is number 10 [17:29] i bound to [17:30] a slider so now you can kind of slide [17:32] around and see this compression [17:34] kick in [17:39] here i took the first 20 and [17:42] it's just an array so i can click and [17:44] kind of go through [17:46] and so for this i needed to know some [17:48] javascript to write this but [17:51] this webcam i'm putting it in bluetooth [17:53] ui so that you can use it as well [17:56] but in general you don't need to know [17:58] any javascript [17:59] html for these simple interactions what [18:02] you do is you take your parameters and [18:03] move them something [18:04] somewhere else in a different cell and [18:07] that's the entire [18:08] concept for the file format we wanted [18:12] something minimal [18:13] and we wanted to only save the code that [18:15] you write inside cells and not the [18:17] output [18:19] to demonstrate this on the left there's [18:21] a small notebook and on the right [18:23] there's the same notebook again but now [18:25] using a text editor [18:26] and so this notebook can be saved in [18:30] these 16 lines [18:31] so it's very small for small notebooks [18:34] and the first thing is that it actually [18:36] auto saves so [18:38] when i change my codes you see that it [18:42] oops you see that it instantly also [18:45] changes the file [18:48] and so first because this is a julia [18:51] file we can actually run it [18:53] using julia so this is the notebook file [18:56] which we actually save as dot jl because [18:58] they're just julia files [19:00] and it works it doesn't print anything [19:02] because [19:03] we didn't do any print statements there [19:06] but if we [19:07] include it inside the repel you can see [19:10] that i can actually use those variables [19:13] from the notebook and so it's not just [19:15] including inside [19:16] repo it's you can include one notebook [19:19] in the other notebook or [19:20] if you're students you can test your [19:24] students homework one by one just by [19:25] including those 2df files [19:28] and so that's fun but if you make it a [19:30] bit more complicated for example we [19:32] define [19:33] potato to be melon times three [19:38] you see that of course that's legal [19:39] because with the reactivity you're [19:41] allowed to put your cells in any order [19:44] and then the file it actually moves this [19:46] first cell to the bottom [19:48] because the first cell is dependency of [19:50] the second cell [19:52] and so using these identification [19:54] strings [19:55] it actually has all those ids again a [19:57] second time [19:59] and that's how it knows in which order [20:00] you actually want these notebooks to be [20:02] so these cells to be in your notebook [20:06] um and so this is nice for including [20:10] your script somewhere else [20:12] but it's also nice because now you can [20:14] use git for version control [20:16] without getting these enormous dips [20:19] for example um here i have a [20:22] git diff from a notebook where [20:26] there were a bunch of changes but [20:28] everything you see in the kit tip is [20:29] just exactly what you [20:31] actually changed to your code the output [20:33] also changes a lot but output is not [20:35] inside this file [20:36] and so yeah that's it a minimal file [20:40] format [20:42] which is also fast enough that it can do [20:44] auto saving [20:46] so we have a notebook system that is [20:47] reactive your notebook is stored as a [20:49] gdf file and everything is interactive [20:52] it's available in github written in [20:54] julia [20:55] it has minimal dependencies and it's [20:57] easy to install you just [20:59] add pluto import pluto.run [21:03] so what's next uh we have a lot of plans [21:06] but i'll tell you about two of them [21:07] today so first [21:09] right now you can export to pdf and html [21:13] it kind of looks like this but what you [21:16] really want is to be able to export [21:18] these fully interactive notebooks so [21:20] send someone link where they can play [21:22] with your notebook directly in the [21:24] browser [21:25] and this kind of works today if you run [21:28] the pluto server uh [21:30] at an online server but we want this to [21:33] be possible without these web [21:35] architecture skills [21:37] and it should be free and we [21:40] think this should be possible uh because [21:43] it is so lightweight that it can run on [21:45] this free heroku server [21:47] but it's not one click yet and part of [21:49] this is making [21:50] the package environments part of the [21:52] notebook [21:54] so next i want to make pluto a very [21:58] accessible tool for students and [21:59] teachers i think especially new [22:01] programmers can benefit the most [22:03] from an accessible programming [22:05] environment [22:06] so for students it's easy to install and [22:08] they can get live feedback [22:10] because of this reactivity for example [22:12] here i have an exercise to write [22:15] an expression for the golden ratio and [22:18] i might remember that it's something [22:20] like this [22:22] all right and it says oops the golden [22:25] ratio should be positive [22:27] it's like ah okay this was a plus [22:31] and there you go it's correct and so uh [22:34] yeah for teachers [22:36] pluto can help you write more engaging [22:38] course material [22:40] and also because these notebooks are [22:43] julia files [22:44] it makes autograding easier because you [22:46] can just run all the notebooks in a [22:47] script [22:49] so the plan is in the upcoming semester [22:51] to do some trial runs [22:52] theo theobilin and mit and i'll actually [22:55] be there myself [22:56] taking questions from students and [22:58] teachers [22:59] and what we learned there will go into [23:03] guides for writing course material like [23:05] more sample notebooks and some video [23:07] tutorials [23:08] and also maybe a package with some [23:10] useful widgets like what i have [23:12] on the bottom here or maybe multiple [23:14] choice questions [23:16] and these other grading tools and so if [23:19] you're interested [23:20] do get in touch and yeah [23:23] that's it thanks um if you go to our [23:26] github page there'll be a link [23:28] on how you can contact us and i'll leave [23:30] you all with a quote from [23:31] matt hubert ciao yay thank you