Giter Club home page Giter Club logo

naming-cheatsheet's Introduction

Naming cheatsheet

Naming cheatsheet


Naming things is hard. This sheet attempts to make it easier.

Although these suggestions can be applied to any programming language, I will use JavaScript to illustrate them in practice.

English language

Use English language when naming your variables and functions.

/* Bad */
const primerNombre = 'Gustavo'
const amigos = ['Kate', 'John']

/* Good */
const firstName = 'Gustavo'
const friends = ['Kate', 'John']

Like it or not, English is the dominant language in programming: the syntax of all programming languages is written in English, as well as countless documentations and educational materials. By writing your code in English you dramatically increase its cohesiveness.

Naming convention

Pick one naming convention and follow it. It may be camelCase, PascalCase, snake_case, or anything else, as long as it remains consistent. Many programming languages have their own traditions regarding naming conventions; check the documentation for your language or study some popular repositories on GitHub!

/* Bad */
const page_count = 5
const shouldUpdate = true

/* Good */
const pageCount = 5
const shouldUpdate = true

/* Good as well */
const page_count = 5
const should_update = true

S-I-D

A name must be short, intuitive and descriptive:

  • Short. A name must not take long to type and, therefore, remember;
  • Intuitive. A name must read naturally, as close to the common speech as possible;
  • Descriptive. A name must reflect what it does/possesses in the most efficient way.
/* Bad */
const a = 5 // "a" could mean anything
const isPaginatable = a > 10 // "Paginatable" sounds extremely unnatural
const shouldPaginatize = a > 10 // Made up verbs are so much fun!

/* Good */
const postCount = 5
const hasPagination = postCount > 10
const shouldPaginate = postCount > 10 // alternatively

Avoid contractions

Do not use contractions. They contribute to nothing but decreased readability of the code. Finding a short, descriptive name may be hard, but contraction is not an excuse for not doing so.

/* Bad */
const onItmClk = () => {}

/* Good */
const onItemClick = () => {}

Avoid context duplication

A name should not duplicate the context in which it is defined. Always remove the context from a name if that doesn't decrease its readability.

class MenuItem {
  /* Method name duplicates the context (which is "MenuItem") */
  handleMenuItemClick = (event) => { ... }

  /* Reads nicely as `MenuItem.handleClick()` */
  handleClick = (event) => { ... }
}

Reflect the expected result

A name should reflect the expected result.

/* Bad */
const isEnabled = itemCount > 3
return <Button disabled={!isEnabled} />

/* Good */
const isDisabled = itemCount <= 3
return <Button disabled={isDisabled} />

Naming functions

A/HC/LC Pattern

There is a useful pattern to follow when naming functions:

prefix? + action (A) + high context (HC) + low context? (LC)

Take a look at how this pattern may be applied in the table below.

Name Prefix Action (A) High context (HC) Low context (LC)
getUser get User
getUserMessages get User Messages
handleClickOutside handle Click Outside
shouldDisplayMessage should Display Message

Note: The order of context affects the meaning of a variable. For example, shouldUpdateComponent means you are about to update a component, while shouldComponentUpdate tells you that component will update itself, and you are only controlling when it should update. In other words, high context emphasizes the meaning of a variable.


Actions

The verb part of your function name. The most important part responsible for describing what the function does.

get

Accesses data immediately (i.e. shorthand getter of internal data).

function getFruitCount() {
  return this.fruits.length
}

See also compose.

You can use get when performing asynchronous operations as well:

async function getUser(id) {
  const user = await fetch(`/api/user/${id}`)
  return user
}

set

Sets a variable in a declarative way, with value A to value B.

let fruits = 0

function setFruits(nextFruits) {
  fruits = nextFruits
}

setFruits(5)
console.log(fruits) // 5

reset

Sets a variable back to its initial value or state.

const initialFruits = 5
let fruits = initialFruits
setFruits(10)
console.log(fruits) // 10

function resetFruits() {
  fruits = initialFruits
}

resetFruits()
console.log(fruits) // 5

remove

Removes something from somewhere.

For example, if you have a collection of selected filters on a search page, removing one of them from the collection is removeFilter, not deleteFilter (and this is how you would naturally say it in English as well):

function removeFilter(filterName, filters) {
  return filters.filter((name) => name !== filterName)
}

const selectedFilters = ['price', 'availability', 'size']
removeFilter('price', selectedFilters)

