The Struggle with Prefix Syntax

If you’re programming in a Lisp-family programming language, working with numbers is going to be a little bit different.

Some might say that, while it may seem odd at first, you can get used to it.
That is to say, it’s not bad. Just… different.

Prefix means that where you would normally have the operator between operands, you would have only one operator at the very beginning.

In my experience, this is fine for when you need to add or multiply. For some reason that isn’t confusing at all; it really is just nothing more than different.

But for other things like greater-than, less-than, minus, it’s not so simple. When I started out programming in Lisp, I thought prefix syntax seemed to present only a minor difficulty. But now that some time has passed, I’ve given some thought to my experience with it.

And it’s actually mind-boggling how confusing it is.

For example.

(- 3 2)

I would read this as “minus three two”.

Hang on. Let me try to read that again.

(- 3 2)

Minus… three… two.

But wait. What minus three? And then there’s that two…

So is it two minus three?

Nope.

Minus Three Two = Three Minus Two

Huh gif

I now realize it’s almost impossible to get used to because, when reading the code from left to right (as code is usually read) it partially reads like infix notation. So it’s not that it’s different. It’s that it’s not different enough.

There is a way to avoid the confusion though. But we need to read it step-by-step. First the operator, then the operands:

-

“Minus.” (Hyphen, actually. But we’re just gonna have to roll with it.)

This means we’re dealing with subtraction, so let’s see what comes after that.

3 2

“Three two.”

Now imagine the operator between the numbers.

“Three minus two.”

There we go.

And if you have more numbers, like

(- 9 3 2)

It should be read as “minus”… “nine minus three minus two.”

And you do this with other operators too, like

(> X Y)

This should not be read as “greater than X Y”, which can leave you wondering: what is greater than X? And what’s that Y doing there?! Is Y greater than X?
No, no, no.

Don’t read it left to right in one go! Oh, sure, you can read all other code left to right in one go, but not this part.

Just repeat the previous steps. “Greater than”, take a look what you’ve got (X Y), and then… “X greater than Y.”

See? That wasn’t so bad.

Well, actually, that was pretty bad. It may not seem like too much ask here, but that’s because we’re forgetting the context. A thing such as (> X Y) is problematic when it is involved in a train of thought. That is, when you’re busy thinking about code. And that’s practically always going to be the case.

Let’s see here. If X is greater than Y, then…

(> X Y)

Wait… greater than…

Yeah. Okay. So…

No, hang on. Greater than… X? Y. Wait, what?

Train of thought: derailed.

I know how prefix syntax is supposed to work at this point, so it’s not difficult to start typing (> X Y). But there is that small moment of second-guessing that happens when confronted with the sight of > X Y, and that moment is enough to screw me over.

There’s no getting used to it. Instead, you just get used to having your train of thought messed up once in a while; or catch a lucky break when you only have to add or multiply.

There might be a way to solve this problem though.

Infix Readings

The idea I propose here doesn’t involve changing the notation, but rather involves the editor, and what it can do to make prefix syntax easier to read.

Before I explain further, have a gander at these examples.

If you read this - 3 2 as “minus three two.”

Then the following would be read as -3 2 “minus three, two.”

And -3 -2 as “minus three, minus two.”

And - 3 - 2 as “minus three minus two.”

Then, perhaps, the following could be read as…?

- ... 3 - 2

“Minus, three minus two.”

Bringo.1

Here’s what I propose the editor should do:

  1. Visually separate the first operator from the rest
  2. Create more space between the operands by doing a bit of padding
  3. Fill the newly created space between the operands with the appropriate symbol–a ligature

We could call this functionality ‘Infix Readings’, although I’m not sure yet if that’s the right term for it.

Rather than pad the space between the operator and the first operand as above, a similar effect can be achieved by displaying some sort of barrier around the first operator, thereby ‘detaching’ it from the operands, and having a ligature appear connected to the operands by being visually closer to the operands than the first operator.

That sounds a bit complicated. But no worries, I made mockups in the form of animated GIFs, showing what it would look like.

Mockups

Here’s a GIF showing (- 3 2).

- 3 2 gif

Of course, if there’s more operands, the editor will continue to fill the gaps with the appropriate symbol.

- 9 3 2 gif

The programmer doesn’t input those extra minuses you see in the above GIF. That’s the editor’s doing. They show up as soon as the programmer enters a space character.

So rather than go out of your way to imagine the appropriate operator between the operands, the editor will just, like, do it for you.

And while we’re using ligatures: another thing that has bothered me is the greater-than-or-equal-to operator >= which looks a bit incomprehensible to me. We can use something that looks a bit nicer instead.

Greater-than-or-equal-to gif

Prefix syntax never gave me trouble when adding or multiplying, but here’s what that would look like:

Plus and multiply gif

I suppose you could provide options in the editor as to which operators infix readings should act upon.

Nested expressions gif

Selecting the expressions would show that those extra operators aren’t actually ’there’, i.e. not entered by the programmer

Selection gif

Here’s what it would look like if you toggled infix readings on and off. The programmer never inputs extra space between the operands; the editor just makes it seem that way.

Toggle gif

Thus everything stays compatible with existing code.
(And also, when working with others who may not use infix readings, to prevent any confusion as to why the heck you keep putting two spaces in expressions when there should be only one!)

Of course, we need to remember to do this in context, as before. That means we need to pretend like we’re busy coding.

So let’s see, if X is greater than Y, then…

If then gif

Hopefully that would help us stay on track.

P.S. At time of writing, work has not begun to implement this feature.

Anyone interested in implementing, copying, or modifying this proposal is free to do so.