Allow mixedCase in the constants naming style

The problem

Currently the only recommended naming convention for constants is SCREAMING_SNAKE_CASE. This leads to weird APIs, for example:

contract Four {
    uint8 public constant FOUR_CONSTANT = 2 + 2;
    uint8 public immutable fourImmutable = 2 + 2;
    function fourFunction() public pure returns (uint8) {
        return 2 + 2;
    }
}

For the consumers of the API, it’s all the same, they see 3 pure functions returning uint8s, but while fourImmutable() and fourFunction() are consistent, FOUR_CONSTANT() is completely different, even though it behaves exactly as the rest.

For the devs writing contracts deriving from Four, fourImmutable and FOUR_CONSTANT are in most contexts equivalent, the only exception are assigning to other constants and static array sizes.

For the devs of Four, a cosmetic change of fourImmutable or fourFunction into a constant is an API-breaking change even though it can’t affect any consumers. A change of FOUR_CONSTANT into an immutable or a function won’t affect the API consumers either, it will only affect the constant evaluation in the deriving contracts.

Because the naming convention is defined in the Solidity language’s own documentation, it’s considered the (soft) law. All the code linters and analyzers, and also all the devs require using the SCREAMING_SNAKE_CASE for constants, to do otherwise one needs to overcome both the tools and the people.

The solution proposal

I propose to allow both SCREAMING_SNAKE_CASE and mixedCase names in the constants style guide, but recommend mixedCase. It won’t make the existing code and interfaces break the style, after all they can’t be changed anymore. Over time the tools will start accepting mixedCase, and the devs will learn to use them. The future APIs will stick to mixedCase everywhere and won’t expose their inner implementation details via the naming convention anymore.

WDYT?


This post is based on a GitHub issue.

AFAIK, the recommended naming convention for the group of contract-level variables in general (a group which the constant variables are a part of), is to declare each one of them as either private or internal (depending on your functional requirement), and then expose them for reading via functions.

For example:

contract Four {
    uint8 private constant FOUR_CONSTANT = 2 + 2;
    function fourFunction() public pure returns (uint8) {
        return FOUR_CONSTANT;
    }
}

That would make sense, it would prevent exposing functions in SCREAMING_SNAKE_CASE. Is it included in the style guide? IIUC a rule like this would make all public constants break the style, they should be converted into internal/private and get a function for accessing them. I don’t think that it’s the case, I never saw any tool or person complain about a public constant.