├── .github
└── FUNDING.yml
├── LICENSE.md
├── README.md
└── naming-cheatsheet.png
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: kettanaito
2 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018—preset Artem Zakharchenko
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
6 |
7 | # Naming cheatsheet
8 |
9 | - [English language](#english-language)
10 | - [Naming convention](#naming-convention)
11 | - [S-I-D](#s-i-d)
12 | - [Avoid contractions](#avoid-contractions)
13 | - [Avoid context duplication](#avoid-context-duplication)
14 | - [Reflect the expected result](#reflect-the-expected-result)
15 | - [Naming functions](#naming-functions)
16 | - [A/HC/LC pattern](#ahclc-pattern)
17 | - [Actions](#actions)
18 | - [Context](#context)
19 | - [Prefixes](#prefixes)
20 | - [Singular and Plurals](#singular-and-plurals)
21 |
22 | ---
23 |
24 | Naming things is hard. This sheet attempts to make it easier.
25 |
26 | Although these suggestions can be applied to any programming language, I will use JavaScript to illustrate them in practice.
27 |
28 | ## English language
29 |
30 | Use English language when naming your variables and functions.
31 |
32 | ```js
33 | /* Bad */
34 | const primerNombre = 'Gustavo'
35 | const amigos = ['Kate', 'John']
36 |
37 | /* Good */
38 | const firstName = 'Gustavo'
39 | const friends = ['Kate', 'John']
40 | ```
41 |
42 | > 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.
43 |
44 | ## Naming convention
45 |
46 | 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!
47 |
48 | ```js
49 | /* Bad */
50 | const page_count = 5
51 | const shouldUpdate = true
52 |
53 | /* Good */
54 | const pageCount = 5
55 | const shouldUpdate = true
56 |
57 | /* Good as well */
58 | const page_count = 5
59 | const should_update = true
60 | ```
61 |
62 | ## S-I-D
63 |
64 | A name must be _short_, _intuitive_ and _descriptive_:
65 |
66 | - **Short**. A name must not take long to type and, therefore, remember;
67 | - **Intuitive**. A name must read naturally, as close to the common speech as possible;
68 | - **Descriptive**. A name must reflect what it does/possesses in the most efficient way.
69 |
70 | ```js
71 | /* Bad */
72 | const a = 5 // "a" could mean anything
73 | const isPaginatable = a > 10 // "Paginatable" sounds extremely unnatural
74 | const shouldPaginatize = a > 10 // Made up verbs are so much fun!
75 |
76 | /* Good */
77 | const postCount = 5
78 | const hasPagination = postCount > 10
79 | const shouldPaginate = postCount > 10 // alternatively
80 | ```
81 |
82 | ## Avoid contractions
83 |
84 | 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.
85 |
86 | ```js
87 | /* Bad */
88 | const onItmClk = () => {}
89 |
90 | /* Good */
91 | const onItemClick = () => {}
92 | ```
93 |
94 | ## Avoid context duplication
95 |
96 | 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.
97 |
98 | ```js
99 | class MenuItem {
100 | /* Method name duplicates the context (which is "MenuItem") */
101 | handleMenuItemClick = (event) => { ... }
102 |
103 | /* Reads nicely as `MenuItem.handleClick()` */
104 | handleClick = (event) => { ... }
105 | }
106 | ```
107 |
108 | ## Reflect the expected result
109 |
110 | A name should reflect the expected result.
111 |
112 | ```jsx
113 | /* Bad */
114 | const isEnabled = itemCount > 3
115 | return
116 |
117 | /* Good */
118 | const isDisabled = itemCount <= 3
119 | return
120 | ```
121 |
122 | ---
123 |
124 | # Naming functions
125 |
126 | ## A/HC/LC Pattern
127 |
128 | There is a useful pattern to follow when naming functions:
129 |
130 | ```
131 | prefix? + action (A) + high context (HC) + low context? (LC)
132 | ```
133 |
134 | Take a look at how this pattern may be applied in the table below.
135 |
136 | | Name | Prefix | Action (A) | High context (HC) | Low context (LC) |
137 | | ---------------------- | -------- | ---------- | ----------------- | ---------------- |
138 | | `getUser` | | `get` | `User` | |
139 | | `getUserMessages` | | `get` | `User` | `Messages` |
140 | | `handleClickOutside` | | `handle` | `Click` | `Outside` |
141 | | `shouldDisplayMessage` | `should` | `Display` | `Message` | |
142 |
143 | > **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.
144 | > In other words, **high context emphasizes the meaning of a variable**.
145 |
146 | ---
147 |
148 | ## Actions
149 |
150 | The verb part of your function name. The most important part responsible for describing what the function _does_.
151 |
152 | ### `get`
153 |
154 | Accesses data immediately (i.e. shorthand getter of internal data).
155 |
156 | ```js
157 | function getFruitCount() {
158 | return this.fruits.length
159 | }
160 | ```
161 |
162 | > See also [compose](#compose).
163 |
164 | You can use `get` when performing asynchronous operations as well:
165 |
166 | ```js
167 | async function getUser(id) {
168 | const user = await fetch(`/api/user/${id}`)
169 | return user
170 | }
171 | ```
172 |
173 | ### `set`
174 |
175 | Sets a variable in a declarative way, with value `A` to value `B`.
176 |
177 | ```js
178 | let fruits = 0
179 |
180 | function setFruits(nextFruits) {
181 | fruits = nextFruits
182 | }
183 |
184 | setFruits(5)
185 | console.log(fruits) // 5
186 | ```
187 |
188 | ### `reset`
189 |
190 | Sets a variable back to its initial value or state.
191 |
192 | ```js
193 | const initialFruits = 5
194 | let fruits = initialFruits
195 | setFruits(10)
196 | console.log(fruits) // 10
197 |
198 | function resetFruits() {
199 | fruits = initialFruits
200 | }
201 |
202 | resetFruits()
203 | console.log(fruits) // 5
204 | ```
205 |
206 | ### `remove`
207 |
208 | Removes something _from_ somewhere.
209 |
210 | 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):
211 |
212 | ```js
213 | function removeFilter(filterName, filters) {
214 | return filters.filter((name) => name !== filterName)
215 | }
216 |
217 | const selectedFilters = ['price', 'availability', 'size']
218 | removeFilter('price', selectedFilters)
219 | ```
220 |
221 | > See also [delete](#delete).
222 |
223 | ### `delete`
224 |
225 | Completely erases something from the realms of existence.
226 |
227 | 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`.
228 |
229 | ```js
230 | function deletePost(id) {
231 | return database.find({ id }).delete()
232 | }
233 | ```
234 |
235 | > See also [remove](#remove).
236 |
237 | > **`remove` or `delete`?**
238 | >
239 | > When the difference between `remove` and `delete` is not so obvious to you, I'd suggest looking at their opposite actions - `add` and `create`.
240 | > 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_".
241 | > Simply pair `remove` with `add` and `delete` with `create`.
242 | >
243 | > Explained in detail [here](https://github.com/kettanaito/naming-cheatsheet/issues/74#issue-1174942962).
244 |
245 | ### `compose`
246 |
247 | Creates new data from the existing one. Mostly applicable to strings, objects, or functions.
248 |
249 | ```js
250 | function composePageUrl(pageName, pageId) {
251 | return pageName.toLowerCase() + '-' + pageId
252 | }
253 | ```
254 |
255 | > See also [get](#get).
256 |
257 | ### `handle`
258 |
259 | Handles an action. Often used when naming a callback method.
260 |
261 | ```js
262 | function handleLinkClick() {
263 | console.log('Clicked a link!')
264 | }
265 |
266 | link.addEventListener('click', handleLinkClick)
267 | ```
268 |
269 | ---
270 |
271 | ## Context
272 |
273 | A domain that a function operates on.
274 |
275 | 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.
276 |
277 | ```js
278 | /* A pure function operating with primitives */
279 | function filter(list, predicate) {
280 | return list.filter(predicate)
281 | }
282 |
283 | /* Function operating exactly on posts */
284 | function getRecentPosts(posts) {
285 | return filter(posts, (post) => post.date === Date.now())
286 | }
287 | ```
288 |
289 | > 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.
290 |
291 | ---
292 |
293 | ## Prefixes
294 |
295 | Prefix enhances the meaning of a variable. It is rarely used in function names.
296 |
297 | ### `is`
298 |
299 | Describes a characteristic or state of the current context (usually `boolean`).
300 |
301 | ```js
302 | const color = 'blue'
303 | const isBlue = color === 'blue' // characteristic
304 | const isPresent = true // state
305 |
306 | if (isBlue && isPresent) {
307 | console.log('Blue is present!')
308 | }
309 | ```
310 |
311 | ### `has`
312 |
313 | Describes whether the current context possesses a certain value or state (usually `boolean`).
314 |
315 | ```js
316 | /* Bad */
317 | const isProductsExist = productsCount > 0
318 | const areProductsPresent = productsCount > 0
319 |
320 | /* Good */
321 | const hasProducts = productsCount > 0
322 | ```
323 |
324 | ### `should`
325 |
326 | Reflects a positive conditional statement (usually `boolean`) coupled with a certain action.
327 |
328 | ```js
329 | function shouldUpdateUrl(url, expectedUrl) {
330 | return url !== expectedUrl
331 | }
332 | ```
333 |
334 | ### `min`/`max`
335 |
336 | Represents a minimum or maximum value. Used when describing boundaries or limits.
337 |
338 | ```js
339 | /**
340 | * Renders a random amount of posts within
341 | * the given min/max boundaries.
342 | */
343 | function renderPosts(posts, minPosts, maxPosts) {
344 | return posts.slice(0, randomBetween(minPosts, maxPosts))
345 | }
346 | ```
347 |
348 | ### `prev`/`next`
349 |
350 | Indicate the previous or the next state of a variable in the current context. Used when describing state transitions.
351 |
352 | ```jsx
353 | async function getPosts() {
354 | const prevPosts = this.state.posts
355 |
356 | const latestPosts = await fetch('...')
357 | const nextPosts = concat(prevPosts, latestPosts)
358 |
359 | this.setState({ posts: nextPosts })
360 | }
361 | ```
362 |
363 | ## Singular and Plurals
364 |
365 | Like a prefix, variable names can be made singular or plural depending on whether they hold a single value or multiple values.
366 |
367 | ```js
368 | /* Bad */
369 | const friends = 'Bob'
370 | const friend = ['Bob', 'Tony', 'Tanya']
371 |
372 | /* Good */
373 | const friend = 'Bob'
374 | const friends = ['Bob', 'Tony', 'Tanya']
375 | ```
376 |
--------------------------------------------------------------------------------
/naming-cheatsheet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kettanaito/naming-cheatsheet/7b90cd7b2d3ccb104a4443d5e7e152b8fd400533/naming-cheatsheet.png
--------------------------------------------------------------------------------