Change Software
Like a Scientist
FRED GALOSO | GROWTH ENGINEER, TRELLO | ATLASSIAN | @WAYOUTMIND
Change is
inevitable.
Stuff
happens
blows up.
ScaleWhy does
software
change?
Requirements
Maintenance
Improvements
ScaleWhy does
software
change?
Requirements
Maintenance
Improvements
ScaleWhy does
software
change?
Requirements
Maintenance
Improvements
ScaleWhy does
software
change?
Requirements
Maintenance
Improvements
ScaleWhy does
software
change?
Requirements
Maintenance
Improvements
How does it work now?Fix it.
Apply changes.
Don’t break anything.
Good luck!
How does it work now?Fix it.
Apply changes.
Don’t break anything.
Good luck!
“List of Software Bugs”
FIX IT
Therac-25 radiation therapy machine code is directly
responsible for at least five patient deaths in the 1980s when
it administered excessive X-rays.
SOFTWARE BUGS
How do we
safely
change software?
How do we
safely
refactor software?
Tests
Code Review
Specifications
Quality Assurance
Safe/Continuous Deployment Practices
…
Oh my!
Wofratz; https://en.wikipedia.org/wiki/
Icebreaker#/media/
File:Nuclearicebreakeryamal.jpg
Program testing can be used
to show the presence of
bugs, but never to show
their absence
DR. EDSGER W. DIJKSTRA
Since software has bugs,
given enough time and
volume, your data will have
bugs, too.
JESSE TOTH, GITHUB
Inspection
Measure Twice, Cut Over Once
Scientific Method
Question
Research
Hypothesis
Experiment
Analysis
Communication
Project-128; https://flic.kr/p/iG5hmM
GitHub: Scientist (Ruby)
http://githubengineering.com/scientist/
Hypothesis Experiment Measurement
Scientific Changes
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
http://githubengineering.com/scientist/
GitHub: Scientist (Ruby)
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
http://githubengineering.com/scientist/
GitHub: Scientist (Ruby)
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
http://githubengineering.com/scientist/
GitHub: Scientist (Ruby)
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
http://githubengineering.com/scientist/
GitHub: Scientist (Ruby)
Atwood’s Law: any application
that can be written in JavaScript,
will eventually be written in
JavaScript
JEFF ATWOOD
Scientist (Node.js)
github.com/trello/scientist
npm install scientist
git clone https://bitbucket.org/
fredgaloso/code-like-a-scientist.git
cd code-like-a-scientist/examples
npm install
node —-harmony
Example
Experiment
Example Code
Array Sum
Experiment
Result
'use strict';
const sum = (arr) => {
let sum = 0;
for (var i of arr) {
sum += i;
}
return sum;
};
module.exports = sum;
Example
Experiment
Experiment
Result
Array Sum
Example Code
Example
Experiment
Array Sum
Result
Experiment
Example Code
'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;
Example
Experiment
Array Sum
Experiment
Result
Example Code
> const sum = require('./sum-science')
undefined
> sum([1, 2, 3])
6
> Experiment candidate matched the control
{ context: {}, result: 'value: 6' }
'use strict';
const science = require('scientist/console');
const helloWorldConcat = (name) => {
return 'Hello world, ' + name;
};
const helloWorldJoin = (name) => {
return ['Hello world, ‘].join(‘');
};
const helloWorld = (name) => {
return science('helloWorld', (experiment) => {
experiment.use(() => helloWorldConcat(name));
experiment.try(() => helloWorldJoin(name));
});
};
module.exports = helloWorld;
Example
Experiment
Exercise
'use strict';
const science = require('scientist/console');
const helloWorldConcat = (name) => {
return 'Hello world, ' + name;
};
const helloWorldJoin = (name) => {
return ['Hello world, ‘, name].join('');
};
const helloWorld = (name) => {
return science('helloWorld', (experiment) => {
experiment.use(() => helloWorldConcat(name));
experiment.try(() => helloWorldJoin(name));
});
};
module.exports = helloWorld;
Example
Experiment
Exercise
Side effects?!
Side effects?!
API calls
Side effects?!
DataAPI calls
Side effects?!
Data
Persistence
API calls
Side effects?!
Data
PersistenceI/O
API calls
Isolation Instrumentation Side effect
Scientific Side Effects
Scientific
Side Effects
Modifying
Data
Fetching Data
Dependencies
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;
}
Scientific
Side Effects
Modifying Data
Fetching Data
Dependencies
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;
}
Scientific
Side Effects
Modifying Data
Fetching Data
Dependencies
function applyBrakes(userId) {
const brakeThreshold = science(‘brakeThreshold',
(experiment) => {
experiment.use(() =>
ExistingProximityRadar.getBrakeThreshold());
experiment.try(() =>
NewHybridComputerVisionAndRadar.getBrakeThreshold());
});
return activateBrakes(brakeThreshold);
}
TRELLO ENTERPRISE CASE STUDY
Critical
Component
Authentication
Variability
Different implementations of
SAML standard
Maintenance
Ensure bug fixes do not cause
regressions
Isolation
Authentication
API
Instrumentation
Compare result of
old vs new and
improved library
Side effect
Authenticate user
and create session
Scientific Side Effects
Safety in experiments.
Velocity in experiments.
Separation is hard.
Isolation
…
Side effect
Loose coupling is even harder.
Thank you!
FRED GALOSO | GROWTH ENGINEER, TRELLO | ATLASSIAN | @WAYOUTMIND

Change Software Like a Scientist