See also delete.

delete

Completely erases something from the realms of existence.

Imagine you are a content editor, and there is that notorious post you wish to get rid of. Once you clicked a shiny "Delete post" button, the CMS performed a deletePost action, not removePost.

function deletePost(id) {
  return database.find({ id }).delete()
}

See also remove.

remove or delete?

When the difference between remove and delete is not so obvious to you, I'd suggest looking at their opposite actions - add and create. The key difference between add and create is that add needs a destination while create requires no destination. You add an item to somewhere, but you don't "create it to somewhere". Simply pair remove with add and delete with create.

Explained in detail here.

compose

Creates new data from the existing one. Mostly applicable to strings, objects, or functions.

function composePageUrl(pageName, pageId) {
  return pageName.toLowerCase() + '-' + pageId
}

See also get.

handle

Handles an action. Often used when naming a callback method.

function handleLinkClick() {
  console.log('Clicked a link!')
}

link.addEventListener('click', handleLinkClick)

Context

A domain that a function operates on.

A function is often an action on something. It is important to state what its operable domain is, or at least an expected data type.

/* A pure function operating with primitives */
function filter(list, predicate) {
  return list.filter(predicate)
}

/* Function operating exactly on posts */
function getRecentPosts(posts) {
  return filter(posts, (post) => post.date === Date.now())
}

Some language-specific assumptions may allow omitting the context. For example, in JavaScript, it's common that filter operates on Array. Adding explicit filterArray would be unnecessary.


Prefixes

Prefix enhances the meaning of a variable. It is rarely used in function names.

is

Describes a characteristic or state of the current context (usually boolean).

const color = 'blue'
const isBlue = color === 'blue' // characteristic
const isPresent = true // state

if (isBlue && isPresent) {
  console.log('Blue is present!')
}

has

Describes whether the current context possesses a certain value or state (usually boolean).

/* Bad */
const isProductsExist = productsCount > 0
const areProductsPresent = productsCount > 0

/* Good */
const hasProducts = productsCount > 0

should

Reflects a positive conditional statement (usually boolean) coupled with a certain action.

function shouldUpdateUrl(url, expectedUrl) {
  return url !== expectedUrl
}

min/max

Represents a minimum or maximum value. Used when describing boundaries or limits.

/**
 * Renders a random amount of posts within
 * the given min/max boundaries.
 */
function renderPosts(posts, minPosts, maxPosts) {
  return posts.slice(0, randomBetween(minPosts, maxPosts))
}

prev/next

Indicate the previous or the next state of a variable in the current context. Used when describing state transitions.

async function getPosts() {
  const prevPosts = this.state.posts

  const latestPosts = await fetch('...')
  const nextPosts = concat(prevPosts, latestPosts)

  this.setState({ posts: nextPosts })
}

Singular and Plurals

Like a prefix, variable names can be made singular or plural depending on whether they hold a single value or multiple values.

/* Bad */
const friends = 'Bob'
const friend = ['Bob', 'Tony', 'Tanya']

/* Good */
const friend = 'Bob'
const friends = ['Bob', 'Tony', 'Tanya']

naming-cheatsheet's People

Contributors

abhijit-hota avatar alonronin avatar ayushman17 avatar dandelionadia avatar donatoaguirre24 avatar keis avatar kettanaito avatar maheshbansod avatar mapleccc avatar mhizterkeyz avatar sagarjs avatar sevenoutman avatar shermanhui avatar smv1999 avatar tebb avatar yusufpapurcu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

naming-cheatsheet's Issues

isRoot or hasParent?

a node in a "parent pointing tree" which has no parent, is a root node.
should the method for checking that be isRoot or hasParent ?
also, should setting a node's parent have a method named attach or setParent ?

Questions about naming functions?

The article states that function names should follow the form:

prefix? + Action (A) + High Context (HC) + Low Context? (LC)

Next, the article explains the semantic difference between shouldUpdateComponent() and shouldComponentUpdate() in detail, and argues that the latter is more appropriate in React. I shouldn't have misunderstood it, please correct me if so, thanks!

However, shouldComponentUpdate() seems to be named differently than the A/HC/LC modes mentioned in the article.

  • shouldComponentUpdate - prefix + HC + A
  • shouldUpdateComponent - prefix + A + HC 😲

Based on the guidance in the article, it seems that shouldUpdateComponent() is more appropriate, right?

So, I'm a little confused 🤯, please clarify!

Use of singular/plurals for compound terms

I'd suggest a convention regarding the use of singular/plurals if only I knew how to formulate it in English properly :) Hopefully, someone has a good English formulation to replace mine.

The idea is to pay attention to what noun in a (more-or-less) compound term we employ in plural form when naming things with multiple values. I.e., just as we use, say, documentTypes, I think we should most probably use childPaths instead of childrenPaths, etc.

I've seen this (i.e., using the plural form for all nouns in such composed term) happening a lot and I don't quite agree with it.

Suggested corrections in variable examples

Hi, first of all, a very nice work on how to do better naming of Classes, Functions and Variables in programming! Thanks.

In the example, it looks better to show the distinction b/n a constant and a variable (Ex., talking the JS way)

const initialFruits  = 5;
let fruits = initialFruits;

function getFruits() {
return fruits;
}

function setFruits(newFruits) {
fruits = newFruits;
}

function resetFruits() {
fruits = initialFruits;
}

Just my personal thoughts :-)

Role-based names vs. Information Repetition

The words 'handler', 'callback', ... are often used to add a notion of where a variable/function is going to be used. However, this is very much as useless as naming a variable after its type.

As an example, consider some library to represent countries on a geographical map or so...

# library code
class Country(Widget):
  ...
  def on_click(self, click_handler):
    self.click_handlers.append(click_handler)

And we want to use this library to e.g. draw dots on the respective countries.

# main code

# example: BAD
def my_click_handler(source, click_event):
  paint_circle(source.country_colors, click_event.coordinates)

for _, country in world_map.items():
  country.on_click(my_click_handler)  # BAD: I already expect that `on_click` accepts a click handler 

In this code, the my_click_handler name is meaningless. When reading the main file, you have to read up to the body of the click handler function to know what should happen when a country is clicked.

Imagine a more extreme example:

def divide(nominator, denominator):
  return nominator / denominator

class Vehicle:
  def speed(self):
     nominator = sum(self.distances)
     denominator = time.now() - self.journey_start.time
     return divide(nominator, denominator)   # BAD: this is a repetition of the function parameter names

In both cases, the information in the variable names (my_click_handler, nominator, denominator) are mere repetitions of the parameter names of the called function. This information is already present in the function signature itself, and must not be repeated.

Rather, when the names are chosen to reflect the role the variable/function plays in the program, it becomes much more meaningful:start_time

# example: GOOD
# - the function name reflects what I want to _achieve_ with it
# - the function parameter tells me that I expect a _country_
def mark(country, click_event):
  paint_circle(country.colors, click_event.coordinates)

for _, country in world_map.items():
  country.on_click(mark)  # GOOD: name gives new information in terms of 
class Vehicle:
  def speed(self):
     total_distance = sum(self.distances)
     elapsed_time = time.now() - self.journey_start.time
     return divide(total_distance, elapsed_time)   # GOOD: this represents the physical truth of the program

This naming pattern happens very often for the simple reason that it seems that the role of the variable is determined by the called function (a dependency, external to our own context), and needs no thought.

However, this does not add information and does not help the reader of the code to understand it. Rather, choosing the name according to the role within the context of the own problem domain gives the reader insight in its effective meaning.

Suggestion: difference between verb `remove` and `delete`

Hi Artem, thanks for this cheatsheet and the A/HC/LC pattern!

I still find it bit ambiguous for remove and delete when talking about relations instead of entities. I prefer remove being used on a relation, e.g. remove a member from a team. But the term delete still makes sense if explained as "erases the relation from the realms of existence.".

So I'd suggest explaining the difference between remove and delete by looking at their opposite actions - add and create. I find the key difference between add and create is that add needs a destination while create requires no destination. Readers can get confused when they find something can be either removed or deleted from somewhere, but they will then realize that it can only be added not created to somewhere.

Take the team member relation as an example, I can add a member to a team but cannot "create a member to a team", thus remove is used instead of delete.

Suggestion: Change [Reflect the expected result] to [Reflect the positive result]

When it comes to booleans, instead of Reflect the expected result, I would suggest to use the positive result for the name.

E.g. instead of isDisabled I would use isEnabled.

This avoids mental overhead of having to think about:

  • negating negative variables (e.g. !isDisabled = not not enabled = enabled)
  • which boolean state is expected. (For example, is a button really expected to be disabled?)

verb suggestions

This is a fantastic idea! I hope it becomes a common convention.

Related to #20, replacing remove with drop might help to avoid the remove/delete ambiguity.

I'm looking for what to call something that returns an iterator (in python), and think that collect is another good verb (for i in foo.collectBars())

Add scope and length rule

There's a nice rule that suggests that the verbosity of names should be related to the size of the scope they're visible in.

E.g.

// good: the use and meaning of x is obvious
const example_doubled = example.map(x => x * 2);

// bad: sq and nn are unclear and the length of some_number obscures actual use
const sq = nn.map(some_number => some_number * some_number);

What about abbreviation / Acronyms?

You mention in the docs that "contractions" (like "btn") should be avoided. What about abbreviations or acronyms?
For example: ButtonComp vs ButtonComponent or signUpFG vs signUpFormGroup

Incorrect order of arguments

The Context example has incorrect order of arguments, filter expects first predicate and then list. But it is called with posts list first and then predicate.

/* A pure function operating with primitives */
function filter(predicate, list) {
  return list.filter(predicate)
}

/* Function operating exactly on posts */
function getRecentPosts(posts) {
  return filter(posts, (post) => post.date === Date.now())
}

Possible simplification of shouldDisplayPagination

Great summary.

One question/suggestion - wouldn’t:

const shouldDisplayPagination = (postsCount > 10) // alternatively

be better as:

const shouldPaginate = (postsCount > 10) // alternatively

The latter is more concise and I think expresses the meaning better(though I could have the meaning wrong).

Suggestion: Variable name for arrays

I don't remember in which style guide I've seen the following convention, but IMHO it makes sense.
Instead of using plurals, for naming variables that contains an array, just use "List"

For example:

Good

var users = ['Gabri', 'Tom', 'Dave']

Better

var userList = ['Gabri', 'Tom', 'Dave']

In large codebases is more readable List instead of s

So we can avoid:
users.map(user => {})
but use
userList.map(user => {})

Add Create Action

Since the actions section has "compose" for creating something new from existing data, I think a "create" action should also be added to accommodate creating something from nothing, or something that might not be a direct composition of the inputs e.g. Factory methods. Since only "compose" is included the guide could be misleading as it sounds like compose should be used for all creation actions.

A practical example could be a static factory method for a class e.g.

await Resource.create(config)

I don't thing compose makes sense in such a case.

Feedback about A/HC/LC Pattern

Can you add some additional references/sources for the A/HC/LC pattern you document?

I am familiar with similar standards from BPM (Business Process Management) world where steps are written verb-noun format.
The noun is the input to the step, and the output is noun-verbed. (The BPM book Workflow Modeling is one reference for this verb-noun format) This A/HC/LC pattern has many similarities to naming conventions in the BPM domain. (A good thing for learning/adopting one if you are familiar with the other.)

I read and understood most of the A/HC/LC pattern, but I have some doubts and wondered if its just something that could be explained better. I did not find anything with google when I searched... It feels like there is something good here, so I read it a few times and there are some areas that I am not getting 100% or that I find confusing.

  • I understand the differences with shouldUpdateComponent and shouldComponentUpdate example when I reflect on their meaning without looking at the grammar you defined.
    • But if I look at the grammar, the 2nd case is not mentioned. I think you should consider explicitly defining the prefix? + high context (HC) + action (A) + low context? (LC) case too.
    • In your example there are 2 resources: component and an unknown subject. By a convention/assumption, this unknown subject is to be understood as you. I can accept there is some convention for how to interpret dropped information... But I'd like more explanation about this convention so that I understand how to use the convention safely and have confidence downstream readers will correctly decode there is a 2nd resource and infer who the unknown resource is.
  • Is it true that the "context" (HC or LC) is a noun? If so, I think it would be helpful to say so. This will help people who are familiar with verb-noun and noun-verbed naming conventions. As I read about HC/LC, I want it to be true that they are nouns, but 'click' and 'post' examples in the table are usually verbs... an indicator I am interpreting this wrong... or there needs to be some improvement in explaining things. Perhaps there is an implicit transformation of these verbs into nouns for this context? And this transformation needs to be pointed out because the word can be a verb or noun. Or maybe this is another case of a noun (subject) being dropped like the shouldUpdateComponent being short for shouldYouUpdateComponent?
  • Maybe getPost is an idiom? I think you're talking about the HTTP verb POST. And when I look at it without thinking about this A/HC/LC pattern, I immediately interpret it as getting the posted data or getting the data to be posted. getPost seems to have dropped some detail because it doesn't map to a complete sentence. Hence my thinking that it is an idiom; idioms are learned and are confusing if they aren't explained. My issue with the getPost example is not that I don't understand this specific example's meaning, but that I can't relate it well to the A/HC/LC pattern's grammar. Something about the meaning has been truncated - and its expected I can figure out the meaning without it.
  • It is common to transform a verb into a noun... For example: 'walk dog' (verb noun) can be transformed into another action get dog walker where walk is transformed into walker. This second action is (verb noun noun). Here I think the tuple [noun noun] is an example of HC/LC that you are talking about? post data has the same verb-noun pattern... so using similar transformation I could define another action get data posted (which is like get dog walker). By the previous logic, if get post is an idiom for get data posted, then would get dog be an idiom for get dog walker? Perhaps... but like any idiom, its not going to be clear to some people.

I think there is some good guidance... but to me it feels like it is not quite complete (refined enough for my taste)... (or I am missing something). But its on its way to being complete.

It may be that I need to invest more time to fully understand it, or the writing needs to be refined... or a bit of both.

Negative boolean variable names

Suggestion to explain the best approach for naming negative booleans.

Example: if you create a variable for checking if an object is a dog , you could either do:

const isDog = (dog) => dog.sound() === 'bark'

if (!isDog(pet)) {
    // handle the not dog logic
}

or

const isNotDog = (dog) => dog.sound() !== 'bark'

if (isNotDog(pet)) {
    // handle the not dog logic
}

Plurals Considered Harmful

I think plurals are side effects of English language, because plurals are noun mix up with quantifier, regardless of the complexity of plural spell rules, sometimes plurals are redundant and inappropriate in coding language.

so my suggestion is to use Array or List as quantifier rather than plurals.

/* Bad */
const friends = ['Bob']
const friends = [ ]

/* Good */
const friendArray = ['Bob']
const friendArray = [ ]

/* Good as well */
const friendList = ['Bob']
const friendList = [ ]

English language as go-to option for code

First of all, thank you so much for taking the time on doing this work.

I would like to open up a question about the use of English language in code, since I do think that is not always the case.

English should be considered as a good default, but in terms of importance the business language should comes first. It's not uncommon to see functions, types or variables with a mixed approach of business language and English and I do believe that this should not considered an anti-pattern but enforced instead, maybe with a TRANSLATION.md or GLOSSARY.md somewhere in the project.

While it's true that for consistency is very important, the final objective of labeling (as in variable, functions, type etc) should be to convey as much meaning as possible.

The first step to build a comprehensive ubiquitous language which can serve as a bridge between tech and business should come from the subject-matter expert which might or might not be a native English speaker, code should simply follow as a simple tool used to describe and model the world.

Please go ahead in brings your point of view as we can discuss this further.

Use destroy instead of delete

delete is a reserved word in JavaScript and since this guide helps people decide in generic situations, I’m suggesting to use destroy instead of delete, because in cases where using the word delete are not possible we should be promoting a solution that works everywhere.

Add recommendation about `XhasY` naming

I have encountered a case where a boolean is telling if Entity A has Entity B.
For example, if an admin has members.

How should it be named? (The following are examples of what I have searched)

  • hasAdminMembers
  • adminHasMembers
  • isAdminHavingMembers

I think this would be a good thing to include in this cheatsheet as I, and many others, might have stumbled in such a case.

Include Note About Following Conventions of Specific Languages

First off, thank you for this great contribution! I think we all have wasted too much time trying to name things correctly and you did an excellent job summarizing how to name things well with minimal effort.

As I read through the first section, regarding casing, perhaps there should be a note to follow the conventions of your programming language? I know Python is very big on snake case, and it is often found in C, but would be completely out of place in a C# application. Some languages try very hard to establish conventions around PascalCasing or camelCasing variables.

If you agree that this is important, I would be happy to correct in a PR; I wanted to get your opinion on the matter first. Thank you again!

Add recommendation on how to handle unsafe async / remote fetch functions

Currently the only fetch example is:

function fetchPosts(postCount) {
return fetch('https://api.dev/posts', {...})
}

“Fetch” is a synonym for get, and it — on its own —- implies a safe operation. How should we name unsafe operations that are also async, like update / delete etc?

to continue this pattern, we would expect:

  • fetchPost
  • fetchDeletePost
  • fetchCreatePost
    ... etc

Or, do we just forget the fetch altogether?

I’d like to propose just dropping the “fetchFoo” completely from the style guide, and not distinguish between fetching from a remote service or any other synchronous or asynchronous internal “getFoo” function.

The semantics of “fetchFoo” only differ from “getFoo” in that they encode a data type in the name (a promise), which is a potential code smell. (see #37)

Question about the `is` prefix.

What do we think about the usage of the is prefix with gerund variables. For example, loading.

We could use the prefix:

if (isLoading) {
  doSomething();
}

But does it seems a bit redundant, or is it just me? 😆

if (loading) {
  doSomething();
}

JavaScript getter/setters (S|Get keyword)

👋 hey, this is a great repo/cheatsheet, thanks for this!

A couple points on your get/set examples, in short, they are confusing when compared with each other and conflicts with OO principles.
"Accesses data immediately (i.e. shorthand getter of internal data)."

// Get
function getFruitCount() {
  return this.fruits.length
}

this suggests that getFruitCount is part of either a class or object, which has the property fruits with type array (or other iterable).

const bowl = {
  fruits: ['apple', 'orange', 'pear'],
  getFruitCount() { this.fruits.length },
  get fruitCount() { this.fruits.length }
}

with the example above to get the number of fruits in the bowl, you can do either bowl.getFruitCount() or bowl.fruitCount. If you find you are using getFruitCount often in your code, or you are passing it into another function, it can get unreadable/extraneous quite quickly.

 throw new Error(`Not enough ${bowl.getFruitCount()}`);
 // vs
 throw new Error(`Not enough ${bowl.fruitCount}`);
// Set
let fruits = 0

function setFruits(nextFruits) {
  fruits = nextFruits
}

setFruits(5)

I think this example should either match your get example, or be completely different so it's not confusing, since get/set on an object is thought of to be a matching pair. Currently, I don't see a "benefit" of using this set function over a simple fruits = randomNumber() or fruits = 5 especially with the current scoping. If you were to match the getter method (get keyword), the example would look like this.

const bowl = {
  fruits: 0, 
  get fruitCount() { this.fruits },
  set fruitCount(val) { 
    if (typeof val === 'number') {
      fruits = val
  } else {
     throw new Error('You need to provide a number');
  }
}
console.log(bowl.fruitCount) // 0;
bowl.fruitCount = 5;
console.log(bowl.fruitCount) // 5;
bowl.fruitCount = "invalid"; // throws Error 

the key words, in js and other languages usually allow for those sorts of protections against setting (and getting a private field without exposing the field's value directly).

To avoid this confusion, I think you should either explain getters/setters vs a function with get/set in the name and provide an example of both, or more simply, use a pure function as an example.

function getRandomFruit() { /* returns a fruit */ }
function setTheme(palette) { /* changes UI theme to light | dark mode */ }

Consider "High signal per word ratio" rather than "short"

In my experience, "high signal per word ratio" is a more accurate intuition in practice rather than "short". Focusing on "short" alone can lead to unnecessary dilemmas *

I'm curious what the author thinks of the above.

* e.g. when you try to describe concepts that is complex enough to require many words.

Suggestion: Add section or clarification about datatypes in variable names

One major contributor of code smell (in my opinion) is code that superfluously includes the type of the thing in its name. (e.g. List itemList, or CREATE TABLE itemTable instead of just items). This goes hand-in-hand with the "avoid context-duplication" rule too.

One edge-case to consider is date type variables- whereby you may have item.dateAdded, and simply removing the type from the name leaves you with item.added, which is very unclear (sounds more like a boolean flag set if the item has been added). My personal preference is to follow the form of At. So, dateAdded would be addedAt. This defies the A/HC/LC pattern somewhat however, so take it as you will.

State-of-being verbs

I recently prepared a presentation on the topic of variable naming for juniors, and I ended up going down the 8th grade English rabbit hole.

Something that I found fascinating, and I think worth noting, is that the "prefixes" in this guide align strongly with "state-of-being verbs"... "is", "has", "was", "should", etc.

In a sense, they straddle the gap between adjectives and verbs, in that they define the state of a thing via verbs.

https://www.google.com/search?q=state+of+being+verbs

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.