Controlled Shell, Generated Core
Sometime around 2012, Gary Bernhardt started talking about the program design “functional core, imperative shell”. It had a pretty big impact on my own programming style.
It’s a style which is well suited to python, especially when you learn that modules can be treated like lightweight encapsulation instead of leaning on classes. Essentially you write lots of independent groups of functions and then stitch them together in main procedures in a more imperative style. It’s a bit like relaxed functional programming.
With AI augmented programming we can revisit many topics of programming design and philosophy. Which ways of assembling code lead to effective and safe outcomes and best leverage the potential pace of generating code?
One I’ve been thinking about and experiencing is drawing on the functional core and imperative shell ideas.
There’s plenty of talk about top down, vibe coding. It’s interesting but I keep finding it goes off the rails for larger scale work for which I want to maintain and understand over time. So I get in these loops of vibe and refactor when I’m lazy up front or too top down. It’s plenty effective though.
A different approach, which is a little less nonchalant, is if you work bottom up. Think and design the data structures first if you can. Work out the general organization for some code, maybe a sequence of key steps. Then generate each function one at a time. This allows for leveraging the tab models in tandem with agentic generation.
It’s hard to relinquish control of the internal implementation of code at times. And it’s necessary to control it when there are risks at play.
So maybe that’s where some of the more formal AI programming is headed:
Controlled shell, generated core.