Slide 1

Slide 1 text

Useable, Grammatical & Readable Code Daniel van Berzon @ocastahq ocasta.com @dvberzon [email protected]

Slide 2

Slide 2 text

Grammar Daniel van Berzon @ocastahq ocasta.com @dvberzon [email protected]

Slide 3

Slide 3 text

“Rachel and me went to the cinema” “Rachel and I went to the cinema” A B C

Slide 4

Slide 4 text

Usability Daniel van Berzon @ocastahq ocasta.com @dvberzon [email protected]

Slide 5

Slide 5 text

A B C

Slide 6

Slide 6 text

Readable Code Daniel van Berzon @ocastahq ocasta.com @dvberzon [email protected]

Slide 7

Slide 7 text

A B C var person; if(age > 18) { person = "adult"; } else { person = "child"; } var person = age > 18 ? "adult" : "child";

Slide 8

Slide 8 text

Daniel van Berzon @ocastahq ocasta.com @dvberzon [email protected] Usability Grammar Readable Code Spanish Dutch Brexit Photography Magic Signing Guilbert & Sullivan Footy Television Flamenco Film Musicals

Slide 9

Slide 9 text

Daniel van Berzon @ocastahq ocasta.com @dvberzon [email protected] Usability Grammar Readable Code

Slide 10

Slide 10 text

Daniel van Berzon @ocastahq ocasta.com @dvberzon [email protected] Usability Grammar Readable Code

Slide 11

Slide 11 text

howreadable.com

Slide 12

Slide 12 text

Readable Code

Slide 13

Slide 13 text

Writing code On your own For the computer Student

Slide 14

Slide 14 text

Reading code Collaborating For developers Professional Reading : Writing 10 : 1 - Robert C Martin

Slide 15

Slide 15 text

Student Professional Cool Clever Efficient Succinct Exciting Clear Simple Intuitive Structured Boring write_code => => read_code

Slide 16

Slide 16 text

Code that is easy to read … is hard to write • Too many options • Spoilers • Other people const a = 0; a b c d e f g h i

Slide 17

Slide 17 text

const columns = [ {id: "date", name: "Date"}, {id: "recipient", name: "Recipient"}, {id: "location", name: "Recipient Location"}, {id: "sender", name: "Sender"}, {id: "message", name: "Message"} ]; Requirement that only admins should see the “Recipient” and “Recipient Location” columns. Introduce a boolean isAdmin

Slide 18

Slide 18 text

const columns = [ {id: "date", name: "Date"}, {id: "recipient", name: "Recipient"}, {id: "location", name: "Recipient Location"}, {id: "sender", name: "Sender"}, {id: "message", name: "Message"} ]; const adminColumnIds = ['recipient','location']; // filter out recipient columns const visibleColumns = columns.filter((column) => { return isAdmin || !adminColumnIds.includes(column.id); });

Slide 19

Slide 19 text

const columns = [ {id: "date", name: "Date"}, {id: "recipient", name: "Recipient", admin: true}, {id: "location", name: "Recipient Location", admin: true}, {id: "sender", name: "Sender"}, {id: "message", name: "Message"} ]; // filter out recipient columns const visibleColumns = columns.filter((column) => { return isAdmin || !column.admin; });

Slide 20

Slide 20 text

const columns = []; columns.push({id: "date", name: "Date"}); if(isAdmin){ columns.push({id: "recipient", name: "Recipient"}); columns.push({id: "location", name: "Recipient Location"}); } columns.push({id: "sender", name: "Sender"}); columns.push({id: "message", name: "Message"});

Slide 21

Slide 21 text

const date = {id:"date", name:"Date"}; const recipient = {id:"recipient", name:"Recipient"}; const location = {id:"location", name:"Recipient Location"}; const sender = {id:"sender", name:"Sender"}; const message = {id:"message", name:"Message"}; const columns = isAdmin ? [ date, recipient, location, sender, message ] : [ date, sender, message ]; None of this effort is billable

Slide 22

Slide 22 text

Readable Code = Easy to understand = Clear in intent = Logical = Easy to maintain / change = Unsurprising - Principal of ”Least Astonishment”

Slide 23

Slide 23 text

