DEV Community

Cover image for Prefixing variable names with 'is'

Prefixing variable names with 'is'

Andreas Riedmüller on September 09, 2022

I wanted to share a recent thought about one specific naming topic and get your opinions on that: Using the 'is' prefix. My point is that I feel t...
Collapse
 
taufik_nurrohman profile image
Taufik Nurrohman

Use prefix are or has or is if variable contains boolean. Use prefix the (or not at all, as long as variable name represent a noun) if variable contains data.

const color = isDark ? '#000' : '#fff';
const theButton = hasValue && !isDisabled ? theButton : null;
Enter fullscreen mode Exit fullscreen mode
Collapse
 
receter profile image
Andreas Riedmüller

Imagine you have a component <FancyButton> what interface would you expect/prefer? <FancyButton disabled dark> or <FancyButton isDisabled isDark>?

For me it is definitely the first and for the implementation it would look odd to stick to naming the variables isSomething.

For example:

props => {
  const { disabled, dark, children }  = props;
  return <button
    className={cn(styles.button, dark && styles.button_dark)} 
    disabled
  >{children}</button>
}
Enter fullscreen mode Exit fullscreen mode
props => {
  const { disabled: isDisabled, dark: isDark, children }  = props;
  return <button
    className={cn(styles.button, isDark && styles.button_dark)} 
    disabled={isDisabled}
  >{children}</button>
}
Enter fullscreen mode Exit fullscreen mode

For the hasValue part: If hasValue is used once (or twice) and is as simple as !!value or value != null I would go with the expression. Arguing that hasValue is vague, and I might still end up having to read the definition of hasValue.

Can you come up with downsides of writing your code like this:

const color = dark ? '#000' : '#fff';
const theButton = value && !disabled ? theButton : null;
Enter fullscreen mode Exit fullscreen mode

?

I am searching for some solid arguments against never using thje 'is' prefix.

Collapse
 
naruaika profile image
Naufan Rusyda Faikar

The <FancyButton> is a different case. I'd agree to write it as <FancyButton validated> instead of <FancyButton isValid>. Because it's a pattern used by everyone, so it'll give a clearer understanding.

Collapse
 
drsensor profile image
૮༼⚆︿⚆༽つ

Maybe narrow the prefix "is" only for JS identifier. Or make an exception for property names that can be used as JSX attribute then prefix "is" are not allowed. Just info, three.js use prefix "is" in their class properties.

Thread Thread
 
receter profile image
Andreas Riedmüller

Yes, it has a great readability for class properties as well.

if (object.isCamera) { // ... }

I can’t even come up with another way to name isCamera without is.

Collapse
 
taufik_nurrohman profile image
Taufik Nurrohman • Edited

Can you come up with downsides of writing your code like this: [...]

Most of the time it is just about efficiency in searching/replacing things via code editor. When you type “value” in search box, you will get too many results.

Collapse
 
naruaika profile image
Naufan Rusyda Faikar • Edited

I prefer the is-prefix to without it. But I'd write it as follow:

if (! isValidResponse(response)) {
  // ...
}
Enter fullscreen mode Exit fullscreen mode

This gives clearer call-to-action function naming to me. Also I'd never write getIsCheap(), but isCheap() instead. But whatever you choose, the most important thing is to stay consistent.

Collapse
 
receter profile image
Andreas Riedmüller

Yeah, I get your point and I do have a fair amount of functions starting with is.

One problem I run into is naming the result of an is prefixed function.

I obiously can’t write:

const isCheap = isCheap(true, true);
Enter fullscreen mode Exit fullscreen mode

What I can do is:

const cheap = isCheap(true, true);
Enter fullscreen mode Exit fullscreen mode
const isCheap = getCheap(true, true);
Enter fullscreen mode Exit fullscreen mode
const cheap = getCheap(true, true);
Enter fullscreen mode Exit fullscreen mode
const isCheapResult = isCheap(true, true);
Enter fullscreen mode Exit fullscreen mode

I tend to like the first one the most.

Collapse
 
naruaika profile image
Naufan Rusyda Faikar • Edited

You can do so by writing:

const isPotatoCheap = isCheap(true, true);
Enter fullscreen mode Exit fullscreen mode

Because isCheap() is a generic function, I think it'd be useful to make the context of your code clearer.

Collapse
 
drsensor profile image
૮༼⚆︿⚆༽つ

This discussion remind of prefix I in interface (i.e IDispose). In my journey, there is 2 times when I debate this with my peer. The first one is when we refactor our JS code into Typescript and the second one is when exploring Rust. Now I just follow the majority in that language ecosystem whatever it makes sense or not.

Collapse
 
receter profile image
Andreas Riedmüller

Follow the majority is quite a safe bet if it is clear what the majority does :-) Same is valid for codebase conventions and existing code. I would use is without a second though if there is another isVariable in the same space.

