Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added naming conventions for UPPERCASE use cases. #255

Merged
merged 2 commits into from
Mar 23, 2018

Conversation

estelle
Copy link

@estelle estelle commented Mar 24, 2015

Constants, globals and nested object namespacing, by convention, use all UPPERCASE for those variable names.

also removed an extra line space from line 142.

@goatslacker
Copy link
Collaborator

I'm ok with the uppercase for constants but not the namespace or global variables bit. Namespaces should be whatever case you're exporting (constructors in Pascal, functions in camel, etc), and there shouldn't be global variables :)

@estelle
Copy link
Author

estelle commented Mar 25, 2015

Agree than namespacing in general can be any preferred casing, but nested object namespacing is slightly different. think YAHOO.util.Dom.myMethodName. When you're working with a large application, pulling in 20+ possible namespaces, generally you want a parent or overarching namespace followed by the section or app specific namespace, creating a nested object namespace. The fix is specifically related to nested object namespacing, not general namespacing, if that makes sense.

Also agree that there shouldn't be globals, other than the nested object namespace or single namespace, but if a developer is creating global, it should be identified in some manner. Most guidelines i've seen have used uppercase for this.

That said, should I create a new pull request to get the contant use case added?

@goatslacker
Copy link
Collaborator

Ok cool makes sense, we can keep this together.

Some comments on the PR otherwise this is 👍

README.md Outdated
@@ -1161,8 +1160,34 @@
this.firstName_ = 'Panda';

// good
this._firstName = 'Panda';
this._firstName = 'Panda';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove trailing whitespace

@abrkn
Copy link
Contributor

abrkn commented May 13, 2015

Status of this?

@justjake
Copy link
Collaborator

justjake commented Jul 2, 2015

I would be happy to merge this after a rebase on the ES6 styleguide.

@ghost
Copy link

ghost commented Aug 10, 2015

I was just looking for a style guide rule about constant naming and found this open issue.

I was having doubs whether we would still have a need for UPPERCASE_CONSTANTS_LIKE_THIS when we have const in ES6?

const ActionTypes = {
  theFirstActionName: 'theFirstActionName',
  theSecondActionName: 'theSecondActionName',
};

if const already specifies that it's a contant, the names can be used to specify in a bit more detail what sort of value the constant contains. In the example above, ActionTypes is meant like an enum, and each item is in camel case because they are just strings. (They could be in pascal case if they contain classes, e.g. if you create a const that contains all your Flux stores.)

If you would use the uppercase naming, you would probably only do the property names uppercase and leave ActionTypes in pascal case? I guess the uppercase convention would only make sense for strings, numbers and booleans.

While Googleing some more about this, I found this page about the const keyword in C++: http://www.learncpp.com/cpp-tutorial/2-9-symbolic-constants-and-the-const-keyword/. It mentions uppercase naming as an alternative to using the const keyword. So according to this guide, if you use const, you just name it the way you would with 'normal' variables. I didn't really find any JavaScript guides that have a strong opinion on the const keyword vs. the naming convention (only guides that use var combined with the naming convention).

Google's C++ style guide has another variation: camel case prepended with a 'k' (https://google-styleguide.googlecode.com/svn/trunk/cppguide.html#Constant_Names). Personally though, I don't see why it can't just be camel case without the 'k'.

In any case I think it's good to make this more explicit in the JavaScript style guide. So how about just a small section under 'variables' that clarifies const vs naming convention? And do you agree that const removes the need for uppercase?

@ljharb
Copy link
Collaborator

ljharb commented Aug 10, 2015

const means "can't be reassigned", not "a value that won't be changed" - so you'd still want a convention like SCREAMING_SNAKE_CASE.

@ghost
Copy link

ghost commented Aug 11, 2015

Right you are. Subtle but important difference. Sounds like a good basis for explaining more explicitly when or when not to use uppercase.

Below is an idea for a new section under 'naming conventions'. I can make a PR later if you'd like, but perhaps let's iterate on the text here first?

