Should have done this earlier, making a thread to keep Code Complete notes for key points or stuff I want to bookmark for presentations.
pg. 434, simplifying complex booleans:

If you use the [boolean] test only once, you might not think it's worthwhile to put it into a routine. But wrapping it in a well named fn improves readability and makes it easier to see what it's doing. That's sufficient reason to do it.
pg. 436, reference table for DeMorgan's Theorems for transforming boolean expressions
pg. 440, conditional evaluation and short circuiting

"Since a reader may not be as sharp as you are, use nested tests to clarify your intentions instead of depending on evaluation order and short circuit evaluation."
pg. 443, single-line or statement ifs

aka

if (condition) do something();

"Putting a single statement after an if test is sometimes appealing aesthetically, but under maintenance tend to become more complicated blocks, and single statements are error prone when that happens."
pg. 453, deep nesting

"Complicated code is a sign you don't understand your program well enough to make it simple. Deep nesting [...] indicates a need to break out a routine or redesign the part of the code that's complicated. Have a good reason if you don't modify the routine."
pg. 457, complexity

"This mental juggling act is one of the most difficult aspects of programming and is the reason programmers get upset about 'quick interruptions'. [It's] tantamount to asking a juggler to keep three balls in the air and hold your groceries at the same time."
cont.

"[...] researchers agree that control flow (cyclomatic complexity) is at least one of the largest contributors to complexity, if not the largest."
cont.

"The competent programmer is fully aware of the strictly limited size of [their] own skull; therefore, he approaches the programming task in full humility." - Dijkstra, 1972

"[This] implies that you can't deal with enormous complexity and must reduce it wherever possible"
pg. 459, references to look up later for software complexity

Tom McCabe. A Complexity Measure (1976)

Conte, Dunsmore, and Shen. Software Engineering Metrics and Models (1986)

Also note to look for VS Code plugins that could measure the file I'm editing in real time?
pg. 466, software quality factors and how they impact each other
pg. 470, defect detection rates

Unit testing and integration testing were found to only find defects at a modal rate of 30-35%, max 50%.

This is why I always tell people TypeScript and testing is mutually beneficial. Those who claim tests are enough overlook this.
cont'd.

"The strong implication is that if project developers are striving for a higher detection rate, they need to use a combination of techniques." And studies confirm this implication.
pg. 473

Code reviews are more cost-effective than testing.

Studies all confirm in the 80s and 90s.

700k LOC w/400 devs: Code reviews were 1.38 return on investment vs 0.17 for testing only.

MSft: found finding and fixing defects in 3 hours for reviews vs 12 hours for testing
pg. 473, measure twice, cut once

"A fault in requirements can produce one or more faults in design, which can produce many corresponding faults in code. A requirements error can result in extra architecture or in bad architectural decisions."

Don't skimp on requirements.
pg. 474

"The best way to improve productivity and quality is to reduce the time spent reworking code, whether the rework arises from changes in requirements, changes in design, or debugging."

Higher quality assurance at all stages = shorter dev cycles and higher productivity.
Key point: 🔑 higher quality assurance practices did not cost more. The most costly part of software dev is defect removal. Higher quality assurance lowers overall cost.

It is astounding how many orgs don't understand this and end up removing quality practices.
pg. 480, collaborative construction

"IBM found that each hour of inspection prevented 100 hours of related work (testing and defect correction)" 🤯
cont.

"A study of large programs found each hour spent on inspections avoided an avg of 33 hours of maintenance work and inspections were 20x more efficient than testing"
pg. 484, pair programming:

- holds up better under stress than solo dev. Pairs encourage each other to write better code even when pressure exists to write quick and dirty code
- improves code quality
- shortens schedules
- disseminates culture, mentoring, collective ownership
pg. 491, formal inspections

"The inspection process is the highest level [of maturity]. It is systematic and repeatable and uses measured feedback to improve itself. These ideas are what it takes to move the org to the highest possible level of quality and productivity."
pg. 494, code reading

My summary of this technique is that this is essentially PR reviews as we do them now. Individual reviewers, at least 2, read the code individually and provide feedback. The author addresses it. Book says it's an effective technique esp for remote teams.
pg. 501, testing

"Trying to improve software quality by increasing the amount of testing is like trying to lose weight by weighing yourself more often. [...] If you want to lose weight, don't buy a new scale, change your diet. [...] Don't just test more; develop better."
pg. 504, common drawbacks when devs write tests:

- we only test the happy paths
- we think we covered more than we actually did (branch coverage is better than statement)
- we tend to skip more sophisticated kinds of tests
pg. 517, typical errors

Pareto principle holds true. Multiple studies found that 80% of errors are found in 20% of a project's classes or routines.

50% of errors are found in 5% of a projects source code.

Highly defective routines are extremely expensive.
pg. 519

Typos are a surprisingly common source of problems. One study was as high as 36% of errors were due to typos. Another was 18% in flight software.

Consider the most expensive errors of all time (since writing):

- $1.6b
- $900m
- $245m

Were due to 1 character typos
pg. 522

"Test cases are often as likely or more likely to contain errors than the code being tested. [...] Test cases tend to be created on the fly [...] They are often viewed as one time tests and are developed with care commensurate with something to be thrown away."

🔥🔥🔥
pg. 539, debugging

"In Dante's version of hell, the lowest circle is reserved for Satan himself. In modern times, Old Scratch has agreed to share the lowest circle with programmers who don't learn to debug effectively."

😂
pg. 541, scientific method for debugging

1. Stabilize the error
2. Locate the source
3. Fix the defect
4. Test the fix
5. Look for similar errors

"The defect is easier to diagnose if you can stabilize it -- that is, make it occur reliably."

This is how I learned debugging 👏
pg. 548, debugging tricks:

- 🦆 rubber duck: talk to someone (or an inanimate object) out loud about the problem

- ☕ take a break: outsource to subconscious. "it reduces the anxiety associated with debugging. The onset of anxiety is a clear sign it's time to take a break"
pg. 549

Set a maximum time for quick and dirty debugging.

"How often have you spent two hours debugging code that took only 30 mins to write? That's a bad distribution of labor, and you would have been better off to rewrite the code than to debug bad code."
pg. 551

"Hurrying to solve a problem is one of the most time-ineffective things you can do. It leads to rushed judgement, incomplete defect diagnosis, and incomplete corrections. Wishful thinking can lead you to see solutions where there are none."

Deadline-driven development.
pg. 553

Before you make a change, be confident that it will work. Being wrong about a change should leave you astonished. It should cause self-doubt, personal reevaluation, and deep soul-searching. It should happen rarely.

🤔😑🧐🥲
pg. 554

"Debugging is as intellectually demanding as any other software dev activity. [...] You have to think precisely--forming hypotheses, collecting data, analyzing hypotheses, and methodically rejecting them--with a formality that's unnatural to many people."
pg. 554 - 588

All about refactoring. All good stuff.
pg. 588

"More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason -- including blind stupidity."

- W. A. Wulf
pg. 588 cont.

Performance is only loosely related to code speed. Users care more about throughput, a clean user interface, and things not crashing than they do about your code quality.
pg. 588

"We assume that the better we make the code, the more our clients and customers will like our software.

This POV might have a mailing address somewhere in reality, but it doesn't have a street number and it certainly doesn't own any real estate." 😂
pg. 630, various optimizations. This one is handy for math in games, filing away. cc @ErikOnarheim
pg. 667 change control

Discusses importance of change requests and review board. We do something in our daily 9am community standup where we triage issues. Every new issue that gets made is marked for triage and the issue doesn't leave triage without being put into milestones.
pg. 668

Discusses standardized "disk images". Nowadays that is containerization. It's standard practice here to containerize apps for deployment but it's a little less standard for local development. I hope it becomes easier and more normal to run containers locally for dev.
pg. 671, estimation

"Developer estimates tend to have an optimism factor of 20 to 30 percent (van Genuchten 1991)"

My rule of thumb is to double estimates even if I am optimistic, knowing I'm definitely probably wrong. 👍 Also, trust your gut, it's usually right.
By the way, on a healthy team, I can say this out loud and there's not much pushback. If you work with developers and project managers or scrum masters who have been around longer than 1-2 projects, everybody understands initial estimates are optimistic. Okay to say that!
pg. 678

Useful measurements of software development.

"Our development process doesn't seem to work"

"What are you measuring?"

"Uh..."

To improve anything anywhere you have to measure it.
pg. 684, physical environment

Citing Peopleware, top-25%
workplace environments have 2.6X more productivity per programmer.