function postcodeValid(params){ return strPresent(params.postcode); } function validateParams(params){ return firstNameValid(params) && lastNameValid(params) && emailValid(params) && postcodeValid(params); }

Slide 24

Slide 24 text

function postcodeValid(params){ return strPresent(params.postcode); } function validateParams(params){ return firstNameValid(params) && lastNameValid(params) && emailValid(params) && postcodeValid(params); } Whitespace

Slide 25

Slide 25 text

function postcodeValid(params){ return strPresent(params.postcode); } function validateParams(params){ return firstNameValid(params) && lastNameValid(params) && emailValid(params) && postcodeValid(params); } Whitespace Indentation

Slide 26

Slide 26 text

function postcodeValid(params){ return strPresent(params.postcode); } function validateParams(params){ return firstNameValid(params) && lastNameValid(params) && emailValid(params) && postcodeValid(params); } Whitespace Indentation Breaking long lines

Slide 27

Slide 27 text

Legible code ≠ Readable code function postcodeValid(params){ return strPresent(params.postcode); } function validateParams(params){ return firstNameValid(params) && lastNameValid(params) && emailValid(params) && postcodeValid(params); } Whitespace Indentation Breaking long lines

Slide 28

Slide 28 text

Readability Syntax Naming Approach Organisation Consistency Structure

Slide 29

Slide 29 text

Code readability describes how the structure of code can help a developer understand and control it.

Slide 30

Slide 30 text

Usability

Slide 31

Slide 31 text

? Intuitive

Slide 32

Slide 32 text

Usability Visual form Layout Feedback Familiarity Consistency Simplicity Structure

Slide 33

Slide 33 text

Usability describes how the structure of an interface can help a user understand and control it.

Slide 34

Slide 34 text

Code readability describes how the structure of code can help a developer understand and control it. Usability describes how the structure of an interface can help a user understand and control it.

Slide 35

Slide 35 text

Developers = Users (interface) Readability = Usability Codebase = Interface (business logic)

Slide 36

Slide 36 text

Grammar

Slide 37

Slide 37 text

able to correctly use English than we are aware of. There are less people who are X ^ correctly X fewer X of whom ^ Mistakes

Slide 38

Slide 38 text

Grammar Grammar conveys meaning • Word forms (Morphology) • Sentence structure (Syntax) • Meaning (Semantics)

Slide 39

Slide 39 text

Gurf booged spink fooply

Slide 40

Slide 40 text

Gurf booged spink fooply Gained information from Grammar -ed for past tense English word order: subject — verb — object (SVO) -ly for adverbs

Slide 41

Slide 41 text

Gurf booged spink fooply Grammar helps us Understand the sentence

Slide 42

Slide 42 text

Grammar describes how the structure of language can help a speaker understand and control it.

Slide 43

Slide 43 text

Grammar describes how the structure of language can help a speaker understand and control it. code Code readability developer

Slide 44

Slide 44 text

Grammar describes how the structure of language can help a speaker understand and control it. Usability user an interface

Slide 45

Slide 45 text

Usability Grammar Readable Code

Slide 46

Slide 46 text

Usability Grammar Readable Code

Slide 47

Slide 47 text

Grammar

Slide 48

Slide 48 text

A B C “Rachel and me went to the cinema” “Rachel and I went to the cinema”

Slide 49

Slide 49 text

B: Rachel and I went to the cinema 2 pronouns for referring to oneself “I” as subject: “I went to the cinema” “Me” as object: "Rachel noticed me” “Rachel” and “I” are both subjects ∴ “Rachel and I” is correct Q.E.D. !!

Slide 50

Slide 50 text

1. Opinion 2. Size 3. Age 4. Shape 5. Colour 6. Origin 7. Material 8. Purpose English has complex grammar rules … Adjective order Green little men Little green men lovely little old long green french silver serving spoon

Slide 51

Slide 51 text

No one was ever taught this rule in school! Little green men Rachel and me went to the cinema Between you and I All debts are cleared between you and I Merchant of Venice Act 3 scene 2

Slide 52

Slide 52 text

? Little green men Rachel and I

Slide 53

Slide 53 text

Noam Chomsky Universal Grammar Humans are born with an innate understanding of grammar. Prescriptive grammar Descriptive grammar

Slide 54

Slide 54 text

