DEV Community

Josh Holbrook
Josh Holbrook

Posted on

I'm Publishing Matanuska BASIC's ADRs

I recently posted the first ADR from a project of mine and scheduled many others (up to 17 and counting) over the next few months. I wanted to take the opportunity to offer some context and background on these ADRS - what is this project, anyway?

In short: one of my major passion projects right now is writing a BASIC interpreter. As mentioned, it's written in TypeScript. You can check out the project here:

https://github.com/jfhbrook/matanuska

I've always wanted to write my own programming languages. I really, really like language design! But until recently, I felt like it was a problem out of my reach. But in recent times I felt inspired, and I decided to take the plunge.

Part of that inspiration was learning about parser combinators, particularly Rust's nom library. Of course, parser combinators - particularly in Rust - presented a bit of a learning curve. But this incredible post by Bodil Stokke really helped me understand how they worked, and made me feel empowered. In fact, for small DSLs, I often use parser combinators - for instance, with ts-parsec in TypeScript and parsy in Python. If you want to dip your toes in and have a head for functional programming DSLs, this is a great direction to go in.

But one thing that really helped me get to the point where I felt comfortable writing a "real" language is the book Crafting Interpreters by Robert Nystrom. A lot of the classic resources are old textbooks, such as the dragon book - too dense and academic for my tiny goldfish brain. But Crafting Interpreters is very hands-on and practical, with modern techniques used in real compilers. For instance, it teaches how to write a recursive descent parser, as well as a bytecode VM. I worked through the entire book, porting jlox to TypeScript and writing my first non-trivial C program in the form of clox. It's really an incredible book, and I can't recommend it enough.

Another book I found incredibly valuable is Writing Interactive Compilers & Interpreters by PJ Brown. This is an interpreters book from 1981, and while it doesn't strictly use BASIC as its bedrock, it does come to the table with the philosophy and sensibilities that would show up in a period-appropriate BASIC. It's definitely dated, and not as specific or examples-driven as Crafting Interpreters. But it does have a lot of really good advice in terms of architecture and best practices - and is well-written to boot. It's a fantastic read, if you can get your hands on it.

But why BASIC?

One of my hobbies, particularly during the pandemic, has been retro computing. I watch a lot of retro YouTube - Adrian Black, Gravis, Noel's Retro Lab, Action Retro, 8-Bit Guy and Usagi Electric are all favorites. I also built an RC-2014 from a kit, with my own hands - an extremely cool project with a fantastic community.

When interacting with this sort of thing, you will quickly observe that the typical interface to a home computer in the early 80s wasn't DOS, but BASIC. If you boot up a Commodore 64, for instance, you'll boot to a BASIC prompt. Through C64 BASIC, you would do just about everything you would do with DOS - for instance, loading programs.

But as we all know, DOS won. My read on this is that the big change was the introduction of disk drives. DOS, after all, stands for "disk operating system". Something DOS makes really seamless is navigating and operating on a file system. BASIC, meanwhile, was used prior to widespread file systems - the Commodore 64, for instance, tended to use tape drives and cartridges. When file systems became the norm, BASIC implementations began adding file system support - MSX BASIC, for example, has Disk BASIC - but DOS had a strong advantage in terms of making disk access feel "natural" and "native". In BASIC, meanwhile, this felt "bolted on". At the end of the day, DOS out-competed BASIC during this paradigm shift.

The retrofuturist in me likes to imagine an alternate universe where BASIC was able to succeed in this environment. Suppose BASIC was able to develop a disk interface that had the ergonomics of DOS. Or suppose that, like Visual Basic, these REPL oriented BASICs supported modern features like classes. Could we be using BASIC today?

You can see some hints of these in fantasy consoles, such as BASIC8. BASIC8 in particular supports many modern features, such as classes and coroutines, and has fine-grained file support.

But these fantasy consoles are aimed largely at the classic BASIC use case of writing simple games. My interest, meanwhile, is in replacing my shell. I want a BASIC that can be a useful, productive stand-in for bash. In this sense, I'm actually more influenced by new-school shells like nushell, elvish and PowerShell.

Matanuska BASIC is my attempt at just that. My goal is to write a language in the BASIC family which feels like an old-school BASIC from the 80s, but which has the features of a modern shell - along with the extra bells and whistles that make languages like PowerShell so exciting.

So - what about the name?

Many BASIC dialects are named after either the platform they run on, or the developers of said dialect. For instance, MS BASIC is authored by Microsoft, and MSX BASIC runs on MSX machines. I wanted to give my project name the same general structure. But I didn't want to call it "Josh BASIC" - I wanted to give it a name that felt a little industrial, but also personally meaningful.

I'm a born and raised Alaskan. I grew up in the Matanuska-Susitna Borough, and I currently live in the Matanuska Valley. Home is where the heart is, I suppose. But the people here are also industrious, a value I wanted to reflect in my language. Hence, Matanuska BASIC.

This leads me to today. Matanuska BASIC is still an ongoing project - I have a REPL, "hello world", and if/then/else. But I don't have control flow, functions, or any of the shell features I crave. I have some great infrastructure for building those things, but more to come. I'm at 16,000 lines of code and counting.

$ npm run report               

> matanuska@0.0.1 report
> ./scripts/report.sh

======== line counts ========
project                    count
--------                  ------
main                       14712
packages/citree              707
packages/entrypoint          139
packages/fireball            245
packages/grabthar            704
packages/test-generator      187
total                      16694

=== word counts ===
project       count
--------     ------
README         1011
adrs          14387
adrs/drafts    2846
total         18244

=== artifact sizes ===
size             file
----    --------------
 88K    ./dist/main.js

Enter fullscreen mode Exit fullscreen mode

In the process of writing Matanuska, I also began writing ADRs. I did this for my own sanity. Matanuska is a large project for a single developer with a development lifecycle spanning over years (my first commit was in November 2023). This introduced a number of challenges that were helped along by ADRs, even if I was the only one to read them.

Even when diligently documenting my major decisions, there are many whose origins I simply don't remember. For instance, I found myself looking at how I currently parse number literals, and I don't remember what the code is trying to implement. Perhaps I followed JavaScript's format in the name of expediency? It looks like it, but I didn't write it down, so I technically don't know.

There are also many decisions which were simply difficult to make. For instance, the LET keyword in BASIC is used to both define and set variables, but is often optional. Local variables and closures, on the other hand, are generally unsupported. But suppose Matanuska BASIC supports closures. Should let be used to declare new variables, like in JavaScript? Or should let be dropped from the language in favor of semantics closer to Python? This seems like a simple decision. But it's one where I truly needed to weigh the pros and cons. ADRs help me work through those decisions, by writing the arguments down.

I found over time that I was writing a LOT of ADRs, some of which I think are pretty good. But, due to the solo nature of Matanuska development, I was the only one that saw them. Meanwhile, my blog has been collecting dust. I thought it would be fun - and a good idea - to share these ADRs with the greater community. I'm particularly excited to share some of the architectural decisions I made about Matanuska!

I've scheduled these ADRs to be posted twice a week over the next couple of months. Once that schedule runs out, I'll be publishing them here as I author them. May you find them interesting.

Top comments (0)