I used the api key example used earlier in this PR. Wondering if this is indeed a correct example for this use case? To me it's still a bit vague what "value that won't be changed" means exactly. When I read your comment I realized that it's about changing the initial assignment instead of reassigning it later. But an API key can change, right?


22.9: Use SCREAMING_SNAKE_CASE for values that shouldn't be changed.

const API_KEY = '44b345234534t455245njkl523452-vbb9';

@ljharb
Copy link
Collaborator

ljharb commented Aug 11, 2015

@maartenverbaarschot changed programmatically - clearly anything typed into code can be edited :-) The distinction is less important for strings, since they're immutable, but const WHITELIST = ['a', 'b', 'c'] is less clear, which is why the screaming snake case can help.

@treshugart
Copy link

If I use const liberally - everywhere I don't reassign, which is as much as possible (possibly hundreds of times in a file), then should I uppercase every single one of those? This feels like it's bordering on convention for the sake of convention.

If we took it back a step and said, "only for values that you intend never to change" - similar to what @maartenverbaarschot was suggesting - are there strict rules one could follow to determine that?

@jnelson
Copy link

jnelson commented Nov 3, 2016

@treshugart I've found this to be a bright enough line (in order):

const OUTSIDE_VOICE = 'unchanging parameter';
const insideVoice = new NamedConcept();

These are constant values (i.e. the common meaning of constant) as opposed to const references. If the constant is an object, its properties should also be constants. A constant should not depend on anything that is not also a constant. It should be possible to move all constants to the top of a file (in order) without any effect on the output.

@jackblackCH
Copy link

whats the status here?

@dandv
Copy link
Contributor

dandv commented May 16, 2017

Method and variable names should be camelCase, but what about names that are abbreviations and are usually spelled in ALLCAPS? The Date object preserves the ALL CAPS within method names like .toISOString and .getUTCDay. XMLHttpRequest seems inconsistently named - why not XMLHTTPRequest?

@ljharb
Copy link
Collaborator

ljharb commented May 16, 2017

@dandv that is badly named for a number of reasons - including the one you identified. It also isn't limited to just requesting XML.

@ljharb
Copy link
Collaborator

ljharb commented May 16, 2017

Initialisms like HTTP, XML, USA, JSON, etc should always remain capitalized (or be entirely lowercased), and never CamelCased or PascalCased.

@zph
Copy link

zph commented Aug 31, 2017

@justjake If someone else picks this PR up and does the rebase, does the merging offer stand? I'd be happy to do so.

@ljharb
Copy link
Collaborator

ljharb commented Aug 31, 2017

@zph I'd prefer not to create a second PR; if @estelle is willing to check the "allow maintainers to edit" box, we can try to rebase it and get it in.

@zph
Copy link

zph commented Sep 1, 2017

