What is code formatting?
In this post I describe how to think about code formatting and how to do it correctly.
Spoiler - There is more than 1 correct answer!
Code is a text that tells the computer what to do - what instructions to perform.
In high level code it’s abstracted in special keywords with expressions, clauses and blocks.
Before we discuss elements of code I want to discuss the concept of Code as Text.
To simplify writing code - a special language is used.
The most popular languages are based on the English/Latin language.
Keywords for example: if
, for
, while
, with
, etc…
To understand how to format code we should consider how to format regular text.
Formatting creates a better reading experience.
If we kept everything untidy it would look very chaotic.
Let’s take this silly email:
There are error identations, different symbols, grammer mistakes and non aligned text.
When we write something we want to be clear as possible.
Direction of language -
Right to left, up-down or left to right.
The direction will set up the flow the reader will follow.
Headlines -
Summarizes ideas or make it more interesting to read.
Paragraphs -
Splitting ideas and information into different text blocks.
Spaces and Identation -
White space splits better between ideas and paragraphs.
Identation gives us a clear hierarchy of information.
No spaces:
Spaces:
Symbols -
All text are basically familiar glyphs that we know how to read.
There are symbols that we add information but are not actually read phonetically.
Read this sentence:THE CAT HAS GONE!
If you didn’t scream it or imagined a higher intense voice, you probably didn’t read it.
Styling -
Styling texts adds better emphasis on ideas.
Splitters -
Splitting text with actual splitters and not just white spaces or identation gives us a more clear guidance that a section has been ended or the idea has shifted.
For example:
The line beneath the headline gives us clear information that the pervious section has ended.
Font -
Fonts may deliver a different idea based on their graphical design.
Repeating styling / Conventions -
When we use a certain style we expect to see this style more often - if a convention breaks and we do not deliever in the same manner the reader would be very confused.
In general - No consistency.
Few examples on how to stay consistent:
Templating -
Prior to beginning writing, deciding on a template can help us deliever more consistent text.
A good example for it would be a presentation, When working with Powerpoint it lets you select a template for the presentation.
The main idea in a template is to stay consistent.
Alignment elements clears noise around the idea and allow us to split an idea into smaller points.
Reading elements help us introduce variaty and guide the reader to the right information.
However, there are certain elements that - when misused - create a worse reading experience.
Major eye catchers -
When reading our eyes tend to jump to locations that we may precieve as more important.
Eye jumping -
When you seek information your eyes tend to jump from paragraph to paragraph.
Either reading the first sentence to get a clear idea or trying to glance at headlines or images.
Table of contents -
TOC allows us to summarize and present a smaller view of our whole text.
In general - a smaller summary of the text.
Splitters -
If the text has been splitted correctly we can jump to the correct information that we seek.
Known vocabulary -
When seeking something specific we analyze the text to see if a certain word is presented.
For example:
If I want to find which movies a director has made I’ll look in the correct section in the table of contents.
Ctrl + F
friendliness -
Headers and the right vocabulary helps the reader to find information quicker.
If the text supports finding keywords more easily and in the right location it would be even quicker to find it using Ctrl+F
.
The same ideas that we use to write texts, books, papers, etc…
Can be - and should be - used to write code.
In this exmaple I maksed the actual code.
So what elements are there in this code?
Identation is spaces or tabs in a line.
Identation keeps the hierarchy very clear.
It’s one of the most improtatnt tools for formatting the code.
No identations:
1 | var hasAbovePiece = !isUpSide; |
Identations:
1 | var hasAbovePiece = !isUpSide; |
Spaces seperate between implementation details.
No spaces:
1 | class Menu: |
Spaces:
1 | class Menu: |
Spaces help to create less strain on the eyes and the brain by seperating details.
This section for example:
1 | userInput = input('Please Enter to Begin, C to exit: ') |
The 3 ideas are:
Each marked block consists of a ceratin information - we do not blend between them.
This is highly recommended by the principle Single responsibility
.
Each “Block” contains a single general idea.
One of the most common blocks is - a Function
!
Functions seperate implementation details by creating actions.
1 | public void Main(string[] args) |
By using loops
and if
statements we create another block that is identified easily.
Pro tip: Make statements more visible.
That’s why I prefer to put spaces before and after statements and seperate brackets { }
into new lines:
1 | var race = character.Race; |
{ }
Brackets are symbols that seperate code into elements called Blocks.
A block of code not only seperate the code into ideas but in some languages defines the scope of variables.
So something inside a block isn’t “leaked” outside of the block.
C++ code for example:
1 | { |
This would produce a compilation error because we defined a variable out of scope.
An endless argument is To put new lines or not?
Same lines:
1 | var race = character.Race; |
New lines:
1 | var race = character.Race; |
The answer:
It doesn’t matter - what matters is to stay consistent.
If you use new lines - keep using new lines.
If you put them on the same line - Keep doing that.
In C++
it’s even used as a technique called RAII.
By using the ctor
and dtor
as scope handlers we can manage resources more easily.
A common practice is using a mutex guard alongside the brackets.
1 | void MyFunction(std::string playerName) |
Locking should be minimzed as possible so if we only lock the mPlayers
variable we should minimize the scope by introducing a block using the brackets.
Headers present ideas.
In code we have few definitions that act like headers:
1 | /* |
The class defines a Monster
which inherits the Creature
class.
The final
seals the class for overriding virtual methods.
1 | public void PerformHit(float damage, IEnumerable<IDamageBuffs> buffs) |
A function states:
void
). action
is performed.By emphasizing the headers with spaces, clear identation and proper documentation we guide the programmer more easily in our code:
1 | /// <summary> |
When the code is ordered and a consistent order exists the reader can expect the same element in the same location for every class.
What do we order in a class?
In C#
there are many elements that may exist in a class:
1 | using System; |
Different languages has different styles and each language has its own culture of arrangment.C#
Has many elements therefore it’s a good example on how we order elements inside a class.
Prefer to put on top more common methods and as we go “deeper” in a file we get more implementation details.
Prefer to group everything so it would be easier to navigate throught the class.
Prefer to hide details and make the public interface as clear as possible.
C#
allows the usage of region
text processor:
These kind of regions are helpful to hide elements and focus on what’s important right now.
A more common and trivial approach is to use seperators such as comment lines:
I’m not advocating for any approach as the usage of splitters is very subjective.
As I stated already the preference is not important as long as - you’re consistent!.
Consistency is key.
When should we break consistency?
When we want to emphasise on an idea or make it more readable.
I still struggle today with the idea of lambdas especially when different languages and IDEs prefer different styles.
What I prefer is - READABILITY.
It means that I may alter the style to make it more readable but less consistent overall.
This is a regular lambda, the common practice is to put {
in the same line:
1 | public void Main() |
This example uses many nested elements.
Here I prefered to spread the lambda over new lines to focus on the banning user code.
1 | public void Main() |
There’s another way to achieve clarity and readability and it’s by splitting implementation into different code blocks.
As stated one code block that we can use is Functions
.
By splitting lambdas and code into smaller functions we can format it more easily and not deal with information overload.
1 | public void Main() |
Integrated development environments such as ‘Visual Studio’ and tools like ‘Resharper’ automates the process of formatting.
So if you don’t use an IDE and want to auto format your code it’s recommend to use one.
Of course there are CLI tools as well, some examples:
clang-format
for C++. black
for Python.dotnet format
for C#.Consistency
and Readablity
are important characteristics for code as it decreases the time a programmer spends reading it.
The more you automate this process the better your code will look.
Thanks for reading!