Non-snake case: variables vs functions


#1

There is an annotation to disable the “snake case” lint:

#[allow(non_snake_case)]
fn FunnyFunctionName(){
    let Y = 2.4;
    ...
}

but that is a little crude in it’s application. (It is invalid, for example, to use the annotation directly on a local variable within the function.)

Proposal

Add two new annotations, non_snake_case_fn, non_snake_case_var (or even three: non_snake_case_fn, non_snake_case_let, non_snake_case_param). These can be used to turn off the “snake case” lint (or lints) in specific cases.

Motivation

In a few cases I find it reasonable to use non-snake-case names: when copying equations from a scientific/mathematical article (sometimes referencing an external work is much easier than documenting everything in the code), when using acronyms (in this case it’s debatable whether or not the acronyms should be converted to lower case). And sometimes odd other cases (though mostly temporary).

Usually, however, these are localised exceptions from the norm, and I’d like to use standard names elsewhere, hence #[allow(non_snake_case)] is a bit of a blunt tool.

Examples

Use of an acronym in a function name:

[#allow(non_snake_case_fn)]
fn special_func_ABC(...) {...}

I’m not even sure if the above should be allowed by default (so long as the first letter is lower-case and every capital letter follows an underscore or another capital letter).

A function using more mathematical syntax for variable names:

[#allow(non_snake_case_var)]
fn compute(x: f64) -> f64 {
    let X1 = ...;
    let a = ...;
    let Z = ...;
    ...
}

Alternatives

The status quo: all or nothing (apply [#allow(non_snake_case)] at the function/module/project level).


#2

We originally had separate non_snake_case lints for functions and variables, but in PR #15773 I consolidated them into a single lint at the request of the devs. I personally much prefer the current approach, but given that we have lint groups (added in the same PR) I guess we could make non_snake_case a lint group that encompasses non_snake_case_variables, non_snake_case_functions, non_snake_case_modules etc., allowing for both fine-grained control and ease of use in cases where you don’t need precise control, all in a backwards-compatible manner. That said, I see little reason to separate these lints—the motivation given isn’t really enough in my opinion to warrant such a change.

(I believe that acronyms should always be lowercase in snake case names, much like how they must be capitalised Abc in camel case names.)


#3

I thought there was something in the works in regards to allowing annotations in arbitrary places. Wouldn’t that be an even better solution? :stuck_out_tongue:

I remember shoving a heap of code into an inner function in a macro expansion once, just so I could attach annotations to the code: I had warnings leaking out of the macro expansion that I couldn’t turn off otherwise.


#4

There was something in the works for allowing attributes everywhere. Note that this does not necessarily include specifying lint behavior everywhere.


#5

That’s RFC 16, which hasn’t yet been implemented (but has been accepted). I suspect that after 1.0 (as with a lot of things) someone might get around to implementing it. I agree that that’s a better solution, though, but we might have to wait.