[
  {
    "path": ".github/FUNDING.yml",
    "content": "github: kettanaito\n"
  },
  {
    "path": "LICENSE.md",
    "content": "MIT License\n\nCopyright (c) 2018—preset Artem Zakharchenko\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "<p align=\"center\">\n  <a href=\"https://github.com/kettanaito/naming-cheatsheet\">\n    <img src=\"./naming-cheatsheet.png\" alt=\"Naming cheatsheet\" />\n  </a>\n</p>\n\n# Naming cheatsheet\n\n- [English language](#english-language)\n- [Naming convention](#naming-convention)\n- [S-I-D](#s-i-d)\n- [Avoid contractions](#avoid-contractions)\n- [Avoid context duplication](#avoid-context-duplication)\n- [Reflect the expected result](#reflect-the-expected-result)\n- [Naming functions](#naming-functions)\n  - [A/HC/LC pattern](#ahclc-pattern)\n    - [Actions](#actions)\n    - [Context](#context)\n    - [Prefixes](#prefixes)\n- [Singular and Plurals](#singular-and-plurals)\n\n---\n\nNaming things is hard. This sheet attempts to make it easier.\n\nAlthough these suggestions can be applied to any programming language, I will use JavaScript to illustrate them in practice.\n\n## English language\n\nUse English language when naming your variables and functions.\n\n```js\n/* Bad */\nconst primerNombre = 'Gustavo'\nconst amigos = ['Kate', 'John']\n\n/* Good */\nconst firstName = 'Gustavo'\nconst friends = ['Kate', 'John']\n```\n\n> 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.\n\n## Naming convention\n\nPick **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!\n\n```js\n/* Bad */\nconst page_count = 5\nconst shouldUpdate = true\n\n/* Good */\nconst pageCount = 5\nconst shouldUpdate = true\n\n/* Good as well */\nconst page_count = 5\nconst should_update = true\n```\n\n## S-I-D\n\nA name must be _short_, _intuitive_ and _descriptive_:\n\n- **Short**. A name must not take long to type and, therefore, remember;\n- **Intuitive**. A name must read naturally, as close to the common speech as possible;\n- **Descriptive**. A name must reflect what it does/possesses in the most efficient way.\n\n```js\n/* Bad */\nconst a = 5 // \"a\" could mean anything\nconst isPaginatable = a > 10 // \"Paginatable\" sounds extremely unnatural\nconst shouldPaginatize = a > 10 // Made up verbs are so much fun!\n\n/* Good */\nconst postCount = 5\nconst hasPagination = postCount > 10\nconst shouldPaginate = postCount > 10 // alternatively\n```\n\n## Avoid contractions\n\nDo **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.\n\n```js\n/* Bad */\nconst onItmClk = () => {}\n\n/* Good */\nconst onItemClick = () => {}\n```\n\n## Avoid context duplication\n\nA 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.\n\n```js\nclass MenuItem {\n  /* Method name duplicates the context (which is \"MenuItem\") */\n  handleMenuItemClick = (event) => { ... }\n\n  /* Reads nicely as `MenuItem.handleClick()` */\n  handleClick = (event) => { ... }\n}\n```\n\n## Reflect the expected result\n\nA name should reflect the expected result.\n\n```jsx\n/* Bad */\nconst isEnabled = itemCount > 3\nreturn <Button disabled={!isEnabled} />\n\n/* Good */\nconst isDisabled = itemCount <= 3\nreturn <Button disabled={isDisabled} />\n```\n\n---\n\n# Naming functions\n\n## A/HC/LC Pattern\n\nThere is a useful pattern to follow when naming functions:\n\n```\nprefix? + action (A) + high context (HC) + low context? (LC)\n```\n\nTake a look at how this pattern may be applied in the table below.\n\n| Name                   | Prefix   | Action (A) | High context (HC) | Low context (LC) |\n| ---------------------- | -------- | ---------- | ----------------- | ---------------- |\n| `getUser`              |          | `get`      | `User`            |                  |\n| `getUserMessages`      |          | `get`      | `User`            | `Messages`       |\n| `handleClickOutside`   |          | `handle`   | `Click`           | `Outside`        |\n| `shouldDisplayMessage` | `should` | `Display`  | `Message`         |                  |\n\n> **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.\n> In other words, **high context emphasizes the meaning of a variable**.\n\n---\n\n## Actions\n\nThe verb part of your function name. The most important part responsible for describing what the function _does_.\n\n### `get`\n\nAccesses data immediately (i.e. shorthand getter of internal data).\n\n```js\nfunction getFruitCount() {\n  return this.fruits.length\n}\n```\n\n> See also [compose](#compose).\n\nYou can use `get` when performing asynchronous operations as well:\n\n```js\nasync function getUser(id) {\n  const user = await fetch(`/api/user/${id}`)\n  return user\n}\n```\n\n### `set`\n\nSets a variable in a declarative way, with value `A` to value `B`.\n\n```js\nlet fruits = 0\n\nfunction setFruits(nextFruits) {\n  fruits = nextFruits\n}\n\nsetFruits(5)\nconsole.log(fruits) // 5\n```\n\n### `reset`\n\nSets a variable back to its initial value or state.\n\n```js\nconst initialFruits = 5\nlet fruits = initialFruits\nsetFruits(10)\nconsole.log(fruits) // 10\n\nfunction resetFruits() {\n  fruits = initialFruits\n}\n\nresetFruits()\nconsole.log(fruits) // 5\n```\n\n### `remove`\n\nRemoves something _from_ somewhere.\n\nFor 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):\n\n```js\nfunction removeFilter(filterName, filters) {\n  return filters.filter((name) => name !== filterName)\n}\n\nconst selectedFilters = ['price', 'availability', 'size']\nremoveFilter('price', selectedFilters)\n```\n\n> See also [delete](#delete).\n\n### `delete`\n\nCompletely erases something from the realms of existence.\n\nImagine 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`.\n\n```js\nfunction deletePost(id) {\n  return database.find({ id }).delete()\n}\n```\n\n> See also [remove](#remove).\n\n> **`remove` or `delete`?**\n>\n> When the difference between `remove` and `delete` is not so obvious to you, I'd suggest looking at their opposite actions - `add` and `create`.\n> 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_\".\n> Simply pair `remove` with `add` and `delete` with `create`.\n>\n> Explained in detail [here](https://github.com/kettanaito/naming-cheatsheet/issues/74#issue-1174942962).\n\n### `compose`\n\nCreates new data from the existing one. Mostly applicable to strings, objects, or functions.\n\n```js\nfunction composePageUrl(pageName, pageId) {\n  return pageName.toLowerCase() + '-' + pageId\n}\n```\n\n> See also [get](#get).\n\n### `handle`\n\nHandles an action. Often used when naming a callback method.\n\n```js\nfunction handleLinkClick() {\n  console.log('Clicked a link!')\n}\n\nlink.addEventListener('click', handleLinkClick)\n```\n\n---\n\n## Context\n\nA domain that a function operates on.\n\nA function is often an action on _something_. It is important to state what its operable domain is, or at least an expected data type.\n\n```js\n/* A pure function operating with primitives */\nfunction filter(list, predicate) {\n  return list.filter(predicate)\n}\n\n/* Function operating exactly on posts */\nfunction getRecentPosts(posts) {\n  return filter(posts, (post) => post.date === Date.now())\n}\n```\n\n> 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.\n\n---\n\n## Prefixes\n\nPrefix enhances the meaning of a variable. It is rarely used in function names.\n\n### `is`\n\nDescribes a characteristic or state of the current context (usually `boolean`).\n\n```js\nconst color = 'blue'\nconst isBlue = color === 'blue' // characteristic\nconst isPresent = true // state\n\nif (isBlue && isPresent) {\n  console.log('Blue is present!')\n}\n```\n\n### `has`\n\nDescribes whether the current context possesses a certain value or state (usually `boolean`).\n\n```js\n/* Bad */\nconst isProductsExist = productsCount > 0\nconst areProductsPresent = productsCount > 0\n\n/* Good */\nconst hasProducts = productsCount > 0\n```\n\n### `should`\n\nReflects a positive conditional statement (usually `boolean`) coupled with a certain action.\n\n```js\nfunction shouldUpdateUrl(url, expectedUrl) {\n  return url !== expectedUrl\n}\n```\n\n### `min`/`max`\n\nRepresents a minimum or maximum value. Used when describing boundaries or limits.\n\n```js\n/**\n * Renders a random amount of posts within\n * the given min/max boundaries.\n */\nfunction renderPosts(posts, minPosts, maxPosts) {\n  return posts.slice(0, randomBetween(minPosts, maxPosts))\n}\n```\n\n### `prev`/`next`\n\nIndicate the previous or the next state of a variable in the current context. Used when describing state transitions.\n\n```jsx\nasync function getPosts() {\n  const prevPosts = this.state.posts\n\n  const latestPosts = await fetch('...')\n  const nextPosts = concat(prevPosts, latestPosts)\n\n  this.setState({ posts: nextPosts })\n}\n```\n\n## Singular and Plurals\n\nLike a prefix, variable names can be made singular or plural depending on whether they hold a single value or multiple values.\n\n```js\n/* Bad */\nconst friends = 'Bob'\nconst friend = ['Bob', 'Tony', 'Tanya']\n\n/* Good */\nconst friend = 'Bob'\nconst friends = ['Bob', 'Tony', 'Tanya']\n```\n"
  }
]