Quantcast
Channel: JavaScript – Pointers Gone Wild
Viewing all articles
Browse latest Browse all 10

The Constness Problem

$
0
0

These days, I spend most of my programming time working on the Higgs JavaScript JIT compiler for my thesis, and most of the code I write is in D. I don’t always take the time to write the best, most carefully engineered code, especially if I know I might rework a given piece of code later. Still, I try to pay some attention to generally-accepted-best-software-design-practices. One thing I try to pay special attention to is which data should be immutable and which shouldn’t. I write my code in an imperative language, but I too have come to accept that immutable data and immutable data structures can make a program safer and easier to debug.

The main thing I’m working on right now, for Higgs, is a system of shapes (aka hidden classes) to describe object layouts in memory. In the Higgs object system, JavaScript objects are essentially a flat list of slots which can contain values. Shapes are essentially a tree data structure, where each node describes a property in an object, and most importantly, where that property will be stored in a flat object layout (the slot index associated with that property). Each object has an associated pointer to a node in the shape tree. Through this shape node pointer, you can find the properties stored in that object, their names, and which slot you can find them at. The important thing is that the shape tree nodes are essentially immutable. Once such a node is created, the name of the property it describes, the associated slot index, and all other attributes of the node should never change.

As someone who wants to write safe, descriptive code, I wanted to explicitly express those immutability constraints in my code. I wanted to use const(ObjShape) pointers when manipulating shapes. I also wanted to make the fields of the ObjShape class themselves const. Unfortunately, this plan didn’t work out. The DMD compiler wasn’t having it. I quickly found out that the D programming language (which is quite like C++ in this regard) just didn’t offer a way to express the semantics I wanted. Introducing const or immutable keywords in the code introduced strange and unpredictable compiler errors. Struct objects that could be copied by value before couldn’t anymore. Some of the errors reported were entirely nonsensical problems I never saw coming.

Consider the following snippet, and the compiler error it produces

class A { const(A) parent; }

void main()
{
    auto a = new A();
    auto p = a.parent;
    p = new A(); // test.d(7): Error: cannot modify const expression p
}

This is complete utter nonsense, and it deeply offends me! I specified that the parent field of class A should be constant. In D, you get “constness all the way down”, which means that I can’t mutate the parent field, and I also can’t mutate the object that the parent field points to. But, where in this program did I specify that the variable p was immutable and could not be redefined? Nowhere! This is problematic, because as far as I know, there is pretty much no way to write the type of p in such a way that p points to a const(A) object, but p remains mutable, not without ugly, unsafe type casting tricks. There’s no way to have a mutable variable that points to an immutable object? That’s insane!

In my opinion, C++ and D both lack expressivity when it comes to constness. D’s const and immutable keywords are is simply overpowering. It’s an issue in the other direction, too, because “constness all the way down” means that I can’t have a class field that’s immutable without also being forced to assume that the object pointed to by the field is entirely immutable. That’s not necessarily what I want. In the end, I’ve been forced to give up and remove const keywords on many occasions, because I end up fighting with the type system too much, it’s getting in my way.

It’s good that modern imperative languages have some tools to express purity and immutability. However, I think that there’s an issue of granularity. There are ways in which it makes sense to talk about constness, and ways in which it doesn’t. I’d almost say that I prefer JavaScript’s notion of constness, because it’s much simpler. In JavaScript, you can make an object property constant, but what that field points to does not have to be immutable. That is all! This might seem primitive, since you’re only able to painstakingly mark constness on individual object properties one at a time. It might feel like the only tool you have to deal with immutability in JavaScript is a tiny toothpick. This, however, is forgetting that JS has powerful introspection capabilities which allow to write code that makes an entire data structure immutable with a single function call. The language offers you the tools to express constness any way you want to.


Viewing all articles
Browse latest Browse all 10

Trending Articles