DEV Community

Cover image for Writing Self-Documenting Code 🧑‍💻📜

Writing Self-Documenting Code 🧑‍💻📜

Matt Lewandowski on May 29, 2024

As developers, we've all wasted hours, staring at a piece of code, trying to decipher its purpose, and wondering what the original author was think...
Collapse
 
chasm profile image
Charles F. Munat

Other that JSDoc/TSDoc I am in full agreement. Excellent article.

But I would also mention that consistency in naming is important. Establish a style guide and define your terms so everyone is on the same page.

For example, consider these terms. What do they mean and how do you choose between them:
get, find, make, create, choose, select, send, submit, save, etc.

Perhaps get means you are retrieving a single value from an API and list means you are retrieving a set of values. Then every function that retrieves a single value should be named get<noun> and the corresponding multiple values function, list<noun>s, e.g.,

getUsername()
listUsers()
Enter fullscreen mode Exit fullscreen mode
Collapse
 
mattlewandowski93 profile image
Matt Lewandowski

Great point, thanks! I've added a new section that covers this: Establish Consistency and Set Expectations in a Team.

Collapse
 
z2lai profile image
z2lai

Incredible advice. Im currently dealing with a codebase where there are several functions, addItem, saveItem, createItem all in the same app service and they all actually do the same thing with slight variations.

Collapse
 
chasm profile image
Charles F. Munat

Yep. The secret to programming is a) to break the problem down into small, easily-solvable mini-problems, then solve those in the simplest, clearest, and most consistent way, then compose the small solutions back into the overall solution. Clear style guides followed faithfully and invariably are essential, but how many companies bother? Save a penny, lose a pound.

All of this boils down to one simple thing: reduce cognitive load. Reduce cognitive load. Reduce cognitive load.

To this end, it pays also to apply design principles to your code. For example: proximity, alignment, contrast, repetition (consistency), whitespace, etc. I discuss this and more on Craft Code as well as here on Dev.to.

Collapse
 
thirumalesh profile image
thirumaleshthiru

ss

Collapse
 
ausmurp profile image
Austin Murphy

Self documenting code is a fine standard to follow, but you should still have code comments. I've worked with multiple developers who said "my code is self documenting so why comment?" 🤣 Then when they leave, nobody knows WHY they were doing the things they did, regardless of how self documenting the code is.

Please comment your code as well.

Collapse
 
retakenroots profile image
Rene Kootstra

The need for comments in code is the lack of tests. Comments rot very fast. Uncle Bob has excellent videos on the matter.

Collapse
 
chris_sd_b9194652dbd4a1e profile image
Chris S-D

Agreed, but IMHO, only when there is a potential "why?" question that needs to be answered.

I usually use linters as a great way to enforce this. Generally speaking, I only ever set linters to error if the code doesn't follow standards.

If the person has a reason to break standards, they need to put in a linter comment to allow the code that breaks the pattern and they are required to provide a reason that they are breaking the lint pattern. For those that can't be linted, we handle in PR. If you're doing something that is not obvious and you can't make it obvious, then you must provide a comment clarifying the issue and why you're doing it that way.

Otherwise, you should only ever use doc comments.

Comments should never describe what you are doing, nor how, only why and only when it's not obvious.

Collapse
 
jamescurran profile image
James Curran

Exactly. The code can only tell you what it does. Code comments are there to tell you what it's SUPPOSED to do.

Collapse
 
documendous profile image
Documendous

Very nice work, Matt! Thanks for the post.

Collapse
 
ricardogesteves profile image
Ricardo Esteves

Cool, nice article @mattlewandowski93 !

Collapse
 
ghadzhigeorgiev profile image
Georgi Hadzhigeorgiev

Nice one, but I suggest for you to include using of strongly typed IDs.

Collapse
 
mattlewandowski93 profile image
Matt Lewandowski

Thanks, great suggestions I'll add it in

Collapse
 
shyam_10 profile image
Shyam raj

Wow.. Really interesting, thank u mate❤️

Collapse
 
