Livecoding in Javascript

Livecoding in Javascript

3f51727357dd2eeb7fbb59993e0fca29?s=128

Jason Frame

May 09, 2013
Tweet

Transcript

  1. Livecoding in Javascript Jason Frame / @jaz303 Friday, 31 May

    13
  2. What is livecoding? By akirto. http://www.flickr.com/photos/30132612@N00/3840200923/in/photostream Friday, 31 May 13

  3. Performance-Oriented Friday, 31 May 13

  4. Node-based Friday, 31 May 13

  5. Microworlds Paper - “Twenty Reasons Why You Should Use Boxer

    (Instead of Logo)” Andrea A. diSessa Friday, 31 May 13
  6. Smalltalk, Self Paper - “The Early History of Smalltalk” Alan

    C. Kay Friday, 31 May 13
  7. Why livecode? Friday, 31 May 13

  8. Why Javascript? Friday, 31 May 13

  9. Why Javascript? • Flexible language • Ecosystem - browser +

    node.js = node- webkit • Single threaded • Event loop Friday, 31 May 13
  10. Why Javascript? Describing Live programming using program transformations and a

    callstack explicit interpreter Olov Johansson Friday, 31 May 13
  11. Domain-Specific Livecoding • Generalised tools can be complex • May

    also make unacceptable performance/ timing trade-offs • Evolve tools with your application Friday, 31 May 13
  12. Demo Time Friday, 31 May 13

  13. Friday, 31 May 13

  14. Implementation Strategies Friday, 31 May 13

  15. Implementation Strategies eval() is evil Friday, 31 May 13

  16. Implementation Strategies eval() is evil Friday, 31 May 13

  17. Implementation Strategies • Private State • Variable Injection • “Globals”

    Preservation • Internal eval() • Blueprints • Snapshot • Clocksources Friday, 31 May 13
  18. Private State Prevent pollution of global namespace Friday, 31 May

    13
  19. Private State function setup() { position = {x: 10, y:

    20}; velocity = {x: 1, y: 1}; } function loop() { position.x += velocity.x; position.y += velocity.y; } Friday, 31 May 13
  20. Private State (function() { “use strict”; var position; var velocity;

    function setup() { position = {x: 10, y: 20}; velocity = {x: 1, y: 1}; } function loop() { position.x += velocity.x; position.y += velocity.y; } })(); Friday, 31 May 13
  21. Private State (function() { “use strict”; var position; var velocity;

    function setup() { position = {x: 10, y: 20}; velocity = {x: 1, y: 1}; } function loop() { position.x += velocity.x; position.y += velocity.y; } return { setup: setup, loop: loop }; })(); Friday, 31 May 13
  22. Variable Injection Provide objects to user-code Friday, 31 May 13

  23. Variable Injection function loop() { car.drawAt(0,0,50,50) } // ... //

    ... // ... Friday, 31 May 13
  24. Variable Injection // Generate method signature from defined // objects

    (function(car, trafficLights, background) { // Paste user code here function loop() { car.drawAt(0,0,50,50) } // ... // ... // ... }).apply(null, exposedObjects); Friday, 31 May 13
  25. “Globals” Preservation Persist global values between code reloads Friday, 31

    May 13
  26. “Globals” Preservation var carX = 0; var carY = 0;

    var speed = 5; function loop() { carY += speed; draw(); } Friday, 31 May 13
  27. “Globals” Preservation var carX = 0; var carY = 0;

    var speed = 5; function loop() { carY += speed; draw(); } Friday, 31 May 13
  28. “Globals” Preservation (function() { "use strict"; var carX = 0;

    var carY = 0; var speed = 5; function loop() { carY += speed; draw(); } return { loop: loop, getVars: function() { return {carX: carX, carY: carY, speed: speed}; }, setVars: function(vars) { carX = vars.carX; carY = vars.carY; speed = vars.speed; } }; })(); Friday, 31 May 13
  29. Internal eval() Provide external (e.g. console) access to private state

    Friday, 31 May 13
  30. Internal eval() var car = {x: 20, y: 20} var

    lightState = “red-amber” function setup() { // ... } function loop() { // ... } Friday, 31 May 13
  31. Internal eval() (function() { "use strict"; var car = {x:

    20, y: 20} var lightState = “red-amber” function setup() { // ... } function loop() { // ... } })(); Friday, 31 May 13
  32. Internal eval() (function() { "use strict"; var car = {x:

    20, y: 20} var lightState = “red-amber” function setup() { // ... } function loop() { // ... } function evaluate(code) { return eval(code); } return { __eval__: evaluate } })(); Friday, 31 May 13
  33. Blueprints Augment a supplied object with user-code Friday, 31 May

    13
  34. Blueprints // Inside engine var blueprint = new SystemBlueprint(); blueprint.id

    = oldSystem.id; blueprint.enabled = oldSystem.enabled; blueprint.update = function() { /* default impl */ } USERCODE = ‘(function(system) { // augment blueprint system.title = “foo”; system.update = function() { ... } })’; // Compile code systemBuilder = eval(USERCODE); systemBuilder(blueprint); // inspect user’s refinements to blueprint and // setup accordingly Friday, 31 May 13
  35. Snapshots Save and restore entire application state Friday, 31 May

    13
  36. Snapshots system.snapshot = function() { return { entities: Object.keys(this.entities), lastShotTime:

    this.lastShotTime } } system.restore = function(snapshot) { var self = this; this.entities = {}; snapshot.entities.forEach(function(eid) { self.entities[eid] = self.world.getEntityById(eid); } this.lastShotTime = snapshot.lastShotTime; } Friday, 31 May 13
  37. Snapshots function updateSystem(registry, systemId, newSystem) { var existingSystem = registry.getSystemById(systemId);

    var snapshot = existingSystem.snapshot(); try { newSystem.restore(snapshot); registry.setSystem(systemId, newSystem); } catch (e) { // Incompatible snapshot - restart app? } } Friday, 31 May 13
  38. Clocksources Provide a consistent view of time when loading snapshots

    Friday, 31 May 13
  39. Clocksources Date.now() Friday, 31 May 13

  40. Clocksources Date.now() function Clock() { this.time = 0; this.lastDelta =

    null; } Clock.prototype.tick = function(delta) { this.time += delta; this.lastDelta = delta; } function tick() { var wallclockDelta = Date.now() - lastTick; clock.tick(wallclockDelta); } Friday, 31 May 13
  41. Escaping the Walled Garden Friday, 31 May 13

  42. Escaping the Walled Garden Friday, 31 May 13

  43. Escaping the Walled Garden Friday, 31 May 13

  44. Demo Time Friday, 31 May 13