Collapse
 
receter profile image
Andreas Riedmüller

If I would work together with someone and there would be a debate about using is for boolean variables I hope I would just give in. I like how much cleaner it looks without but this is such a trivial detail in the end. But I love to explore this topic!

Collapse
 
nombrekeff profile image
Keff

I really like this convention! It flows a lot better when reading through code, resembling a real language. I tend to use the is, has, and are prefixes as @taufik_nurrohman also pointed out. Although I prefer making them functions or methods instead of variables, as you also mention in some other comment. Otherwise it can get confusing. Is isEmpty a method or a variable...

Collapse
 
receter profile image
Andreas Riedmüller

Good point, I also like the readability of 'is' prefixed funtions. I am still sceptical if prefixing variables with 'is' is worth it. It might just be me, but I like the subtle more clean looking code without.

const niceAndSmooth = nice && smooth;
const cheap = !fast || !good;
// Speaking: cheap - is - not - fast - or - not - good

const isNiceAndSmooth = isNice && isSmooth;
const isCheap = !isFast || !isGood;
// Speaking: is cheap - is - not - is fast - or - not - is good
Enter fullscreen mode Exit fullscreen mode

I don’t like the second version, it looks so ew.

But for the function isCheap() instead of getCheap() reads so much better I have to admit.

Collapse
 
hakanai profile image
Hakanai

This is precisely why we often end up with methods like isNotEmpty as convenience methods in places where isEmpty exists - because !thing.isEmpty() not only reads weirdly, but a code reviewer might not even spot the ! because of the way it reads.

Collapse
 
theaccordance profile image
Joe Mainwaring

prefixes are useful conventions when working with large codebases in a highly collaborative environment. I have authored many methods with is as a prefix for evaluating conditional actions. I've also used has as a prefix as well for iterating over a collection to evaluate a conditional.

Collapse
 
receter profile image
Andreas Riedmüller

is (and has) for functions is nice, I can’t argue against that.

Collapse
 
conw_y profile image
Jonathan • Edited

I agree with @katafrakt on this:

The problem it solves is that when I see a variable called validResponse, I kind of expect an actual response there.

The is prefix lets us see at-a-glance that the value is a boolean, whereas it's not so easy to tell at-a-glance whether a value is a boolean, so adding is or has offers value.

(Old-school VB coders would have gone further and prefixed variables with i for integer, etc. However I think this is taking it too far. It's usually easy to tell at-a-glance whether a value is a number. E.g. year is very likely to be a number, so adding iYear wouldn't offer much value.)

As @katafrakt mentions, validResponse might refer to:

  1. Boolean indicating whether or not the response is value.
  2. The response itself, if valid.

Even worse - for the false/empty state, it could be used as a boolean. For example, data returned by useQuery in react-query can be undefined or have the data.

Example:

if (!data) {
  return "Empty";
}
Enter fullscreen mode Exit fullscreen mode

My suggestion is to prefix all booleans with is, has, can, etc.

However – where possible, it's better to use a more informative type than boolean, such as enum, object, etc. A richer type can convey more information about the state than just true/false.

  • 🫣 hasValue: false | true - false only tells us whether it's empty, but doesn't tell us why
  • 🙂 value: number | null | "unset" - null tells us whether it was deliberately cleared or never set in the first place
Collapse
 
receter profile image
Andreas Riedmüller

Thanks for your comment. Agreed.

I ended up using the is prefix after all :)

Collapse
 
hakanai profile image
Hakanai

