|Feb 12, 2019||📖||
Distributed systems and time
Failure and time are core to building resilient systems.
|Feb 5, 2019||📖||
Imperative programming and the RPC mistake
Inappropriate uses of sequences and state can be exposed once once we try doing it over the network.
|Jan 29, 2019||📖||
Design follows data structures
Performance concerns can motivate different choices for data representation, but changing representations can be extremely invasive, and OO is often of little help.
|Jan 24, 2019||📖||
What are assertions good for?
As testing practices have evolved, the role and utility of assertions has changed a lot, and I think it'll change some more.
|Jan 15, 2019||📖||
System boundaries and the Linux kernel
A short case study on the effects of freezing or freeing an API.
|Jan 8, 2019||📖||
Book status update
It's 2019! One full year of writing.
|Dec 26, 2018||📖||
Ephemeral model-based testing
Directly comparing two implementations is a powerful testing technique, and we have a second implementation for free surprisingly often.
|Dec 18, 2018||📖||
You should break the Law of Demeter
A kernel of a good design principle, but the law leads to poor outcomes.
|Dec 11, 2018||📖||
Fuzzing vs property testing
These are easily distinct techniques, but also deeply related.
|Dec 5, 2018||📖||
Types are the basic tool of software design
Static or dynamic, a program's design is written in its types.
|Nov 27, 2018||📖||
Going overboard with unit tests
How do test suites become rigid, and impede (rather than help) design?
|Nov 20, 2018||📖||
What would a message-oriented programming language look like?
Some thoughts on Alan Kay's vision of getting rid of data.
|Nov 13, 2018||📖||
On 'function coloring'
How much of a problem is it to sharply distinguish between different kinds of functions?
|Nov 6, 2018||📖||
Different models of concurrency
Approaches to maximizing resource utilization.
|Oct 30, 2018||📖||
Async and Await: concurrent control flow
Building concurrent programs with a minimum of fuss.
|Oct 23, 2018||📖||
Concurrency with just one thread: embracing event loops.
|Oct 16, 2018||📖||
Concurrency vs parellism
The difference, and what is means to design for each.
|Oct 9, 2018||📖||
Testing, induction, and mocks
Oh my. Design for reasoning about code. Testing isn't the only reasoning method.
|Oct 2, 2018||📖||
The insides and outsides of abstractions
Variance affects where you get guarantees and where you get restrictions.
|Sep 25, 2018||📖||
Wishing for better abstraction
A few case studies in designs that lacked the ability to create abstractions.
|Sep 18, 2018||📖||
The design of toolkits and the web front-end
A comparison case study of a few different designs for UI libraries.
|Sep 11, 2018||📖||
Adapting an existing design to suit new purposes.
|Sep 4, 2018||📖||
Stateful MVC: an origin story
A look back to where Model-View-Controller came from, and understanding why it's a thing.
|Aug 28, 2018||📖||
Data as a mediator between computation and state
Tight coupling between computing what action to perform and actually performing that action can make things harder than they have to be.
|Aug 21, 2018||📖||
Abstractions at the boundaries
How do we understand what a module offers us? And what is an abstraction anyway?
|Aug 14, 2018||📖||
Breaking systems into modules
Modularity is how our little human brains can contruct large complex systems.
|Aug 7, 2018||📖||
What does it mean to design software well?
Thinking carefully about what our goals even are.
|Jul 31, 2018||📖||
Why an interface with only one implementation?
Sometimes this is evidence of over-abstracted design, but sometimes it legitimately makes sense.
|Jul 24, 2018||📖||
Design considerations for software security
General advice about what every programmer should understand when it comes to building secure software.
|Jul 17, 2018||📖||
How to avoid being led astray when designing for security
It's easy to focus on the wrong things.
|Jul 3, 2018||📖||
How we go about creating abstractions
Types, abstractions, names, and meaning. A look at interfaces, type classes, structural interfaces, and duck typing.
|Jun 26, 2018||📖||
Why variance matters
Accidental and intentional complexity, and how we reason about it.
|Jun 19, 2018||📖||
All advice comes from a context
Sometimes we're so immersed in context, we don't see it, and good ideas at the time can be mistaken for universal rules.
|Jun 12, 2018||📖||
Whereas types can be pervasive
Testing on system boundaries can aid us in making changes. Testing elsewhere can sometimes impede us. But types can go anywhere.
|Jun 5, 2018||📖||
Small is not the same as simple
Complexity is sometimes the enemy, but smaller is not necessarily better.
|May 22, 2018||📖||
Classifying programming paradigms by their composition operators
A different perspective than I'm used to. Different paradigms offer different pieces and different ways those pieces can be put together.
|May 15, 2018||📖||
Familiar forms of composition
Every form of useful code re-use involves some form of composition operator. We build the whole out of parts, and the seams have properties.
|May 8, 2018||📖||
Deconstructing the "Unix philosophy"
Composing smaller pieces into a great whole is a powerful design technique.
|May 1, 2018||📖||
Designing imperative code with properties in mind
Property testing still applies well to imperative code. While it's usually harder to test the complete interface, this is mitigated somewhat by invariant checking (asserts).
|Apr 24, 2018||📖||
Designing abstractions with properties in mind
Property tests are not just more powerful, more general unit tests. They're a different way of thinking, with a different impact on design.
|Apr 17, 2018||📖||
Using documentation to improve the design of software
We confront our design in several ways when documenting it. We have to explain our decisions, we have to understand our users, and we have to know what the system boundaries are.
|Apr 10, 2018||📖||
The influence of testing on design
Testing can affect our software design, both for better and also worse. How can we be sure it will have a positive effect?
|Apr 3, 2018||📖||
How did we end up with containers?
A short case study breaking down the interesting design aspects of containers.
|Mar 27, 2018||📖||
The design of build tools and dependency management
What can we learn from the design of build tools like Maven? A case study on what works and what doesn't.
|Mar 20, 2018||📖||
Programmer as wizard, programmer as engineer
Context matters. Sometimes we need to get things done, sometimes we need to build things to last.
|Mar 13, 2018||📖||
What can we learn from how compilers are designed?
A case study on how compilers decouple components from each other using data.
|Mar 6, 2018||📖||
Notes on the expression problem and type design
Adding precision, explaining some of my choices, answering 'what about...?', and more.
|Feb 27, 2018||📖||
Design duality and the expression problem
A fundamental question in program design: how is this type open?
|Feb 20, 2018||📖||
What would OOP without inheritance look like?
A hypothetical design experiment, and a look at open recursion.
|Feb 13, 2018||📖||
What's wrong with inheritance?
The over-hyped language feature, and how we should cope with it today.
|Feb 6, 2018||📖||
System boundaries: the focus of design
Efforts must be focused on where the system cannot evolve gracefully.
|Jan 30, 2018||📖||
The one ring problem: abstraction and our quest for power
We often mispercieve something that cannot be done as a problem. But often enough, that's a feature.
|Jan 23, 2018||📖||
Data, objects, and how we're railroaded into poor design
Our programming languages don't really support us in making good design decisions. They fall short of allowing us to choose appropriate representations.
|Jan 16, 2018||📖||
How humans write programs
A standard algorithm for programming and improving the design of our software.