Writing 12 programming languages in 2023, part 2

Heyyyy, long time no see. I'm still working on this project, even though I haven't checked in here. Hope this entry finds you well. I should probably just get into the language, but I feel a certain obligation to account for my time.

Before that, a short recap of the project:

  1. I think I want to work on programming languages. I used to think that I would have to get a PhD to do this, but instead I've decided to just do it.
    Even if I decide I don't want to work on programming languages, I can't know without trying.
  2. It's hard to get a job working on a programming language. Languages are high leverage tools and network effect is the most important factor in picking one for a project, so there are relatively few jobs working on them compared to websites and stuff. I get to do some language-type stuff in my job (for which I'm very lucky!), but if I want to work on more impactful language stuff I need to develop the requisite skills outside of my paid work time.
  3. To that end, I've devised a project wherein I:
    1. Read Beautiful Racket, a book about writing small languages
    2. Write 12 small languages in the year 2023
    3. Write about the project here

As of last time I had read about half of Beautiful Racket.

The timeline since last article

Here is the timeline since then:

A drawing of the timeline since the last 12lang post
  • Feb 2, Published the last post
  • Feb 18, Arielle's website project
  • Mar 8, Finished the book (but it took longer than I might have wanted)
  • Mar 8 - Mar 23, Try to write an article about the book, but what? Think I should really be working on the language. Feel bad.
  • Mar 11, Get distracted developing a PAO memory system
  • Mar 14 - Mar 24, Stuck in text editor anxiety hell
  • Mar 26, Actually start working on the language
  • Apr 9, Today (Now it's April 13th actually, wasn't able to edit on the 9th!)

I don't have much more to say about it than that actually. Sometimes I need a break. Also it's hard to work on stuff I care about. Maybe some day I'll write a post about that.

Okay, on to the language.

Overview of AMAL

Background

Arielle has a personal website, mostly for her writing work. She wanted to put a poem on the front page of the website. She didn't want the poem to just sit there though, she wanted it to be a spectacle. She wanted it to look as though she was typing the poem out letter-by-letter for whoever visited the site.

She came to me for advice. I thought we could accomplish this effect with CSS animations. It turned out to be too much of a pain in the butt. We ended up just recording her typing out the poem and turning that into a GIF.

The idea stuck in my head though. Why shouldn't there be an ergonomic animated markup? Thus, AMAL: a language for animated markup (in Markdown, for the non-animated parts).

Design

AMAL, or the Arielle Markdown Animation Library is, essentially, a preprocessor of Markdown that provides syntax for using CSS animations. CSS animations can be hard to write, so the idea is that AMAL comes with a library of prewritten animations which can be plopped into any Markdown text. AMAL also provides users the ability to change elements of animations or use entirely custom animations.

For example, this piece of AMAL:

@ type-and-erase Hello! @

Produces this HTML and CSS animation:

Animation arguments can be placed between the name of the animation and the body of the text, like so:

@type-and-erase animation-duration: 4s Hello!@

This produces CSS with the specified animation-duration

Here is a breakdown of an AMAL expression:

A diagram of an AMAL expression showing @ delimiters on each end, a name as the first element, followed by arguments, followed by the body of the text to animate.

The implementation plan

My plan for implementing AMAL rests on the fact that HTML can (usually) be embedded in Markdown.

I will:

  1. Convert AMAL expressions to the associated HTML and CSS
  2. Let everything else pass through unchanged
  3. Pass the resulting string to the existing Markdown package to turn into HTML

I don't love that this means the language has to go through two passes: AMAL -> Markdown (with embedded HTML) -> HTML. It seems like I should be able to convert it all to HTML in one shot. Given the time constraints though, I think this is the prudent way forward.

Unfortunately, even given this design, I am not finished.

Turns out that writing programming languages is hard

I admit that I didn't exactly set myself up for success by starting six days before the end of the month. Since then I've been working pretty hard on the language! (ask Arielle) Unfortunately I'm not done, and not just because I haven't fleshed out the animation library. The language doesn't work at all! The example above uses handwritten HTML!

Turns out that designing and writing a novel(-ish!) language is harder than copying languages from a book. Oops. I expected this but uh, well, I was optimistic. So I don't have a language (yet). What I do have is a parser.

Parser problems

We can think about a programming language as a recipe. Each step produces output that feeds into a later step. The first step in this analogy would be opening the recipe (sending code off to compile). The last step in this analogy would be eating (the compiled program doing whatever it's supposed to do).

Parsing is the mise en place of writing a language. It's prepping the ingredients for the more involved cooking coming up. Expansion (in the case of writing a language in Racket) is the actual cooking. So I've got my bowls full of carrots, celery, onions, etc…, but I still need to actually turn them into soup.

An example AMAL parse tree
My ingredients

I had a hell of a time figuring out how to slice my carrots. Eventually I settled on the design in The implementation plan, but I spent a lot of time thinking about different plans, implementing them, then testing them only to find that they wouldn't work for one reason or another. You can read my inane ramblings in the work log if you want more background, but ultimately I had to relearn a few lessons I am always relearning:

  1. Spend more time than feels comfortable on design. Try to validate ideas in the design phase!
  2. Spend more time than feels comfortable reading. Reading is great. It gives me so many ideas. It often feels like a waste of time. It's almost never a waste of time.
  3. Test at a granularity that feels superfluous while building. I'm able to skip this more in domains where I feel comfortable, but working on a language in Racket I really don't know what's going on without a short feedback loop.

Next steps

So I still have to cook the soup.
Which is to say, give meaning to the collection of ingredients I've assembled.
Which is to say, write the expander.

I hope to have a language that people can actually use by next month. But I wanted to put something up here in the mean time. It's easy to get discouraged when I'm not making progress as fast as I'd like and think about quitting. Publishing makes that a little bit harder :)

Subscribe to Buncha Nonsense

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe