Constness: Difference between revisions

From Helpful
Jump to navigation Jump to search
mNo edit summary
Line 81: Line 81:


-->
-->
[[Category:Computer‏‎]]
[[Category:Programming]]

Revision as of 13:11, 12 July 2023

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.


In programming languages that have it, const is mostly about you telling the compiler about what you won't do with the value, in the scope you declare this in in.

In languages that are statically typed, you say you will not change the value.

In languages that are dynamically typed, that you will not assign another reference to this name. (the difference between which can be subtle)


Depending a little on the language, you might e.g. have a const global that promises it won't be altered at all, a const function parameter to promise that the function won't alter it, have a const thing in a function, or in block scope, etc.


This is primarily a tool to allows some basic checks that code does not alter these (not-so-)variables, in the form of the compiler throwing errors when you try.


And yet, const generally does less than you think

People have a few different ideas of what const might do:

  • make the compiler complain about attempts to never alter data that is declared const
  • let the compiler optimize

Both turn out to be limited.


Say, constness means you cannot accidentally reassign a variable in the same scope, because it is very clear to the compiler when you do that. So the const variable will, in its lifetime, always be bound to the thing you assigned to it when you defined it.


At the same time, in many languages it does nothing to prevent you from altering the contents of the thing that it points to.


In more precise terms, it can be a constant reference to a value or object that might itself be mutable. Even if not here, then possibly elsewhere.

The problem is often that constness is part of the type in a scope, not a property of the thing it points to (regardless of whether the language is statically or dynamically typed, and regardless of whether you can tell the compiler separately that the reference and the value are const, as in C++)


Consider const in javascript.

const a = {}
a   = 2;     // will be a SyntaxError
a.b = 3;     // is perfectly fine


C and C++ are a little more interesting, see C_and_C++_notes_/_Syntax_notes#const, in part because both the pointer and the value can be const or not - and that can still be defeated.


What about optimizations?


The reason constness doesn't lead to many compiler optimizations is similar: you don't know how far the constness promise goes, or who can violate it, so it leads to very few things you can actually guarantee.

(Similarly, the lack of guarantee of immutability means it also doesn't help around parallelism)

(this is more true in C/C++ where pointers make things complex; in JS there are probably a few more cases where it does help)


Consider, for example, a library that wants to be given const strings so that it might be a little more efficient if it promises the compiler it won't via const. They were probably non-const to begin with, but treated as const by that library, maybe just to inform you that it's safe to pass by reference without issues like those from side effects. Sounds good, right?

Now consider another library that doesn't, that alters the strings in-place for optimization reasons they might call zero-copy or whatnot. This breaks the first library's promise to the compiler (and your promise to the other library).

Usually that won't happen. ...for reasons unrelated to constness, and that constness has no say over.+


It may still be useful to keep in that library, just to signal to you what it is and isn't doing, and perhaps how you should treat it.