Prescriptive Descriptive Arbitrary grammar rules that prescribe the way people should speak Vs. Innate grammar rules that describe the way people speak - Boldly to go - From whom is that? - Rachel and I went to the cinema - He wanted the book - Bob eats pizza (SVO) - Little green men

Slide 55

Slide 55 text

Descriptive grammar Rachel and me and Rachel and I = Noun phrases When people speak naturally... The grammar of a sentence acts on a Noun Phrase as a whole, not on its internal parts. “Rachel and me are tall” “Me are tall” or “Me went to the cinema” ∴ Both fine! Q.E.D. !!

Slide 56

Slide 56 text

? Grammar Readable Code

Slide 57

Slide 57 text

Some literature on readability Learning code readability Psychology of code readability Google JavaScript Style Guide Make your code easier to read with Functional Programming Idiomatic.js

Slide 58

Slide 58 text

Feels quite prescriptive • Talk of idiom • Opinions presented as rules • Phrases like: Prefer…, Avoid…, Recommended • No references or links to research

Slide 59

Slide 59 text

Prescriptive Descriptive

Slide 60

Slide 60 text

No native speakers of: JavaScript Python C / C++ Ruby Java Baṣa Jawa Universal grammar applies to native language speakers Flaw in the metaphor

Slide 61

Slide 61 text

Useful takeaways: • Accepted rules can be arbitrary • If people keep making a mistake
 ➞ It might not be a mistake • Base advice on empirical evidence • Don’t tell devs how to code
 ➞ Learn from how they code

Slide 62

Slide 62 text

Over half of all developers are junior < 5 yrs - Robert C Martin

Slide 63

Slide 63 text

Over half of all developers are junior < 5 yrs - Robert C Martin

Slide 64

Slide 64 text

Over half of all developers are junior < 5 yrs - Robert C Martin

Slide 65

Slide 65 text

Usability

Slide 66

Slide 66 text

A B C

Slide 67

Slide 67 text

Answer It depends! Radio buttons Dropdown See all the options One click Rich text options Less space Current selection clear Better on mobile

Slide 68

Slide 68 text

Dropdown ✔ Default option is the recommended one Many options with natural order Selected option forms part of a sentence

Slide 69

Slide 69 text

Radio Buttons ✔ Small number of options User should compare options Add context information

Slide 70

Slide 70 text

Usability depends on context Context is different in each case Very difficult to formulate rules Leads to frustration Use of four letter words ! "

Slide 71

Slide 71 text

Test

Slide 72

Slide 72 text

Best way to work out if an interface is usable Easiest method is the Survey But → Jam experiment! → Try it out on users

Slide 73

Slide 73 text

Psychologists in 2000 set up a supermarket display with 6 24 or Varieties of jam, on alternating days But, Bought more jam with fewer options £££ Shoppers preferred having more options

Slide 74

Slide 74 text

Jam experiment shows that Opinion ≠ Behaviour Surveys measure opinion Better to directly test behaviour Less choice More choice

Slide 75

Slide 75 text

Types of user behaviour test: • A - B testing • User observation • Automated screen recording Directly measure user experience

Slide 76

Slide 76 text

? Usability Readable Code

Slide 77

Slide 77 text

Best way to work out if code is Readable Don’t ask developer’s opinion → try it out on developers Directly measure behaviour

Slide 78

Slide 78 text

Objective metric for readability? Ability to predict output Time to comprehension

Slide 79

Slide 79 text

Readable Code

Slide 80

Slide 80 text

A B C var person; if(age > 18) { person = "adult"; } else { person = "child"; } var person = age > 18 ? "adult" : "child";

Slide 81

Slide 81 text

Ternary Operator vs If Else Look for a descriptive readability rule Testing the code on developers Directly measure ability to predict output and time to comprehension

Slide 82

Slide 82 text

howreadable.com

Slide 83

Slide 83 text

howreadable.com Measure code readability Developers shown a series of code samples Time how long they take to read the code After reading each sample asked: • Predict the result of the code • Rate how readable they found it • Add any comments → Proof of concept experiment

Slide 84

Slide 84 text

Ternary a ? b : c; if(a){b}… Method

Slide 85

Slide 85 text

Ternary a ? b : c; if(a){b}… Method

Slide 86

Slide 86 text

