Code shouldn’t be ugly. It generally shouldn’t be pretty, either.
Everything makes me happy in proportion to its similarity to the hunt or the
military campaign. Also cats. End of list.
Rote memorization gets a bad rap, but it’s useful to think of it as analagous to
cache warming. It’s a strategy for reducing recall latency, which helps keep
your feedback loop tight.
The best mentoring someone can offer is to expect efficient bootstrapping.
A great way to lose credibility with someone is to tell them their truth is
false when it’s actually just incomplete.
Good design is as much a function of intelligibility, which in turn is a
function of a variety of human factors and local context, as it is about
flexibility under changing requirements. Given two equivalent
implementations, one more elegant but also more reliant on knowledge of
language idioms or design esoterica, one’s bias would naturally be toward the
more elegant one on a team familiar with those or invested in learning them, and
toward the more workmanlike one on a team that’s optimizing on other priorities.
(Interpret team under the sign of Heraclitus: the same group of people is a
different team from one moment to another.)
Good intentions are worth their weight in gold.
Writing Lisp is intensely satisfying in a way that’s hard to describe. Doing
anything complicated in a functional language gets painful earlier, so you’re
forced to abstract away complexity with less conscious effort than it takes in
an object-oriented one. There are fewer temptations to design beyond realistic
needs, and no importing of a design pattern’s attendant conceptual baggage or
latent constraints, which can end up becoming hazardous in the long run. The
syntax lets you focus on the heart of your problem. Compared to especially
expressive languages, there’s no cognitive overhead from needing to choose
between three or four different ways to express the same logic. Everything leans
hard in the direction of simplicity.
Pretty much everyone I’ve worked with closely has had some gift, some
exceptional ability or inclination, that I really appreciated about them. A
knack for debugging, an intense bias for simplicity, a willingness to either
break or carefully improve things no one else wants to touch (code, conventions,
habits). In a strong team these predilections are superadditive, modulo the
efficiency of collective information processing. But one of the ur-skills for a
coder, and probably the skill I admire the most, is change-discipline. The
metaphor for software development most commonly operative for me, somewhere in
the depths of my consciousness, is of a bounding fire-team.
Software engineering is a lot like macroeconomics in that (as with most
knowledge domains) the underlying phenomenon is high-dimensional, so in practice
we employ simple models that are only reliable under strong assumptions but
(unlike most knowledge domains?) both suffer from a pretense of knowledge
problem driven by a combination of economic incentives, epistemic naivete, and
physics-envy (or something akin to it, in the case of the former).
Much of what constitutes expertise in the field is less knowledge than folk
wisdom, with a short shelf life and tight bounds on applicability. Situation
normal. We enter failure modes when we don’t attend to this provisionality
(consider, e.g., fetishized best practices, the risible claim that the tech
interview is a standardized test, vulgar meritocracy in hiring and promotions).
“Strong opinions, loosely held” degenerates into “cheap talk, loudly voiced.”
It’s not as catchy but I prefer something along the lines of
“Well-informed opinions, held as tightly as warranted by the context.”