Classic Problem: Dynamic Software Updating, Hot Swapping, etc.
Desired behavior after code updates
Data might need to be updated along with code
var i = 0;
function inc() { i++; }
inc(); i+=2;
console.log(i);
Where does inc()
return to?
<div>
<button>Click Me</button>
<span>Count: 0</span>
</div> Clicks:
<script>
var i = 0; "mouseover"
$("button").on("click", function() {
$("span").html("Count: " + (++i));
}); "Clicks: "
</script>
<div>
<button>Click Me</button>
<span>Count: 0</span>
</div>
<script> (i,n)
function mkCounter(i) { i+=n
return function() { return ++i; };
} (0,2)
var counter = mkCounter(0);
$("button").on("click", function() {
$("span").html("Count: " + counter());
});
</script>
<div>
<button>Click Me</button>
<span>Count: 0</span>
</div>
<script>
var i = 0;[];
$("button").on("click", function() {
i.push(Date.now());
$("span").html("Count: " + (++i));i.length);
});
</script>
Single-threaded event loop (e.g. JavaScript)
⟶ No Active Call Stack or Program Counter
init :: () ⟶ State
handle :: Event × State ⟶ State
render :: State ⟶ Output
render
should not change statevar i = 0;
function inc() { i++; }
function render() {
return (
<div>
<button onclick={inc}>Click Me</button>
<span>Count: 0{i}</span>
</div>);
}
Code gets parsed, checked, rewritten and evaluated upon each change
Rewriting turns global references to access a managed state object
function inc() { i++; }
⟶ function inc() { ENV.state.i++; }
Variable initializations will be extracted to an init
function
var i = 0;
⟶ function init() { ENV.state.i = 0; }
JSX (JavaScript with inline-XML) will be expanding to regular JavaScript (other ways of generating HTML would work equally well)
var i = <p>Hello!</p>;
⟶ var i = {type: 'p', children: ['Hello!']};
After each event,
render
is called with an immutable clone of the stateObject.freeze
)UI for accessing previous code versions and states
Github Repository: https://github.com/levjj/rde/
Online Live Demo: https://levjj.github.io/rde/
Challenge | Proposed Solution | |
---|---|---|
Updating running functions | Use single event loop to update code | ✓ |
Outdated visual feedback | Seperate rendering from event handling | ✓ |
Updating function values/closures | Restrict application state | ! |
Inconsistencies between state and code | Programmer may need to restart | ✗ |
Enables live programming, time travel and continous feedback
Implemented in JavaScript but works for any event-based language
Restricting function values in the state may be too strong (e.g. OOP)
Use programming language features to ...
Improve tool support, e.g. programming by example
Smalltalk/Squeak
Elm
React/Redux
var i = 0;
var dom = (
<div>
<button onclick={inc}>Click Me</button>
<span>Count: 0</span>
</div>);
function inc() {
dom.find('span').html = 'Count: ' + (++i);
}
function render() { return dom; }