The convention in Kotlin is for boolean properties to start with is. This extends to its automatic recognition of properties in Java classes - if a class has an isCheap and setCheap method then it will automatically get a isCheap var. This seems to be a common convention in C# as well.

In Java I usually would not do it - there, it's conventional for the getter method to be called isCheap while the backing boolean is just called cheap.

So which one to use is entirely going to depend on what language I'm writing.

For functions, I think it depends as well.

If it were isCheap(thing) then I'd keep the name isCheap. Actually, I would try to refactor it such that it's just an isCheap property on Thing if possible. But if I'm working in something functional where I can't really do that, sure - isCheap(thing) makes some sense. But in the current form in that example, I'd probably call it determineIsCheap or similar - the thing being passed in isn't the thing where you're determining whether it's cheap, but more a collection of other properties about some object which is not itself provided.

Collapse
 
receter profile image
Andreas Riedmüller

Interesting, thank you!

Collapse
 
mbarzda profile image
Martynas Barzda • Edited

I stumbled upon this article a few days ago michaelzanggl.com/articles/tips-on... . Also, if you are using typescript there is worth to setup typescript-eslint rule:

"rules": {
  "@typescript-eslint/naming-convention": [
    "error",
    {
      "selector": "variable",
      "types": ["boolean"],
      "format": ["PascalCase"],
      "prefix": [
        "has",
        "is"
      ]
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
receter profile image
Andreas Riedmüller

I am still not on the is for variables side… But I like this example from the article:

if (account.isEnabled) {
  // ...
}
Enter fullscreen mode Exit fullscreen mode

Maybe it is a little different for class properties as well.

Collapse
 
ihor912 profile image
Ihor Khomiak • Edited

I like the way you chosen with using of prefix ‘is’ only for functions.

Collapse
 
fjones profile image
FJones

I change my mind about it fairly frequently in practice, but in theory my thinking is the following: verb prefixes imply predicates or instructions, which means it should be a function (or a toggle flag). That said, booleans are tricky - it never quite "feels" right to have an unprefixed variable representing a boolean. validResponse is the valid response, right? Oh, wait.

Collapse
 
receter profile image
Andreas Riedmüller

This is true, could be the valid response as well. I think this level of ambiguity might not be problem, it happens quite often in code. I would argue it’s not the job of the variable name to tell me its type.

There is still the issue with naming the result when the function has the name already:

const nameMe = isValidResponse(response);
Enter fullscreen mode Exit fullscreen mode

One idea would be to name it responseIsValid. I still prefer responseValid if the context allows for it.

Collapse
 
katafrakt profile image
Paweł Świątkowski

Well, I prefer my variables to not have is prefix and to end with a question mark, in general. So:

valid_response? = response.code < 300
Enter fullscreen mode Exit fullscreen mode
Collapse
 
receter profile image
Andreas Riedmüller

Which language are you using? In Javascript for example you cannot use a question mark for naming a variable.

And how does using this signifier help you?

Collapse
 
katafrakt profile image
Paweł Świątkowski

I'm using Elixir.

The problem it solves is that when I see a variable called validResponse, I kind of expect an actual response there. On the other hand, with the prefix it becomes tricky sometimes. isValidResponse but isAllResponsesValid (for consistence of having is- prefixes) or rather areAllResponsesValid (to be more grammatically correct).

With question mark notation you don't have these problem. It is validResponse? and allResponsesValid?, which saved time on bikeshedding.

Collapse
 
lexlohr profile image
Alex Lohr

Naming things is one of the hardest tasks in development. I'm not opinionated when it comes to these conventions, except for two things: make it consistent and obvious enough to be easily explained.

Collapse
 
receter profile image
Andreas Riedmüller

There are two different things coming to my mind when I read "easily explained"

  1. The rule is easy to explain
  2. It is easy to explain why the rule exists and what problem it solves

I think the second one is very very important. If the rule is easy to explain (as in the first), it is easy to follow but people will start to question the rule and break it if they want.

If people understand the WHY of a rule, it is more likely that they follow the rule. The rule can still be broken, but at least the problems of breaking the rule are understood. And sometimes breaking a rule is better then just blindly following it.

Collapse
 
lexlohr profile image
Alex Lohr

And both of them were meant. Thanks for elaborating on that point, I should have clarified this myself.