October 7, 2025

Aslan French

A UX designer designs a programming language

Hi, I’m a UX Designer and I made my own programming language. Here’s why and how:

Around 2018–2020 I was taking programming courses online. I’d get frustrated, confused, or find a particular way of doing things ugly. I needed a creative outlet, so I would vent that frustration by writing a document describing a programming language of my design. I had no intention of implementing this language, it was just a toy to help me better understand what I was learning.

But now I have implemented it!

(a toy interpreter in the Python runtime using a custom AST, parser, evaluator, REPL CLI, and file runner with a vscode syntax highlighting plugin.)

What does it mean to design a programming language?

Unlike natural languages, every programming language that exists was designed by someone. As a UX designer it kind of makes sense to be interested in programming language syntax design. Code is the ultimate user interface, it is literally the most fundamental interface between humans and computers, the foundation on which all others are built.

Programming languages can have a lot in common with natural languages. Older languages influence newer languages, there’s mixing and matching, loan concepts, stylistic approaches. It’s easy to think of programming languages as purely logical objective tools. In reality, programming languages are as much social and expressive constructs as they are technical ones. They form a medium through which humans communicate ideas to computers and to each other. In fact, computer languages have a dual nature: they are mathematical constructs and “social constructs” shaped by human culture and community1.

It occurs to me that my fantasy programming language project is sort of similar to what Tolkien did as a philologist making elvish Quenya or Sindarin. Unlike Esperanto (another famous constructed language) which sought to construct a new language for a designed purpose, a goal, a problem to solve, Tolkien’s works were aesthetic explorations of grammar and syntax for his own enjoyment, and expression of his perspective on the world.

I don’t pretend that this language is anything more than a sort of weird art project. I did this because it was interesting to me and helped me test things. This language will never be used in the real world, even by me. I don’t make any claim that it is better designed, or superior to any existing language, aesthetic or otherwise.

The language project Quorum (which sparked some of my early interest in syntax design), seeks to design according to the best empirical evidence. Enzo does not. It’s based on what I thought would be interesting, cool, or aligned with my heuristic design principles. Enzo reads well to me. Me. I mean I designed it, so of course it reads well to me. I spent hours and hours writing it, researching other languages in order to expand it, and then finally implementing it in an interpreter. Enzo is expressive of my point of view.

Generative Design and Development

I started designing the Enzo syntax in 2019, prior to the widespread use of LLMs, as a tool to help me learn stuff. The way I got the idea to try and actually implement Enzo was when I was taking a Javascript course and was trying to wrap my head around destructuring. I had trouble reading the syntax, and so I fed an LLM the markdown language spec doc I’d been working on, and asked it to give me an example of what destructuring would look like with a syntax in the style of Enzo. Seeing a new concept expressed in a syntax I had designed helped me understand it, and playing with the generated variations alongside comparative analysis research gave me ways to extend the rules further.

Simple example of a function definition and its use in a pipeline data flow construct.

The design workflow that came out of this was simple: Define spec in human language as best I could, generate extensions of that spec to fill it out, and hand select variations that fit best. The term “generative” has gotten thrown around a lot in the last few years, but when I describe this workflow as “generative design” I mean it in the sense as used by Brian Eno in his generative music work. A small set of rules can have a huge number of possible outcomes, far too many for any single person to see. Generative workflows allow us to sketch out a huge amount of combinatorial space. Eno likened his process to “gardening, not architecture”, plant the seeds and then prune.

Brian Eno, pioneer of generative music

This generative process was not restricted to the design workflow but overlapped with the LLM assisted development of the syntax implementation. I initially hand wrote much of the example Enzo code when defining the spec, but to implement I needed to write test cases, and would often generate Enzo code for these test cases. If I was adding a new feature I would need to write integration tests to show how syntax features interacted, and these interactions would often not have any prior examples in the spec (since the spec attempted to be pretty atomic). In turn, these generated integration tests raised new questions that needed answers in the form of careful design decision pruning.

Sneak peek at the custom types syntax, which focuses on composition over inheritance.

I’ll go more into my design process, the unique features of Enzo, the specifics of how I implemented the interpreter, and some thoughts on how this process has changed how I look at the future of product work, in future posts. I’ll link those here once they’re written.

In the meantime you can play with Enzo right now, in your browser using this Google Colab notebook.

End Notes
  1. University lecture slide notes talking about this in more depth. ↩︎