202307241042 The Pragmatic Programmer
#structure #source #wip #newIntro
- 202308141544 Make the future less painful
- 202308281423 Ship of Theseus
- What makes a pragmatic programmer?
- 202308271610 Quarry workers' creed
Chapter 1
- 202308282340 No broken windows
- 202312091400 Be the exemplar of change
- 202312091413 Know what's good enough
- Think critically
Chapter 2
- Good design is easier to change than bad design. Almost all other patterns boil down to "easier to change" or ETC or 202205031449 Optimize for change or 202204262114 Write code that's easy to delete, not extend.
- This is a value (spectrum) not a rule.
- This is why I don't like frameworks that lift a lot (tailwind style string classes everywhere in code) or rails magic. It's everywhere and pervasive and not good. Or things w/lots of non-standard tooling (bit or graphql)
- 202312091434 Have a single source of truth for invariants
- 202312091440 Eliminate effects between unrelated things
- 202312091445 Rely on what you control
- 202312091503 Make reversible decisions quickly
- 202312091517 MVPs should be vertical slices
- 202312091520 Your language limits your world
Chapter 3
- 202312091526 Get good with your tools
- 202110221653 Always bet on text
- 202312091531 Start at square one when debugging
- 202312091534 Write a failing test for bugs
- 202312101839 Think horses, not zebras
- Pick a strong text manipulation language as my tool of choice and get really good at it (awk, sed, ruby, python, js?) (98)
- Use real debuggers sometimes. Know how to dig deep. (99)
- Engineering daybooks are cool: sketches, observations, notes (100)
- journaling notes?
- be more free with my journal, doodle more, use the space off the grid
Chapter 4
- Design by contract (104–112)
- Preconditions, postconditions, class invariants
- caller's responsibility to call correctly, but do I agree? I code my stuff assuming no one will use anything correctly (110)
- Semantic invariants guide error handling (sem. inv. "err on the side of never processing twice" leads to code that will bail instead of get to a place where that could happen)
- Dead programs don't mess up more things/data. (113–114)
- Use supervisor that knows what to do. But how? K8s is kind of that. Aren't exceptions this same idea? crash, unwind stack, handlers are localized supervisors on how to proceed. But they present the idea of crashing as opposed to handling exceptions. They want to unhandle and crash.
- Clean up after yourself (rust style resource ownership) (118)
- Take small steps always. Rate of feedback is the speed limit for your changes. Tasks are too big if they require predicting the future. (126)
Chapter 5
- Decoupled code is easier to change (130–131)
- Tell don't ask. "You shouldn't make decisions based on the internals of something and then update that thing." Instead, tell the thing itself to do that update so it continues to own itself and its responsibilities (132)
- Writing reusable code is much more important than ever reusing it (135)
- APIs, DBs, etc. are global/shared data/state (136)
- Events are a powerful way to manage the real world and the time based streams therein (137)
- Programs are about data: inputs, outputs, and transformations (141)
- Use Monads! (155)
- Instead of inheritance use interfaces and protocols, delegation, and mixins/traits (not convincing on mixins how they describe it) (161)
- Parameterize your application using external configuration (166)
- Recommend APIs that call for config as needed and can change app behavior without restarting (thing feature flags)
Chapter 6
- Use activity diagrams to identify workflows/concurrency (172)
- Concurrency is hard (180)
- Use actors. But how does that work with multiple copies of your app. It can't? State has to not be shared at all? (185)
Chapter 7
- Listen to your instincts (lizard brain, gut etc.) take a walk, step away, sleep on it, etc. (192)
- We cannot program by coincidence. "Idk, this is what made it work" is a horrible attitude. (197)
- "Close enough isn't" (197)
- Rely on documented behavior only, never on internals or undoc. (197)
- $Big;O$ notation is great but for small $n$, things are usually different (208)
- Software is more like gardening than construction (210)
- Refactoring should not change external behavior and requires automated testing to verify (211)