All caps for statics


#1

I recently stumbled upon the non_uppercase_statics lint, and it made me wonder, what is the rationale behind this convention? The naming conventions call them SCREAMING_SNAKE_CASE, and I do find them screaming, often too screaming. Are statics so important that they need to be screaming? One could argue that it makes it easy to identify statics, but is there any value in that? We don’t use Hungarian notation either. Especially because variables are immutable by default, I think there is little distinction between regular immutable variables and static variables in practice. Uppercase might be useful for flags, though those are similar to enum variants, which use CamelCase.

The most obvious reason for all caps statics that I could think of, is that it is a convention in C.


#2

I think there needs to be some method of distinguishing statics from normal bindings. The main problem with statics looking identical to normal variables is with patterns (this applies to enum variants as well, which are also distinguished by casing conventions):

static foo: uint = 56;

// a bunch of unrelated code...

match frobnicate() {
    Some(foo) => { ... },
    _ => fail!("frobnicate() failed!"),
}

This code might seem innocent, but in fact has a subtle bug in it. The foo in the first match arm is in fact referring to the static defined many lines up, and so the match will fall back on the second arm in all cases except when frobnicate() returns Some(56). This bug is very difficult to locate, because the foo in the pattern just happens to conflict with the foo static above (which the author has probably forgotten exists).

I’ve seen people get extremely confused about this on IRC a few times (it’s more common than you might think), so I decided to turn the lint on by default, so that people rename their statics before they happen to make a name conflict in a pattern. All the other naming lints are on by default, anyway.


#3

BTW, when this lint was added it was on warn by default, but people found it too noisy so it was switched to allow; maybe the convention has become widespread enough that the ‘spurious’ errors are no longer a problem.


#4

That is a good point.


#5

It’s clear that statics should be uppercase. But why should they be SCREAMING_SNAKE_CASE and not CamelCase?


#6

Most important must be to not mix up statics with other bindings. SCREAMING_SNAKE_CASE doesn’t really bother me that much. I don’t have a strong opinion either way. Using affixes is another alternative: s_example.

CamelCase clashes somewhat with type names, but alas, there are only so many ways to disambiguate by case.

Do you care about being able to visually distinguish global statics from global constants? (accepted RFC #246rendered)


#7

I think that constants should be written in CamelCase just like enum variants are, because as non-addressable values they are very much alike.

Global static variables, on the other hand, do represent memory addresses (see RFC above). I think that this property warrants a visible distinction. They should be quite rare. And where they do occur they might as well be unmistakably identified as special:

static GLOBAL_VARIABLE: int = 1;

const SomeConstantValue: int = 2;

#8

A static will be basically just a let with a global scope. That makes me think that statics should be snake_case and consts should be SCREAMING_SNAKE_CASE. After all, static muts are recommended to be snake_case today.

I understand the argument for making statics CamelCase, but there are a lot of languages (Python, Java, C, C++, PHP; that’s all I could think of from the top of my head/showed up in a search) that use uppercase for constants as well. Perhaps C-like enums could be uppercase, too, for consistency. I’d be fine with that.


#9

I think maybe all nullary enum variants should have the same naming convention as constants:

static global_variable: int = 1;

const CONSTANT_VALUE: int = 2;

enum Thing {
    SOME_THING,
    ANOTHER_THING,
}

enum Food {
    Apple(f32), // (radius)
    Cucumber(f32, f32), // (circumference, length)
    BUTTER,
    BROWN_SUGAR,
}

#10

Or, for consistency, consts could be made CamelCase (C# does that as well). Using snake_case for static muts makes sense. But then non-mutable static would be used so infrequently, that it would be questionable whether it is worth a separate naming convention.