6 Coding Style
I have developed a very specific way of writing code over time. While extending an application causes a collapse in discipline in order to get things done, I do try to stick to it where feasible. With the rise of coding LLMs, this task has become a lot easier. I can write what I want and then have it review the codebase and fix it according to my guidelines.
While my guidelines are often project-specific, the following is a good baseline to follow and gives me maintainable code.
Basic Code Guidelines
- Use SRP/DRY
- Functions + immutable data structures > objects with methods
- Fail fast: no defensive programming, no backward compatibility, no provisions for migrations
- Loose coupling: touching one part of the system should not have a cascading effect across the entire system
- No global mutable state. Thread a
State/Environmentobject through as the first parameter of every function that needs it. - No stringly-typed code. When used doing hydration/serialization, verify that the strings do not leak beyond function boundaries.
- In client/server architecture, both client and server must share a single contract. JSON/XML payload must be lifted into typed data structures before they can be used.
- No magic numbers or strings. Lift into constants that are defined in one place and used everywhere.
- Unless a branch exits early (
if not x then return y), everyifmust have anelse. Everyswitchmust have adefault. Impossible paths must throw aNotPossibleAssertion, thereby crashing the program. Errorshould only be caught if the function knows what to do with it.
Naming
| Kind | Convention | Example |
|---|---|---|
| Functions | snake_case, noun-first | user_create(), mail_send() |
| Dataclasses | PascalCase | User, VerificationCode |
| Modules | snake_case | email_service.py |
| Constants / enums | UPPER_SNAKE_CASE | MAX_RETRY_COUNT |
Exception Taxonomy
| Kind | Meaning | Handling |
|---|---|---|
| Fault | Unrecoverable (connection loss, HTTP 500) | Expose via banner/terminal in the UI. Never retried silently. |
| Error | Expected in normal business operation (FileNotFound, InvalidCoupon, PasswordTooShort) | Handle explicitly, and report to the user in the normal execution flow. |
| Assertion | API/Function contract breached | Expose via banner/terminal in the UI. Application crashes hard. Never swallowed. |
Error vs Assertion is a judgment call. A 403/404 can mean a genuine dev mistake (stale URL) or hostile interference (tampered payload/route). This must be resolved depending on the application environment: dev vs production.
Exceptions must never be swallowed silently in any of the three cases.
I wrap the above guidelines in a simple prompt:
Do a comprehensive code review of `@src/` and write it to `@docs/<YYYYMMDD[A-Z]>_CODE_REVIEW.md`.
Extract the architecture of the application from the code and write it to `@docs/<YYYYMMDD[A-Z]>_ARCHITECTURE.md`. The elements I am interested in include:
- An intro: what the application does
- Application layout
- The expected shape of the input data, and the output
- Etc
This is more than enough to guide most LLMs to do the right thing.