u 0.0.1 release

Published on 2024-03-17, 718 words


u is a functional programming language based around unary operators. I started working on it for fun at the very beginning of 2024. The v0.0.1 release includes a REPL ur that can run all the examples in this blog.

The source code is on Github.

What’s a unary operator?

A unary operator acts on a single argument, like a number. The increment operator ++ is an example of a unary operator - it “takes” an integer and increases it by one:

y = x++;

The gimmick

u has a simple, terse syntax. Each line of u starts with a value (like the number 10), then a chain of operators are applied left-to-right. For example, this program applies the increment operator (+) five times to the number 10, yielding a result of 15:

10 + + + + +;

For comparison, here’s the equivalent program in C:

#include <stdio.h>
void main() {
   int x = 10;
   x++;
   x++;
   x++;
   x++;
   x++;
   printf("%d", x);
}

Other language features

Repeater operator

The repeater operator {N} repeats the subsequent operator N times. For example, these two programs are equivalent:

> 10 + + + + +;
15

> 10 {5} +;
15

Decrement operator

Does the opposite of the increment operator - subtracts one:

> 10 - - -;
7

Variables

Variables are immutable (assign-once).

> 99 $bottles_of_beer_on_the_wall;
99
> $bottles_of_beer_on_the_wall {1} -;
98
> $bottles_of_beer_on_the_wall {2} -;
97
...
> $bottles_of_beer_on_the_wall {50} -;
49

Strings

The language also supports strings. The increment/decrement operators replace each letter in the string with the next or previous letter in the alphabet:

> "abc" +;
bcd
> "xyz" -;
wxy

This can be used to implement Caesar Ciphers.

> "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG" {3} -;
QEB NRFZH YOLTK CLU GRJMP LSBO QEB IXWV ALD
> "QEB NRFZH YOLTK CLU GRJMP LSBO QEB IXWV ALD" {3} +;
THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG

…Why?

I’ve always wanted to give compiler development a try, and I thought it would be fun to come up with a language that is novel, elegant, and yet extraordinarily useless. Working on a language that (as far as I know) no one has written before meant that I was on my own - but the syntax was so dead-simple that I was able to successfully do it.

The parser/interpreter that I wrote are structurally “by the book”. There’s a lexer that generates a stream of Tokens, a syntax analyzer that shapes the stream of Tokens into an Abstract Syntax Tree, and finally an interpreter that traverses the Abstract Syntax Tree to actually execute the program.

Some math context

Those who work in the world of formalized arithmetic know the increment operator as the Successor function. Over 100 years ago, Giuseppe Peano and others showed that with a few axioms, the number zero, and the Successor function, one can formally derive many of the things we intuitively know about Natural Numbers, including arithmetic operations like addition and multiplication.

With u, I can start from the same building blocks. From 0 and +, I can represent an expression like 3 + 5:

> 0 +++ +++++;
8

The repeater operator is just a more concise notation for the same thing:

> 0 {3}+ {5}+;
8

And the repeater operator can repeat itself - thus multiplication!

> 0 {5}+ {5}+ {5}+;
15
> 0 {3}{5}+;
15

They can be used in combination. Here are a few ways to express the binomial (2 + 3)(4 + 5):

# Addition first:
> 0 {5}{9}+;
45
# Distribute over the left product: 2(4+5) + 3(4+5)
> 0 {2}{9}+ {3}{9}+;
45
# "FOIL" (2*4 + 2*5 + 3*4 + 3*5)
> 0 {2}{4}+ {2}{5}+ {3}{4}+ {3}{5}+;
45

To be clear, I didn’t intentionally set out to build a language to model foundational mathematics. I just wanted to build something novel and easy, and happened to stumble on something interesting!

What’s next for u?

Some ideas for the future: