A Month with Antigravity: The Good, The Bad, and The Ugly

I’ve been on paternity leave over the past few months, and between sessions playing with my son, rocking him to sleep, and changing diapers, I made a point to try and stay sharp and learn some new skills. There’s nothing more topical in the software engineering world than agentic AI for development, and I had an idea for a few new greenfield projects, so I signed up for the “pro” tier of Google’s AI infrastructure, downloaded the Antigravity IDE, and got to work on building. I entered with very little experience - I had used Claude with an outdated model a few times, but was essentially entirely new to the ecosystem. I tried out all of the models natively available in Antigravity as I could. Most of my time was spent with Opus 4.5 and Gemini 3 Pro. I gave the less powerful models a try too (such as Sonnet 4.5 and GPT-OSS 120B), but their performance was so far below the two more powerful models that I abandoned their use soon after starting. ...

January 2, 2026

Applying Template Concepts to Tuples in C++

Tuples and Templates In C++, tuples are a collection of values of heterogenous types. You can access different elements at compile time via the get method, while the std::tuple_size and std::tuple_element APIs provide metadata about the collection’s structure. Classes that satisfy this “Tuple Protocol” in the STL - and can therefore utilize the techniques in this article - include std::tuple, std::pair, std::array, and some types in the std::ranges library. When we use templates, the C++ Core Guidelines tell us to specify concepts for all parameters. This article demonstrates a few methods for applying concepts to tuples and their individual elements. While developing Crunch, I had quite a few use cases for applying template concepts to tuples and found some good - and not so good - ways to do it. I did not find any clear explanations of the syntax proposed for those solutions, or how you could arrive at them yourself. I hope that by the end of this article, you feel comfortable writing template concepts targeting std::tuple parameters in your own projects! ...

December 23, 2025

Introducing Crunch: A Message Definition Protocol for Getting Things Right

There are a lot of different tools for defining structured messages and working with their serialized representations for communication over-the-wire. I have worked with open source, closed source, and hand-rolled toolchains tackling this problem. Every tool I have seen has a serious design flaw that makes them very difficult to use correctly in mission-critical contexts. Validation - both of individual fields and of whole messages - is completely decoupled from the message definitions. This is a fundamental gap in how messages are specified. A comprehensive description of what makes a message valid is equally important in system design as the types and names of the fields. ...

December 13, 2025

Can You Survive the C++ Auto Type Deduction Gauntlet?

One of the most iconic C++ features is the language’s ability to deduce types with the auto keyword. In this post, I’ll give a series of code snippits. Your job is to assess what will be deduced for v in each case. Determine for each: The deduced type If it is a value, an lvalue or rvalue reference, or a pointer Which CV qualifiers are applicable Some of these may not even compile, so “this won’t work” is a totally valid answer. ...

December 5, 2025

Implementing a Framework For Closed-Loop Controllers in Modern C++

In this post, we’re going to implement a generic interface for creating a wide variety of closed-loop control systems. We’ll end with a flexible template library capable of implementing whatever control algorithm you’d want, enforced separation of concerns, flexible configuration, consistent error handling, and support for logging. We will use modern C++ infrastructure such as template concepts, std::expected, and lambda functions. Before we dive in, I want to acknowledge that the final code utilizes a good number of advanced C++ facilities for what may appear to be a relatively simple set of functionality. In the course of reading, you may balk at the complexity introduced for the sake of consistent abstraction. Hopefully the culmination of what we have built presented in the last section of the post sufficiently motivates the complexity tradeoff for projects with many controllers or which need to distribute the development responsibilities of the control laws and hardware interfaces across teams. ...

November 26, 2025

Dependency Inversion in C: A Technique for Extensible Embedded Software

The core value proposition of software is flexibility - but in embedded systems, we often lose that advantage. Codebases become tightly coupled to a specific hardware revision, making even small platform changes expensive and risky. As hardware complexity grows linearly, software complexity grows exponentially. Costs rise. Schedules slip. Eventually organizations become resistant to improving their own products because the software architecture can’t absorb change. This risk is avoidable. By intentionally separating the high-level business rules from low-level hardware details, we regain the flexibility software is supposed to provide. One of the most effective techniques for achieving this separation is dependency inversion. In short, lower-level components implement an interface defined at a higher level. Control still flows from high to low abstraction layers, but the dependencies flow upward. High-level code is unaware of how the interface is concretely implemented. In an embedded context, this paradigm allows the software architecture to adapt quickly and cheaply to new hardware iterations without rewriting core logic. ...

November 16, 2025