kwoodgmr profile image
kwood-gmr

Good article, though I would disagree with using Enums in Typescript. The thing is that they are kind of funky and don't translate in and out of the underlying type well. It can better be expressed as:

`export const PaymentStatus {
Pending = 'pending',
Completed = 'completed',
Failed = 'failed',
} as const;

export type PaymentStatus = (typeof PaymentStatus)[keyof PaymentStatus];
`

Collapse
 
jakewilson profile image
Jake Wilson

I would urge caution about breaking a large function into too many smaller functions just for the sake of making it smaller. It can lead to too much abstraction that becomes less readable because you are trying to follow the code around separate, spread out methods and files etc.

Collapse
 
gokayburuc profile image
gokayburuc.dev

It's a great explanation of the principle of "create a meaningful standard language", which is one of the principles that programmers should follow.

However, there are still missing parts. In particular, there is a need to add meaningful comment statements next to the codes and comment notations.

// TODO :
//REVIEW :
// FIX :
// TEST :
// OPTIMIZE :
// NOTE:
// HACK:
Enter fullscreen mode Exit fullscreen mode

Comment expression notations provide the user with mobility for immediate intervention on faulty points.

Collapse
 
lincpa profile image
Lin Pengcheng
Collapse
 
itsmeseb profile image
sebkolind

Great article! I think there are a lot of good ideas and valid points. I am not a fan of (2.) though - it seems like taken right out of the "Clean Code" book. It's a pain jumping from function to function to function, and you most likely lose context. I would like a bigger function where the entire context is visible and ready for me to read.

Collapse
 
corscheid profile image
Corey Scheideman

Recommending the use of TypeScript Enums is an interesting take I don't often see. 😅

Collapse
 
mattlewandowski93 profile image
Matt Lewandowski • Edited

I think Enums have their place in typescript, even if you can use types most of the time. I listed types first, as I do prefer types for most cases. Here is an example of where an enum would shine over a type though.

enum HttpStatus {
  OK = 200,
  BadRequest = 400,
  Unauthorized = 401,
  Forbidden = 403,
  NotFound = 404,
  InternalServerError = 500,
}
Enter fullscreen mode Exit fullscreen mode

with a type

const HttpStatus = {
  OK: 200,
  BadRequest: 400,
  Unauthorized: 401,
  Forbidden: 403,
  NotFound: 404,
  InternalServerError: 500,
} as const;

// Define the type
type HttpStatus = (typeof HttpStatus)[keyof typeof HttpStatus];
Enter fullscreen mode Exit fullscreen mode

With the enum in this case, we can utilize the bidirectional mapping. Which allows us to use the single Enum to determine the status and code of different scenarios.

console.log(HttpStatus[200]); // Outputs: "OK"
console.log(HttpStatus.OK); // Outputs: 200
Enter fullscreen mode Exit fullscreen mode

Ultimately, I think that enums are a lot more verbose, making them more self-documenting. HttpStatus.OK or HttpStatus.BadRequest is very intuitive.

Collapse
 
neurabot profile image
Neurabot

Nice. A shine perspective.

Collapse
 
marcelomazza profile image
Marcelo Mazza

this is good advice, thanks. It surprises how one still finds codebases with any lack of common sense... :)

Collapse
 
aloisseckar profile image
Alois Sečkár

Good summary. Why you shouldn't use enums in TS though...

Collapse
 
mattlewandowski93 profile image
Matt Lewandowski

Interesting, thanks for sharing. I’ve never considered how enums were compiled.

Collapse
 
zakari714 profile image
Zakari Adamu

Awesome! Nice one bruv

Collapse
 
retakenroots profile image
Rene Kootstra

Excellent points but you lost me after at point 4. Is still don't like the TS compilation step. It slows down development. For me at least.

Collapse
 
mattlewandowski93 profile image
Matt Lewandowski

TS is just an example. The idea extends to any strongly typed programming language.

Collapse
 
krishankumarmourya profile image
Krishan Kumar Mourya

Great suggestions. I am following more than 90% of the above suggestions.