Whatever is easiest
Don't know the theory
Can't teach anyone else
Is bad at writing notation
Pursuit of perfection
Learns and understands the theory
Can share their learnings
Can write beautiful notation
PLAYS MUSIC
MUSICIAN
WRITES CODE
SOFTWARE ENGINEER
With a great community
var done = false;
var running = 0;
var errored = false;
(function replenish () {
if (done && running <= 0) {
return callback(null);
}
while (running < limit && !errored) {
var key = nextKey();
if (key === null) {
done = true;
if (running <= 0) {
callback(null);
}
return;
}
running += 1;
iterator(obj[key], key, only_once(function (err) {
running -= 1;
if (err) {
callback(err);
errored = true;
}
else {
replenish();
}
}));
}
})();
function(path, options, fn){
// support callback API
if ('function' == typeof options) {
fn = options, options = undefined;
}
if (typeof fn === 'function') {
var res
try {
res = exports.renderFile(path, options);
} catch (ex) {
return fn(ex);
}
return fn(null, res);
}
options = options || {};
options.filename = path;
return handleTemplateCache(options)(options);
};
for (var i = 0; i < args.length; i++) {
var arg = args[i];
if (/^--.+=/.test(arg)) {
// Using [\s\S] instead of . because js doesn't support the
// 'dotall' regex modifier. See:
// http://stackoverflow.com/a/1068308/13216
var m = arg.match(/^--([^=]+)=([\s\S]*)$/);
var key = m[1];
var value = m[2];
if (flags.bools[key]) {
value = value !== 'false';
}
setArg(key, value, arg);
}
else if (/^--no-.+/.test(arg)) {
var key = arg.match(/^--no-(.+)/)[1];
setArg(key, false, arg);
}
else if (/^--.+/.test(arg)) {
var key = arg.match(/^--(.+)/)[1];
var next = args[i + 1];
if (next !== undefined && !/^-/.test(next)
&& !flags.bools[key]
var xM = isX(M);
var xm = xM || isX(m);
var xp = xm || isX(p);
var anyX = xp;
if (gtlt === '=' && anyX)
gtlt = '';
if (xM) {
if (gtlt === '>' || gtlt === '<') {
// nothing is allowed
ret = '<0.0.0';
} else {
// nothing is forbidden
ret = '*';
}
} else if (gtlt && anyX) {
// replace X with 0
if (xm)
m = 0;
if (xp)
p = 0;
If a lion could speak, we could not understand him
- WITTGENSTEIN
CORRECT LEARNABLE READABLE MAINTAINABLE
REUSABLE SCANNABLE DOCUMENTED
Good code is written for your team, not for yourself.
PERFORMANT? CONCISCE? COMPLEX?
To me, good code is:
IMPROVE READABILITY THROUGH CLEARER SYNTAX
if(~'human'.indexOf('u')){
// When is this executed?
}
if(_.includes('human', 'u')){
// This is a lot clearer
}
function isReadable(){
return !!this.readable;
}
var date = +new Date()
function isReadable(){
return Boolean(this.readable);
}
var date = Date.now();
IMPROVE READABILITY THROUGH CLEARER SYNTAX
Avoid many nested conditions by returning as quickly as possible
function getSomething(){
if(condition) {
// Long
// function
// body
// example
if(otherCondition){
return true;
}
}
return false;
}
function getSomething(){
if(!condition){
return false;
}
// Long
// function
// body
// example
return Boolean(otherCondition);
}
IMPROVE READABILITY THROUGH CLEARER SYNTAX
NO
function getTQ(t) {
var q = extend(getQuery(u), {
type: t
});
return q;
}
function getTypeQuery(type, user) {
var query = extend(getQuery(user), {
type: type
});
return query;
}
NO SINGLE LETTER VARIABLES. NO ABBREVIATIONS
PROVIDE CONTEXT THROUGH SENSIBLE NAMING
var d = 5;
var stateList = ['good','bad'];
var open = true;
var elapsedTimeInDays = 5;
var possibleStates = ['good','bad'];
var isOpen = true;
VARIABLE NAMES SHOULD BE DESCRIPTIVE
FUNCTION NAMES SHOULD IMPLY A RETURN TYPE
function pending(){}
function orgs(){}
function states(){}
function calculatePercentage(){}
function isPending(){}
function hasOrganizations(){}
function getStates(){}
function getPercentage(){}
PROVIDE CONTEXT THROUGH SENSIBLE NAMING
COMMUNICATE INTENT THROUGH CORE CONCEPTS
var result = [];
_.each(rums, function(rum){
if(rum.year < 1918){
result.push(rum);
}
});
_.filter(rums, function(rum){
return rum.year < 1918;
});
_.each(rums, function(rum){
if(rum.year < 1918){
rum.isDelicious = true;
}
});
_.map(rums, function(rum){
rum.isDelicious = rum.year < 1989;
return rum;
});
COMMUNICATE INTENT THROUGH CORE CONCEPTS
Functions should always return the same type
function getAvailbleYears(rum){
var rumYears = {
'Angostura': [1, 5, 7 ,12],
'Havana Club': [1, 3, 4, 7]
};
return rumYears[rum];
}
function getAvailbleYears(rum){
var rumYears = {
'Angostura': [1, 5, 7 ,12],
'Havana Club': [1, 3, 4, 7]
};
return rumYears[rum] || [];
}
Array
undefined
Array
COMMUNICATE INTENT THROUGH CORE CONCEPTS
var availableRums = [{
name: 'Angostura',
age: 12
}, {
name: 'Havana Club',
age: 7
}];
function incrementAges(rums) {
availableRums.forEach(function age(rum) {
rum.age++;
});
}
var availableRums = [{
name: 'Angostura',
age: 12
}, {
name: 'Havana Club',
age: 7
}];
function incrementAges(rums) {
return availableRums.map(function age(rum) {
var agedRum = clone(rum);
agedRum.age++;
return agedRum;
});
}
REDUCE CONFUSION BY SMARTER BRANCHING
function submitForm(){
var data = this.getFormData();
validateForm(data);
}
function validateForm(data){
if(isValid(data)){
augmentData(data);
}
}
function augmentData(data){
data.something = 123;
makeXHRCall(data);
}
function submitForm(){
var data = this.getFormData();
if(!isValid(formData)){
return;
}
var augmentedData = augmentData(data);
makeXHRCall(data);
}
function augmentData(data){
data.something = 123;
return;
}
REDUCE CONFUSION BY SMARTER BRANCHING
function isProper(sausage){
if(sausage.isMadeOfChicken()){
return false;
} else {
return true;
}
}
If you need an else in your function then your function does too much.
function isProper(sausage){
if(sausage.isMadeOfChicken()){
return false;
}
return true;
}
We never change the minds of the people who are most vocal against it, we just have to wait for them to die... can we get rid of goto now?
- DOUGLAS CROCKFORD
https://github.com/DrBoolean/mostly-adequate-guide
https://facebook.github.io/immutable-js/
https://www.youtube.com/watch?v=bo36MrBfTk4 (Crockford, the better parts)
https://github.com/Willyham/human.js
https://www.youtube.com/watch?v=65-RbBwZQdU (Vyacheslav Egorov, performance and benchmarking)