The top-25% work environments had 78sq ft. of dedicated space per person and 62% of people said they had acceptably private workspaces.

Open plans suck
pg. 706, integration

Interestingly, most of the section is focused on daily builds and CI is only an afterthought. I guess a lot has changed in that department since 2004.

He says that he polled top executives, including Amazon, and they preferred daily over CI at that time.
pg. 723, tool fantasyland

"We will always need people who can bridge the gap between the real world problem to be solved and the computer that is supposed to be solving the problem"

Even back then he is saying vendors who claim their tool "eliminates programming" is silly.
Cont.

"Good tools can reduce the more tedious aspects of software development, but they can't eliminate the need for programming, although they will continue to reshape what we mean by 'programming'".

I mentioned @retool the other day as something that fits this definition.
pg. 734, Layout and Style

"Schneiderman found that when program statements were arranged in a sensible order, experts were able to remember them better than novices. When statements were shuffled, the experts' superiority was reduced." Other studies confirm this.
Cont.

"[This] suggests that structure helps experts perceive, comprehend, and remember important features of programs. [...] The bottom line is that the details of [style] are much less important than the fact that the program is structured consistently."
pg. 735

A good layout scheme should:

- Accurately represents the logical structure of code

- Consistently represent the logical structure of code

- Improve readability

- Withstand modifications
pg. 737

Studies correlated readability with indentation. 2-4 space indentation is optimal. People *said* they liked 6 space indentation better but they scored 20-30% lower on comprehension. This is an example of a collision between aesthetics and readability.
pg. 761, formatting

Even if you read statements with side fx easily, take pity on the other people who will read your code. [...] Let them use their brain cells to understand the larger questions of how your code works rather than the syntactic details of a specific expression.
pg. 768, class organization

Class implementation (and interfaces) should be organized in the following order:

1. Header comment (jsdoc, xml doc, etc)
2. Ctors and destructors
3. Class data
4. Public routines
5. Protected routines
6. Private routines
pg. 770 commenting classes

"Avoid dense forests of asterisks."

I've seen this with CSS and JS in the past lol.
pg. 773, layout out classes

Adapting the C++ layout Steve says but for TS modules:

1. File-description comment
2. Imports
3. Const / enum declarations
4. Type definitions
5. Exported vars and funcs
6. Private vars and funcs
7. Classes

🤔
pg. 796, comment at the level of intent

"Another way of thinking about commenting at the level of intent is to think what you would name a routine that did the same thing as the code you want to comment. [...] Type the description without shortening or abbreviating it."
pg. 801

"Don't document bad code, rewrite it." - Kernighan/Plauger (1978)

"If something seems tricky to you, it will be incomprehensible to someone else."

"If you're maintaining a program and don't have the latitude to rewrite bad code, commenting the tricky parts is [fine]."
pg. 821

Coincidentally, great intelligence is only loosely connected to being a great programmer. [...] The people who are best at programming are the people who realize how small their brains are. They are humble. [...] The more humble you are, the faster you'll improve.
pg. 822

In the development of a superior programmer, curiosity about technical subjects must be a priority.
pg. 825

It's no sin to be a beginner or an intermediate. It's no sin to be a competent programmer instead of a leader. The sin is in how long you remain a beginner or intermediate after you know what you have to do to improve.
pg. 827

IBM's Bill Weimer says, "We found that technical people, in general, were actually very good at estimating project requirements and schedules. The problem they had was defending their decisions; they needed to learn how to hold their ground."

👍👍👍
pg. 829

If you don't try to analyze requirements and design before you begin coding, much of your learning about the project will occur during coding and the result of your labors will look more like a 3yr old's finger painting than a work of art.

👏👏👏
pg. 830

"The most important work in effective programming is thinking, and people tend not to look busy when they're thinking. If [a] dev looked busy all the time, I'd assume that they're not a good programmer because they aren't using their most valuable tool, their brain." 🧠
pg. 831-832

overrated characteristics:

- Persistence -- spending 4 hours to fix a bug is not good
- Experience -- Learning has to be continuous, otherwise having "experience" becomes worse than having no experience
- all nighters -- excitement is no substitute for competency
You can follow @kamranayub.
Tip: mention @twtextapp on a Twitter thread with the keyword “unroll” to get a link to it.

Latest Threads Unrolled: