# # Results

## # Participation

In total, **545** participants took part in the experiment. On average, each participant completed 13 exercises, leading to around 250 data points for each snippet.

Just under half of the participants said they had been coding for over 10 years, and around a third had been coding for less than 5 years.

In terms of main programming language, over half the participants said that their main programming language was JavaScript, with the rest spread around a variety of other languages.

## # Results by construct

### # Boolean Algebra

This experiment was based on the principle that the following expressions are identical.

```
!a && !b /* expanded */ === !(a || b) /* simplified */
```

The *expanded* version on the left (with two separate negations) is exactly equivalent to the *simplified* version on the right (with a single negation applied to the expression in parenthesis). We wanted to see whether there was any difference in readability between these two ways of expressing combined booleans.

We wrote six exercises with pairs of snippets like the following:

#### # Expanded

```
function canDrink(drinkerAge, drinkIsAlcoholic) {
var underAge = drinkerAge < 18;
return !underAge || !drinkIsAlcoholic;
}
var result = canDrink(21, true);
```

#### # Simplified

```
function canDrink(drinkerAge, drinkIsAlcoholic) {
var underAge = drinkerAge < 18;
return !(underAge && drinkIsAlcoholic);
}
var result = canDrink(21, true);
```

We found a statistically significant difference in the time taken to read the snippets as follows:

Metric | Expanded | Simplified | P value |
---|---|---|---|

Time taken | 28.0 | 30.6 | 0.045 |

It seems that in our tests, the expanded versions of boolean expressions are faster to parse than the equivalent simplified expressions.

### # Chaining Methods

This experiment compared the chaining of consecutive methods, with the introduction of meaningful intermediate variables. For example:

#### # Chaining methods

```
function sort(input) {
return input
.toLowerCase()
.split('')
.sort()
.join('');
}
var result = sort('bag');
```

#### # Intermediate variables

```
function sort(input) {
var lowerCase = input.toLowerCase();
var lettersArray = lowerCase.split('');
var sorted = lettersArray.sort();
return sorted.join('');
}
var result = sort('bag');
```

We found a statistically significant difference in both the accuracy and the time taken, but in different directions:

Metric | Chained methods | Intermediate variables | P value |
---|---|---|---|

Accuracy (%) | 89.2 | 93.8 | 0.044 |

Time Taken (s) | 30.5 | 39.3 | 0.001 |

We found that more people were able to accurately predict the outcome of the snippets with intermediate variables. However, the snippets were faster to read with chained methods.

It seems that there is a readability trade-off between the speed of parsing chained methods and the increased context given by the meaningful intermediate variables.

### # Extracting Functions

This experiment tested the effect on readability of extracting a series of operations into a named function, as opposed to performing the operations inline. For example:

#### # Extracted function

```
function getSum(values) {
var sum = 0;
for (var i = 0; i < values.length; i++) {
sum += values[i];
}
return sum;
}
function getAverage(values) {
return getSum(values) / values.length;
}
result = getAverage([1, 2, 3]);
```

#### # Inline operations

```
function getAverage(values) {
var sum = 0;
for (var i = 0; i < values.length; i++) {
sum += values[i];
}
return sum / values.length;
}
result = getAverage([1, 2, 3]);
```

We found a statistically significant difference in the time taken to read the code snippets, as follows:

Metric | Function | Inline | P value |
---|---|---|---|

Time taken (s) | 43.0 | 38.4 | 0.048 |

It seems that in our experiment, extracting a named function adds an overhead in the time taken to read the code.

### # Order of If Statements

This experiment tested whether there is any effect on the readability of a conditional statement with two branches, in dealing with the branch case first. For example:

#### # Positive first

```
function getSalutation(title, firstName, lastName) {
var salutation;
if (title) {
salutation = title + ' ' + lastName;
} else {
salutation = firstName + ' ' + lastName;
}
return salutation;
}
var result = getSalutation('Miss', 'Jane', 'Marple');
```

#### # Negative first

```
function getSalutation(title, firstName, lastName) {
var salutation;
if (!title) {
salutation = firstName + ' ' + lastName;
} else {
salutation = title + ' ' + lastName;
}
return salutation;
}
var result = getSalutation('Miss', 'Jane', 'Marple');
```

We found a statistically significant difference in the time taken to read the code snippets, as follows:

Metric | Positive first | Negative first | P value |
---|---|---|---|

Time taken (s) | 17.3 | 19.3 | 0.042 |

It seems that in our experiment, conditional statements where the positive condition appears first are faster to read.

### # Operator Precedence

This experiment tested whether expressions that are dependent on operator precedence are made more readable by adding parentheses to remove the ambiguity. It should be noted that some code linters, such as prettier, will remove parentheses that are considered *unnecessary* by default.

For example:

#### # Parentheses

```
var fixedCost = 200;
var monthlyCost = 20;
var result = fixedCost + (monthlyCost * 12);
```

#### # No parentheses

```
var fixedCost = 200;
var monthlyCost = 20;
var result = fixedCost + monthlyCost * 12;
```

We found a statistically significant difference in both the accuracy and the time taken, as follows:

Metric | Parentheses | No Parantheses | P value |
---|---|---|---|

Accuracy (%) | 97.2 | 91.7 | 0.042 |

Time Taken (s) | 17.0 | 19.1 | 0.013 |

It seems clear that readability is improved by adding explicit brackets, rather than relying on the developers' knowledge of operator precedence.

### # Pure Functions

This experiment tested whether there was an inherent difference in readability between pure and impure functions. A pure function has no external dependencies or side effects, and always returns the same output for the same input parameters values.

For example, the following snippets have functions expressed in both impure and pure forms.

#### # Pure

```
var score = 10;
function doubleScore(initialScore) {
return initialScore * 2;
}
var result = doubleScore(score);
```

#### # Impure

```
var score = 10;
function doubleScore() {
score = score * 2;
}
doubleScore();
var result = score;
```

We found a statistically significant difference in the time taken to read the code snippets, as follows:

Metric | Pure | Impure | P value |
---|---|---|---|

Time taken (s) | 26.7 | 24.6 | 0.025 |

It seems that in our experiment, writing a pure function adds an overhead in the time taken to read the code.