Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Refactor Like a Scientist

Refactor Like a Scientist

Tests are a good baseline for defining the behavior of a program,
but for complicated programs, are tests enough?
[Scientist](https://github.com/trello/scientist) is a Node.js library
for creating and running experiments between old and new pieces of code.
Scientist makes it easy to refactor critical code paths with confidence.
It safely exposes refactorings to actual production interactions and measures
potential mismatches. Part experience report, refactoring discussion,
and workshop, this talk makes the case for changing software safely and will also explore safe refactoring techniques
at companies like Trello and GitHub.

Fredrick Galoso

April 06, 2017
Tweet

More Decks by Fredrick Galoso

Other Decks in Programming

Transcript

  1. The year 2000 problem spawned fears of worldwide economic collapse

    and an industry of consultants providing last-minute fixes.
  2. A bug in the code controlling the Therac-25 radiation therapy

    machine was directly responsible for at least five patient deaths in the 1980s when it administered excessive quantities of X-rays.
  3. The Northeast blackout of 2003 was triggered by a local

    outage that went undetected due to a race condition in General Electric Energy's XA/21 monitoring software.
  4. Smart ship USS Yorktown was left dead in the water

    in 1997 for nearly 3 hours after a divide by zero error.[
  5. In January 2009, Google's search engine erroneously notified users that

    every web site worldwide was potentially malicious, including its own.
  6. –Dr. Edsger W. Dijkstra “Program testing can be used to

    show the presence of bugs, but never to show their absence”
  7. Since software has bugs, given enough time and volume, your

    data will have bugs, too. –Jesse Toth, GitHub
  8. def pullable_by?(user) science "repository.pullable-by" do |experiment| experiment.context :repo => id,

    :user => user.id experiment.use { is_collaborator?(user) } experiment.try { has_access?(user) } end end
  9. –Jeff Atwood Atwood's Law: any application that can be written

    in JavaScript, will eventually be written in JavaScript
  10. Array Sum 'use strict'; const sum = (arr) => {

    let sum = 0; for (var i of arr) { sum += i; } return sum; }; module.exports = sum;
  11. 'use strict'; const science = require('scientist/console'); const iterative = (arr)

    => { let sum = 0; for (var i of arr) { sum += i; } return sum; }; const functional = (arr) => { return arr.reduce((a, b) => { return a + b }); }; const sum = (arr) => { return science('sum', (experiment) => { experiment.use(() => iterative(arr)); experiment.try(() => functional(arr)); }); }; module.exports = sum;
  12. > const sum = require('./sum-science') undefined > sum([1, 2, 3])

    6 > Experiment candidate matched the control { context: {}, result: 'value: 6' }
  13. function processUser(user) { # Isolation const oldDateCalculation = complexDateCreator.create(); const

    newDateCalculation = new Date(); # Instrumentation const dateProcessed = science('datedProcessed', (experiment) => { experiment.use(() => oldDateCalculation); experiment.try(() => newDateCalculation); }); # Side effect user.lastProcessed = dateProcessed; user.save(); return user; }
  14. function getUserById(userId) { const user = science('getUserById', (experiment) => {

    experiment.use(() => Users.findById(userId)); experiment.try(() => { SQL(‘SELECT * FROM Users WHERE id = %s’, userId)); } }); return user; }
  15. function applyBrakes(userId) { const brakeThreshold = science(‘brakeThreshold', (experiment) => {

    experiment.use(() => ExistingProximityRadar.getBrakeThreshold()); experiment.try(() => NewHybridComputerVisionAndRadar.getBrakeThreshold()); }); return activateBrakes(brakeThreshold); }