Naming convention when dealing with variables with the same name

Hey, what naming convention are you using in this type of situation?

let element = 2;
let elements = [0, 1, 2, 3, 4];
elements.iter().find(|&element| *element == element);

Before coding in Rust, I was prefixing the inner element with _, to mark it as "private to the iteration" but in Rust _ is used to define unused variables.
I've seen __ suffix in Python which be another option but I wanted to know what other more experienced people do and if there is a convention for this.

1 Like

If there's no better name, I usually use something like target:

let target = 2;
let elements = [0, 1, 2, 3, 4];
elements.iter().find(|&element| *element == target);

or, especially in search functions:

let needle = 2;
let haystack = [0, 1, 2, 3, 4];
haystack.iter().find(|&straw| *straw == needle);

At the end of the day, it depends on context, and element or elements are rarely good names.

1 Like

In this case, I used element as a generic naming variables to demonstrate my issue.

A more contextual example is:

fn remove(tile: Tile) {
    let index = self.bag.iter().position(|&tile| tile == tile);
    self.bag.remove(index);
    // do other things
}

The issue is when an "external" variable, generally passed to the function needs to be compared to an "inner" variable from a list of the same thing.

Just name it whatever makes sense without a leading _ or other "special name" attempts. The names are private to the function and code further down the same function can "shadow" the same name with another let index = ... binding, so it doesn't have to care either. (Though if your functions are so long that this is a non-trivial concern, perhaps it's time to refactor things a bit...)

4 Likes

TBH, for something like this I just use |x| x == &tile or similar.

If it's something that only shows up once, right at the beginning, of a short closure, I'll just see |x| x BLAH and go "oh, of course", and not even think about the name.

Names are important when they're used in large scopes. But in tiny scopes, using a short conventional name is great.

(See also my_option.map(|x| x.2) or something -- it's not worth spending brain time on naming that.)

10 Likes

I use current, because it better reflects purpose:

elements.iter().find(|&current| *current == element);

I also used _ to prefix parameters in Java to avoid a clash with member names, however Rust is more flexible to names, so you can reassign name more freely, for example:

let name = name?;

And any name separation can't be a permanent.

2 Likes

I tend to use short, one or two letter abbreviations for closure arguments. In this example I would probably use it.

2 Likes

My question is: What is that number "2" that you have called "element"? Presumably it is something and at that point it is not element of anything, so wht not call it what it is?

Typically I would just use a short name for very short lived things like your subsequent uses "element". For example here I might just call it "e". So we end up with:

let needle = 2;
let haystack = [0, 1, 2, 3, 4];
haystack.iter().find(|&e| *e == needle);

I don't like to "_" hanging off the beginning or end of names. Looks messy.

1 Like

There’s no good reason for closure arguments to have long names. The binding is extremely local so its meaning should be obvious from the context. If anything, long names for something that’s only used on the same line make the code noisier, more stuttery [1], and detract attention from what the closure does.

The tendency of functional programmers to prefer single-letter variables (or, indeed, no variables at all!) may go a bit overboard at times, but they do have a point. [2]


  1. |element_| element_ == element – why am I repeating myself and wasting keystrokes? Besides, this is some seriously confusing code. ↩︎

  2. Quite a few languages also have some sort of a lambda shorthand that allows you to just write, eg. _ == needle rather than |e| e == needle. (In languages with automatic currying, like Haskell, you could just write something like (==) needle which returns a single-parameter function, but I’m starting to digress.) ↩︎

2 Likes

The shorter the scope, the shorter the variable name can be, and vice versa.

In small closures, I tend to use abbreviations of 1 to 3 letters. For example, in .find() or .position(), I often use x, as it resembles the mathematical notion of a general unknown value.

In larger scopes, where objects are checked or selected based on specific properties (often involving combinatorics) I use candidate when there is no specific name.

4 Likes

I think that's the snippet that I like the most.
I'm marking your answer as solution even tho this is more about personal preference.


As mentioned later on, naming things elements was just to demonstrate general purpose.


While I do agree the binding is local, some of my closures are sometimes long enough to require more explicit names than just a one letter variable.


Thanks for sharing, I like candidate as much as current to describe the check performed in the closure, that's also a good naming (to me at least).