@ljharb Great :). I'm happier w/ that solution too, but thought this had gotten dusty. I see @estelle's last activity in this thread as May 2015 (#255 (comment)).

@shanemileham
Copy link
Contributor

shanemileham commented Feb 8, 2018

My interpretation of the ideas here is that:

UPPERCASE_VARIABLES are letting the programmer know that they can trust the variable (and its properties) not to change

This is most helpful in situations where the programmer would be unsure if the variable might ever change.

There are a few cases that have come up in the above comments:

  • Variables that can't or shouldn't be changed - these should be uppercased per the above interpretation
  • What about all const variables? - This is unnecessary, so uppercasing should not be used for constants within a file. It should be used for exported constants though.
  • What about exported objects? - Uppercase at the top level of export (e.g. EXPORTED_OBJECT.key) and assume that all nested properties do not change

Which leads to a rule of:

You may optionally UPPERCASE a constant only if it (1) is exported, (2) is a const, and (3) the programmer can trust it (and its nested properties) to never change.

Examples:

// bad
const PRIVATE_VARIABLE = 'should not be unnecessarily uppercased within a file';

// bad
export const THING_TO_BE_CHANGED = 'should obviously not be uppercased';

// bad
export let REASSIGNABLE_VARIABLE = 'do not use let with uppercase variables';

// ---

// allowed but does not supply semantic value
export const apiKey = 'SOMEKEY';

// better in most cases
export const API_KEY = 'SOMEKEY';

// ---

// bad - unnecessarily uppercases key while adding no semantic value
export const MAPPING = {
  KEY: 'value'
};

// good
export const MAPPING = {
  key: 'value'
};

This seems consistent, helpful, and not overbearing. Thoughts? Any cases I'm missing?

@dandv
Copy link
Contributor

dandv commented Feb 9, 2018

@shanemileham: nice writeup! How about members of an options/parameters object that are not intended to be changed during the program's execution, but are configurable nevertheless?

const params = {
    RETRY_DELAY = 5000,
    API_ENDPOINT = '/v1/',
   ...
}

@ljharb
Copy link
Collaborator

ljharb commented Feb 9, 2018

@dandv separate from that being invalid syntax, if you want object properties to be constant, it's best to actually make them nonconfigurable and nonwritable.

@shanemileham that does seem like a good writeup. @estelle, are you willing to either update this PR or check the "allow edits" box?

@estelle
Copy link
Author

estelle commented Feb 9, 2018

@ljharb edits allowed

@ljharb
Copy link
Collaborator

ljharb commented Feb 18, 2018

@shanemileham would you mind converting your comment into a commit on your own fork, and linking that commit here? I can cherry-pick it into this PR (which I've just rebased).

shanemileham added a commit to shanemileham/javascript that referenced this pull request Mar 12, 2018
@shanemileham
Copy link
Contributor

@ljharb I added the comment and cleaned it up - commit is here. Thanks!

Copy link
Collaborator

@ljharb ljharb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM pending one comment

README.md Outdated
@@ -3139,6 +3139,44 @@ Other Style Guides
];
```

<a name="naming--uppercase"></a>
- [23.10](#naming--uppercase) You may optionally uppercase a constant only if it (1) is exported, (2) is a const, and (3) the programmer can trust it (and its nested properties) to never change.
Copy link
Collaborator

@ljharb ljharb Mar 12, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shanemileham "is a const" isn't necessarily clear to me; a const in JS is a variable that's never reassigned. Is that what you mean?

Copy link
Contributor

@shanemileham shanemileham Mar 12, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Literally a const and not let. This just asserts that in addition to not being reassigned, it can't be reassigned. What is the best way to make this more clear?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ljharb (tagging you since idk if you get a notification otherwise)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gotcha - I'll add backticks around it, but otherwise that's probably good as-is :-)

@teohhanhui
Copy link

teohhanhui commented Mar 21, 2018

Per 23.6,

Does this mean that if I have:

const LANGUAGES = [
  // ...
];

export default LANGUAGES;

I should name it LANGUAGES.js?

And do:

import LANGUAGES from './LANGUAGES';

@shanemileham
Copy link
Contributor

shanemileham commented Mar 21, 2018

@teohhanhui Great question! Short answer is yes imho.

23.6 must be followed in all cases; uppercasing is simply optional (superseding 23.8 just as it supersedes normal case rules for constants), and if you choose to do so on a default export, that seems to be the logical conclusion. It seems weird at first, but it's actually really nice to know that an entire file is a constant with just a glance.

Feel free to add that to this PR (assuming consensus) - I think people could benefit from seeing that explicitly.

@ljharb ljharb merged commit 33819d6 into airbnb:master Mar 23, 2018
@borisghidaglia
Copy link

Hello everyone,

A friend and I were questioning the uppercase convention that applies for some kind of constants.

After a bit of digging, I found Google's take on this and MDN's take on this, but neither of those really answer the "why" of this convention.

Thanks to everyone here, Airbnb has a "why" in its style guide :

Why? This is an additional tool to assist in situations where the programmer would be unsure if a variable might ever change. UPPERCASE_VARIABLES are letting the programmer know that they can trust the variable (and its properties) not to change.

Could someone give an example in which "the programmer" would treat a const differently in the code if it's an uppercased one vs a camel-cased one? Does knowing that a variable won't or will change affects what the programmer will do?

If there is no difference, why would one want to keep using this convention?

Thank you!

@ljharb
Copy link
Collaborator

ljharb commented Jul 6, 2022

@borisghidaglia there's a difference between a const - a constant reference - and a constant - a constant value. Uppercase is used to indicate constant VALUES; const does not do this.

@borisghidaglia
Copy link

Hello @ljharb, thanks for your answer.

Of course I agree that these two cases are different.
But what's the added value in uppercasing constant values?

In my question above, I asked for "an example in which "the programmer" would treat a const (be it a constant reference or a constant value) differently in the code if it's an uppercased one vs a camel-cased one".

In my mind, the programmer will have to check the actual value of the const anyway:

  • if the const name is camel-cased, one will have to check its value to know what to do with it (and will indeed discover by doing so, if the const was just a constant reference, or also a constant value)
  • if the const name is uppercased, one might suppose "the author of these lines is probably uppercasing this const to tell me it contains a constant value"... and then will proceed to check the actual value of the const to know how to use it (and will discover by doing so, if the const was just a constant reference, or also a constant value).

Until recently, I was following this rule "by default", and at some point I found myself suggesting to uppercase a const name to a friend during a review. He asked why and I said it was a convention to indicate constant values. He then asked what would change in my usage of this const if it was uppercased vs if it was not... and I could not answer! I mean, one could argue that the programmer can "assume" that it is a constant value and "guess" its value, thus use the const without even checking its content... but this seems unlikely to me.

If you had a practical example to share, it would be really helpful to understand when this convention is really useful.

Thanks again!

@ljharb
Copy link
Collaborator

ljharb commented Jul 19, 2022

@borisghidaglia because it's the signal used in nearly every programming language since the invention of computers to indicate a value that will not change.

That someone might still have to check doesn't change anything; it's still valuable after they check to convey intent.

@lcswillems
Copy link

@ljharb What this signal adds? From a practical point of view, it seems to me it doesn't change anything: it won't change the time I will spend understanding the code or writing it.

If we uppercase to add intent the constant won't change, why not lowercasing (e.g. my_variable) to add intent the constant will change? This adds intent too but we don't do it.

So why the signal the constant won't change is important and merit to be marked?

@ljharb
Copy link
Collaborator

ljharb commented Jul 19, 2022

There is NOTHING more valuable - in a practical sense or any other - than improving readability, which better conveying intent always does.

Most values change, which is why a constant value needs special annotation - because it's rare.

@borisghidaglia
Copy link

@borisghidaglia because it's the signal used in nearly every programming language since the invention of computers to indicate a value that will not change.

That's what I assumed when I did my research before posting here. But even though history of computers is interesting, I don't feel we can use that fact alone to justify this practice.

That someone might still have to check doesn't change anything; it's still valuable after they check to convey intent.

I think you are right on this one. It was a bad argument. As a friend told me afterwards: "it's not because as programmers we often need to check what's inside a variable that we should name them randomly". And in fact properly naming a variable conveys intent as well.

There is NOTHING more valuable - in a practical sense or any other - than improving readability, which better conveying intent always does.

I also agree. But improving readability is not the end goal by itself. Improving readability matters because it allows the programmer to grasp the code quicker, and to grasp it correctly. And that is the problem: I have a hard time finding an example where it is cristal clear that uppercasing makes the difference in these regards.

To try to answer myself to the need for an example I had above, I came up with these examples, stemming from my friend's example about random variable names:

  • If we name a const thisIsAConst, we de not convey anything.
  • If we name a const delay, we convey that this const is about some kind of delay. I think we can agree it is strictly better that the previous name, even though not very explicit.
  • Now, if we name a const DELAY, if feel that as a programmer, and because I've seen this convention everywhere, I will be more likely to assume that this const is some kind of static number, whereas in the previous example, I could have assume it was a function name, for example.

But we could argue that the name "delay" was too unclear to begin with, and that if we used a proper name, we would not really need uppercasing.

For me the conclusion to this is that I was too strict about this convention, thinking it was really making a difference, when in fact it seems to be a much more incremental improvement than properly naming variables (for example). That is probably why this convention is optional in Airbnb style guide!

Thanks @ljharb for your time, I appreciate it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.