Spooky action at a distance January 19, 2021 on Drew DeVault's blog

Einstein famously characterized the strangeness of quantum mechanics as “spooky action at a distance”, which, if I had to pick one phrase about physics to be my favorite, would be a strong contender. I like to relate this to programming language design: there are some language features which are similarly spooky. Perhaps the most infamous of these is operator overloading. Consider the following:

x + y

If this were written in C, without knowing anything other than the fact that this code compiles correctly, I can tell you that x and y are numeric types, and the result is their sum. I can even make an educated guess about the CPU instructions which will be generated to perform this task. However, if this were a language with operator overloading… who knows? What if x and y are some kind of some Vector class? It could compile to this:

Vector::operator_plus(x, y)

The performance characteristics, consequences for debugging, and places to look for bugs are considerably different than the code would suggest on the surface. This function call is the “spooky action” — and the distance between the “+” operator and the definition of its behavior is the “distance”.

Also consider if x and y are strings: maybe “+” means concatenation? Concatenation often means allocation, which is a pretty important side-effect to consider. Are you going to thrash the garbage collector by doing this? Is there a garbage collector, or is this going to leak? Again, using C as an example, this case would be explicit:

char *new = malloc(strlen(x) + strlen(y) + 1);
strcpy(new, x);
strcat(new, y);

If the filename of the last file you had open in your text editor ended in .rs, you might be frothing at the mouth after reading this code. Strictly for the purpose of illustrating my point, however, consider that everything which happens here is explicit, opt-in to the writer, and obvious to the reader.

That said, C doesn’t get off scott-free in this article. Consider the following code:

int x = 10, y = 20;
int z = add(x, y);
printf("%d + %d = %d\n", x, y, z);

You may expect this to print out 10 + 20 = 30, and you would be forgiven for your naivety.

$ cc -o test test.c
$ ./test
30 + 20 = 30

The savvy reader may have already figured out the catch: add is not a function.

#define add(x, y) x += y

The spooky action is the mutation of x, and the distance is between the apparent “callsite” and the macro definition. This is spooky because it betrays the reader’s expectations: it looks and smells like a function call, but it does something which breaks the contract of function calls. Some languages do this better, by giving macros an explicit syntax like name!(args...), but, personally, I still don’t like it.

Language features like this are, like all others, a trade-off. But I’m of the opinion that this trade is unwise: you’re wagering readability, predictability, debuggability, and more. These features are toxic to anyone seeking stable, robust code. They certainly have no place in systems programming.

⇒ This article is also available on gemini.

Have a comment on one of my posts? Start a discussion in my public inbox by sending an email to ~sircmpwn/public-inbox@lists.sr.ht [mailing list etiquette]

Articles from blogs I read Generated by openring

Summary of changes for February

Hey everyone! This is the list of all the changes we've done to our projects and apps during the month of February. We'll also be reporting in our on position in the world, and on our future plans. Summary Of Changes Uxn, started working on a fa…

via Hundred Rabbits February 28, 2021

Contexts and structs

Introduction In many Go APIs, especially modern ones, the first argument to functions and methods is often context.Context. Context provides a means of transmitting deadlines, caller cancellations, and other request-scoped values across A…

via The Go Programming Language Blog February 24, 2021

Status update, February 2021

Hi! Once again my focus has been Wayland-related projects this month. A steady stream of improvements made it into wlroots: Xyene made the X11 clipboard code a lot more robust, bl4ckbone has made good progress on the upcoming Pixman-based software renderer, a…

via emersion February 22, 2021