Programming
Languages
Languages I Like
- C
- Odin
- Go
- Lua
Languages I Tolerate
- Python
- Regular Expressions
Shells I Tolerate
Programming Ethos
Shallow
Function calls should not beget function calls. Code that is shallow is easier to read later and as a fun bonus, it's almost always faster because deeply buried, emergent performance hotspots are very hard to create by accident when everything is one or two layers deep and easily legible.
Composable
Expose everything and design for composing. By all means, create 'off-the-shelf' procedures to do common tasks, create high-level components or even whole pipelines, but never allow these to be the only components you expose.
- Forest is an example of this philosophy. It contains several pre-composed pipelines that can be hacked on at the highest or lowest levels. They're simply quickly available shortcuts, built from all the same primitives the library exposes in the first place that may be used in their own right, easily extended or entirely replaced without consequence.
- Lena is designed to be composable, but does not contain many pre-composed elements. Almost all procedures do what they claim to do without indirection or internal abstraction.
Few attachments
Keep the number of external dependencies low. Regularly audit them for better, simpler alternatives. Examine if porting the narrow segment you actually use into your codebase directly would benefit you. Always vendor clean copies of any dependencies directly into your repository. It's almost always better to write your own minimum-viable solution to most problems anyway1.
- Most of my software is an example of this philosophy. Meander, Sous Chef and Forest all have external libraries and dependencies, but with the caveat that while they are time-saving for me as a programmer — usually saving me from unattainable complexity — they could be replaced with a bit of hard work if necessary.
Build Systems
Don't do them. Build systems should be no more complex than a shell script.
Programming Styles
Data-Oriented Design
Data-oriented design is the primary paradigm of code structure I write in. After a decade of programming, I've landed on it as both the simplest paradigm to understand and explain (at the highest level of writing data and structures followed by procedures to transform them), while also producing the simplest and most readable code, regardless of the complexity or scale of the program. Programming in a data-oriented fashion before you even get to the meat of SIMD-optimised data layouts inevitably leads to the shallowest, easiest to read code.
People are often offput by the requirement to deal with data in unusual layouts, but the reality is that that once you pivot to thinking about what problem the CPU is solving in this moment instead of the high level human-scale problem, it becomes very obvious. It's 'let's transform a thousand vertices by x in one fast operation' rather than 'let's iterate over all these objects and move them on the screen by x'.
The first one is a problem that's extremely easy to optimise without additional effort on your part: you're giving the compiler and CPU a freebie. The other encourages you to 'get all the objects' and slam your cache line by requesting masses of data only to manipulate one tiny part of it.
Literate Programming
Literate programming is a programming paradigm introduced by Donald Knuth. The basic idea is to write a program in the form of documentation, which is to say using English (or language of your choice) comments to create a full-text explanation of the program. The program's executable code is then peppered through the program's executable code in between these passages, almost like an inline example. When compiled, the 'snippets' in between the documentation add up to a full program.
I don't believe I'll be writing any truly literate programs any time soon, but I do strongly believe there is some advantage to the average programmer, engineer or technician's creative thought to write things out. Similar to rubber duck debugging, just writing a statement of intent, or even producing extensive notes about an idea and refining them into some kind of essay about the program before writing the program can be an extremely productive activity. I've never done this to the nth degree while programming personally, but I have many times rubber-ducked a programmed solution to a problem out loud, before attempting to program it, as if explaining it to an audience. Writing (or speaking) while in flow state naturally spawns further ideas and encourages the mind to search for solutions to obvious gaps, something that Knuth points out specifically as a benefit of the system. It's pretty hard to justify continuing down a path after writing documentation that says it's poorly thought out or hacky.
- Although obviously, never play fast and lose with cryptography, your users' personal data or their transactions and payments. ↩