General by Rino Jose 5 min read

Making the Coding Category practical using Forthic

While the Coding Category we described earlier is far more concrete than anything from abstract math, it isn’t really practical for coding work. Each of its transformations works on a single data object and creates another data object. Real coding is messier: we need to pass arguments around, we need to worry about state and side effects, we may want to break words down into smaller components and reuse them for new applications. While these are the things that a general purpose programming language handles, we can still keep things fairly abstract.

So how could this work? If you’ve ever used an HP scientific calculator, you’ll be familiar with the concept of “reverse Polish notation” (RPN). The idea goes like this. Rather than viewing the sum of 2 and 3 like you did in first grade (i.e., 2 + 3), think of it in terms of a transformation: 2 3 +. The 2 and 3 set up the input objects, and the + is the transformation. The simplest way to implement this is to use a stack: push 2 onto the stack; push 3 onto the stack; execute +, which pops the 3 and the 2, adds them and pushes 5 onto the stack. You can perform any calculation like this. One of the crucial benefits of this approach is that you can chain these transformations together like 2 3 + 4 * 5 /, which is starting to have the same vibe as composition in category theory but with the ability to pass arguments to generic transformations like +, *, and /.

Defining the Forthic Category

We could generalize this further and support words beyond arithmetic. We could add words that manipulate and access state. There’s actually a high-level programming language called Forthic that was specifically designed for this. Forthic words could be viewed as morphisms in a category; the objects would be Forthic interpreter states, which includes a stack as we had above, as well as variables for maintaining state. This extension of the coding category allows us to write real code and design real programs categorically. Since it’s based on Forthic, we’ll call this the “Forthic Category”.

The Forthic Category allows us to do everything we could do in the Coding Category, but in a much more flexible way. For instance, instead of requiring a word like GROUP-BY-ASSIGNEE to exist, we could construct it dynamically from a word like GROUP-BY-FIELD: "assignee" GROUP-BY-FIELD. In fact, if we wanted to group by priority or by project, we could construct these words on demand using GROUP-BY-FIELD. We could even define new words in terms of these compositions. Here’s how we might define GROUP-BY-ASSIGNEE in Forthic:

: GROUP-BY-ASSIGNEE   "assignee" GROUP-BY-FIELD;

Forthic was designed for Categorical Coding

Of course, this leads us to wonder where GROUP-BY-FIELD comes from. Is this also composed from simpler words or is it a primitive of the language? This is really a design choice and a matter of taste. For instance, the FORTH language (which was the inspiration for Forthic) focused on one extreme where it’s FORTH all the way down to the metal. There are extremely low level words in FORTH for manipulating things at the hardware level. In FORTH, everything is composed from FORTH words. Forthic takes the opposite view and is focused entirely on the highest level of the app. A Forthic runtime cannot exist without a host language and is actually not a general purpose language. The goal of Forthic is to express categorical solutions to coding problems. Forthic words can be implemented in the host language at as high a level as you like; it’s really up to the engineer to decide how to best solve the problem. As a rule, Forthic code should read as a sequence of transformations. If it starts getting too convoluted, you probably need to implement some higher level Forthic words in your host language.

Using Forthic, we have a practical way to write code categorically to solve coding problems. Its concatenative model lines up perfectly with composition in Category Theory, even better than standard mathematical notation since the order of transformation reads naturally from left to right (F G H) instead of going backwards like $H \circ G \circ F$. Forthic can handle the messiness of real coding because it sits on top of a host language and uses a stack to pass arguments implicitly between words. Forthic has access to anything the host language can do (including all of the host language’s paradigms). It brings categorical coding to its host language.

Closing Thoughts

We’ll have more to say about Forthic and how to use it, but for now the important thing to understand is that it makes Category Theory implementable and executable. It allows us to model problems using categorical constructs and gain insight into how to solve problems by understanding the relationships within them. In our next post, we’ll go into more depth around what it means to solve coding problems by looking at how we solve problems in general.