Ternary a ? b : c; if(a){b}… 60% 40% Method

Slide 87

Slide 87 text

• Simple - correct response in reasonable time • A predictable result • Self contained - predictable from the visible code • Any calculation / logic possible in your head • Avoid tricks / hidden bugs Code samples a ? b : c;

Slide 88

Slide 88 text

function getResult(value) { return value > 4 ? 10 : 20; } var result = getResult(3); function getResult(value) { if(value > 4){ return 10; } else { return 20; } } var result = getResult(3); Participant asked to predict value of `result` Ternary operator vs if else statement

Slide 89

Slide 89 text

• Available in Js, Ruby and Python • Experiments presented in a random order • Equal number participants for each sample - Block randomisation howreadable.com • Other data captured: • Years programming • Main language • Browser agent / Display size ES5

Slide 90

Slide 90 text

Participation 247 participants 38 50 159 Language choice Elixir Go C++ Typescript Other PHP Java C# Python Ruby JS Main Language 10 + 6 - 10 5 4 3 2 1 < 1 Years programming

Slide 91

Slide 91 text

9 Experiments Syntax • Ternary operator vs if else • Nested Ternary vs if else • arr.reduce vs for loop • switch case statements Conditionals • Order of if else • if else vs early return Naming Comments Abstraction

Slide 92

Slide 92 text

Ternary vs if else 94.4% 98.4% 27.1s 23.5s 3.7 3.4 Statistical analysis

Slide 93

Slide 93 text

Ternary vs if else 0 2.5 5 7.5 10 1 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120123 126 129 132 135 138 141144 147 150 153 156 159 Ternary If else Seconds % of results Ternary if else Students T-Test P value ≤ 0.05 P = 0.44

Slide 94

Slide 94 text

arr.reduce vs for loop var values = [1,2,3,4]; var result = values.reduce(function(sum, val){ return sum + val; }); var values = [1,2,3,4]; var result = 0; for(var i = 0; i < values.length; i++){ result += values[i]; }

Slide 95

Slide 95 text

arr.reduce vs for loop 98.4% 92.4% 43.8s 29.1s 3.5 3.4 50% slower P = 0.002

Slide 96

Slide 96 text

Syntax • Ternary operator vs if else • Nested Ternary vs if else • arr.reduce vs for loop • switch case statements Conditionals • Order of if else • if else vs early return Naming Comments Abstraction 9 Experiments

Slide 97

Slide 97 text

if(showPanel()){ $('panel').show() } Naming showPanel() There are only two hard things in Computer Science: cache invalidation and naming things. -- Phil Karlton

Slide 98

Slide 98 text

action.completed() Naming • Set completed flag to true • Has the action been completed? • List of completed actions • Run procedures to complete the action • Run some post completion procedures

Slide 99

Slide 99 text

array.filter(fn) Naming Residue Filtrate

Slide 100

Slide 100 text

function processStr(str){ return str.toLowerCase().split('').sort().join('').trim(); } function isAnagramOf(str, testStr){ return processStr(str) == processStr(testStr); } var result = isAnagramOf("devil", "lived"); function sortAlphabetically(str){ return str.toLowerCase().split('').sort().join('').trim(); } function isAnagramOf(str, testStr){ return sortAlphabetically(str) == sortAlphabetically(testStr); } var result = isAnagramOf("devil", "lived"); Generic vs Specific P = 0.2

Slide 101

Slide 101 text

Comments If you have to write a comment, your code isn't readable enough. Never! Always! 1 2 3 4 5 6 6 4 3 3

Slide 102

Slide 102 text

Comments Your ideal should be: our code does not need comments. Practically tell a story with your comments

Slide 103

Slide 103 text

No comment function doRangesOverlap(range1, range2) { return range1.end >= range2.start && range1.start <= range2.end; } var scores = { start: 1, end: 7 }; var desired = { start: 5, end: 9 }; var result = doRangesOverlap(scores, desired);

Slide 104

Slide 104 text

No comment vs What comment // for any two ranges, do they overlap? function doRangesOverlap(range1, range2) { // does one start before the other ends // and end before the other starts return range1.end >= range2.start && range1.start <= range2.end; } // range of scores var scores = { start: 1, end: 7 }; // the desired range var desired = { start: 5, end: 9 }; // do the scores overlap with the desired range var result = doRangesOverlap(scores, desired); // for any two ranges, do they overlap?

