The Journey to Boba

A post about my in-progress programming language, Boba.

Programming. Debugging. Building. Diagramming. Refactoring. Testing. Deploying. Scratching my head wondering why it all broke.

The above is what I have spent a significant amount of the past third of my life doing. I could loosely quantify it, thanks to hour tracking and GitHub activity graphs, but I'm a little scared to. It's been my education and recreation, both a job and a hobby, both my work and my current legacy. It's nearly always present in the back of my mind.

It seems like it should be less frustrating and tedious than it is!

I got started programming because, like every other tech-adjacent boy of the early 2000's, I wanted to make my own video games. In eighth grade I bought a couple of books that taught young neophytes how to make crude 2D side-scrollers. The first of these I remember distinctly, though I regret that I can no longer find my copy: it was Game Programming for Teens. It taught you in a variant of Basic, which I look back on with amusement now. I quickly moved on to C# after that, at my dad's suggestion. Guess the programming gene is hereditary.

I was lucky to get into a high school that provided a specialized programming track alongside other engineering-focused tracks. This led to an internship with a very cool local hardware startup called MetaGeek and my first experience with professional code bases and development practices. And finally into college at University of Idaho.

For someone who did a lot of math for his education and early career, I never was particularly good at it. I always scored better in English and Latin and reading and writing. In these subjects I learned to love both natural and constructed languages; the popularity of Game of Thrones encouraged my dabbling in conlangs. But college was also where I discovered the beauty of math as a language in its own right. The class that opened my eyes was Abstract Algebra.

I don't know what exactly it was about the way we learned theorem proving in AA that so enamored me. Perhaps it was the puzzle-game-like nature of groups and other algebraic structures. They have a sort of collectible quality to them, like little lawful Pokémon with interesting attributes and qualities.  In any case, I caught on to math in a way I never had before. It wasn't long before I was diving through set theory basics and formal logic.

And then, happiest of all, I was introduced to type theory. After that it was inevitable that I would discover the link between programming as I knew it and formal math, and I was well and truly hooked. Types became a new obsession, and I absorbed as much as I could about the various programming language 'paradigms'. That culminated in an interest in typed concatenative programming languages. I was so hooked I actually wanted to do a Master's thesis on the subject. I ended up at Northeastern University under Matthias Felleisen, a life-changing experience in its own right. I learned about so much more than what I intended during those two years.

In all that time I'd worked in brief periods at a few different places. I knew I wasn't as interested in game development as before, but I'd gained an appreciation for the problems faced by different teams regarding language experience and tooling. The language editor is the toolbox we spend so much of our time using; but the main tool, the language itself, often felt... clunky.

If you're tired of hearing the song of functional programming, best be on with ya. I'll try to spice it up a bit if you're game.

Functional programming was a complete mind-set shift for me. It was totally unnatural at first, and some aspects still are. In most coding problems I face, I think operationally and sequentially; my brain is very wired to the 'and then' notion, the program-as-to-do-list concept that usually finds its home in imperative languages. I understand the goals of declarative programming, but I'm not good at writing code that way.

Instead, what functional programming introduced to me was the comfort and freedom provided by limitations. 'Freedom provided by limitations' may seem like an oxymoron, but the concept is explained in a few sources better than I will here. In my experience, principles like 'immutable by default' and 'no side effects' represented freedom from anxiety and freedom from tedium. Debugging is one of my least favorite activities, but even worse is the potential for hidden bugs that escape QA and violate active users. I value stability in the software I use, so I'd much rather fight with a compiler to get it right the first time than slap assignments together with no warnings and have some little devil slip through.

Still, functional programming can feel like a straitjacket if it's not your first language style. There's an analogy with design patterns: object-oriented programming developed design patterns to regain powerful abstractions that are trivially accessible in functional languages, but they're verbose and kludgy and copy-pasty. Functional programming integrated monads, effect systems and linear-ish types to get convenient assignment back, but the edge cases are just different enough that it's a false affordance: you try to use the new tools like your old ones and then find out 95% of the way through that it won't quite compile the way you want to write it, and that it's critical. You have to rethink the structure of your algorithm to get the compiler to accept it, or to get the behavior you want.

I've since become accustomed to the immutable world and vastly prefer it. Memory is cheap now and garbage collectors sufficiently advanced to make most programs based on these techniques usable. But there's still a number of things missing from most languages that should ease the tedium and annoyance of day-to-day coding.

Eliminating tedious chores and annoyances from the programming workflow is motivation enough to search for new language designs. But there's also the desire to just try something new. It's not a good way to achieve popularity right off the bat: busy programmers have a justifiably small novelty budget when learning a new language. I've chosen to start Boba as a personal project, so I'm not limiting myself too much to what others will find immediately familiar. But I am keeping it in mind because it would be nice to share Boba with others eventually.

As a co-founder of a startup that builds a product that's completely orthogonal to programming languages, Boba is also an escape. It's useful to have a way to keep certain programming skills sharp, a place to think about deep, core problems with wide implications. Programming language design is very rewarding in this way, as even a slight change can have major ripple effects in the way the language is used. And it's an amazing reward too, to write a program in language you've made and have the compiler catch an error you missed while writing it. It's like building your own mini programming buddy that keeps you from wasting your time on silly mistakes.

Good programming, for me who's never gotten the hang of REPL-work, is a conversation with a compiler. Building Boba is like learning a foreign language purely via conversation; when the compiler corrects you, you wonder whether it's a bug in the program-to-be-compiled or the compiler itself. But as the implementation stabilizes, I've learned to trust and be surprised at how helpful the Boba compiler is in preventing mistakes. And when I find it lacking, it's refreshing to be able to just go in and make it better. That won't always be the case, if Boba gets users then there's a community that takes precedence. But for now, its fun watching it take shape in way that's fun and exciting for me.

That's how this quirky little language came to be.

Show Comments