Slide 105

Slide 105 text

No comment vs What comment vs Why comment function doRangesOverlap(range1, range2) { // Two ranges overlap if one starts before the other ends // and ends before the other starts return range1.end >= range2.start && range1.start <= range2.end; } var scores = { start: 1, end: 7 }; var desired = { start: 5, end: 9 }; var result = doRangesOverlap(scores, desired); // Two ranges overlap if one starts before the other ends // and ends before the other starts

Slide 106

Slide 106 text

No comment vs What comment vs Why comment vs Bad comment function doRangesOverlap(range1, range2) { // Two ranges overlap if one starts before the other starts // or ends before the other ends return range1.end >= range2.start && range1.start <= range2.end; } var scores = { start: 1, end: 7 }; var desired = { start: 5, end: 9 }; var result = doRangesOverlap(scores, desired); // Two ranges overlap if one starts before the other starts // and ends before the other ends

Slide 107

Slide 107 text

No comment vs What comment vs Why comment vs Bad comment No difference More Readable Less readable

Slide 108

Slide 108 text

No comment vs What comment vs Why comment vs Bad comment P = 0.34

Slide 109

Slide 109 text

Why the high P values? • No effect to measure (null hypothesis) • The effect is small and the test too blunt • Sample size too low • There's a problem with the methodology... > 90%

Slide 110

Slide 110 text

0 2.5 5 7.5 10 1 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120123 126 129 132 135 138 141144 147 150 153 156 159 Ternary If else Seconds % of results Ternary if else Time to comprehension Why the long tail?

Slide 111

Slide 111 text

I am not keen on the use of abbreviations as they mk cd hrd 2 rd. I would ask for a complete rewrite on a code review. Time to comprehension

Slide 112

Slide 112 text

I am not keen on the use of abbreviations as they mk cd hrd 2 rd. I would ask for a complete rewrite on a code review. If else should be used over ternary when possible Ternary operator here will be better Shadowing the variable name result wasn't a great start... the variable name is misnamed. It's not strictly a name but rather a salutation Time to comprehension

Slide 113

Slide 113 text

I am not keen on the use of abbreviations as they mk cd hrd 2 rd. I would ask for a complete rewrite on a code review. If else should be used over ternary when possible Ternary operator here will be better Shadowing the variable name result wasn't a great start... the variable name is misnamed. It's not strictly a name but rather a salutation String.prototype.charAt would be better in every way and simpler. In addition, this does nothing for i18n support. Time to comprehension

Slide 114

Slide 114 text

I am not keen on the use of abbreviations as they mk cd hrd 2 rd. I would ask for a complete rewrite on a code review. If else should be used over ternary when possible Ternary operator here will be better Shadowing the variable name result wasn't a great start... the variable name is misnamed. It's not strictly a name but rather a salutation String.prototype.charAt would be better in every way and simpler. In addition, this does nothing for i18n support. Your textbook bad code If you write this you are bad and you should feel bad! Time to comprehension

Slide 115

Slide 115 text

Reading code ≠ Reviewing code Possible some participants taking longer to read the code than necessary to understand it Finite ∞ Time to comprehension

Slide 116

Slide 116 text

No content

Slide 117

Slide 117 text

• Show a timer • Remove comment box • Better instructions / signposting • Maybe fixed time? Time to comprehension

Slide 118

Slide 118 text

New experiments • Code golf • Booleans: (!a && !b) vs (!(a || b)) • Chaining methods vs intermediate vars • Consistency Writing code in as few lines as possible

Slide 119

Slide 119 text

Another approach? • Linguists research by searching Language corpus https://books.google.com/ngrams ?

Slide 120

Slide 120 text

The future... • More statistical analysis of existing results • Increase sample size (marketing) • Offer more languages • Harder, more realistic tests • Get help, and funding!

Slide 121

Slide 121 text

In the meantime? • Avoid array.reduce • Take advice of readability literature • Question prescriptive rules • If in doubt - try it out (on a junior!) • Help me! [email protected]

Slide 122

Slide 122 text

Thank you Daniel van Berzon @ocastahq ocasta.com @dvberzon [email protected]