Some thoughts on maintainable code

I take pleasure in writing good code – maintainable, industrial strength, and sometimes beautiful. Here are some of the considerations I make to achieve that goal.

But, first, why is maintainable code important? Maintainable code will generally live longer, be more bug resistant and scale to some degree. With ever increasing engineer attrition, it will result in shorter ramp up times for new hires.

READABILITY
Readability is the most important and biggest consideration. Readability starts with ‘naming’ method/function names, variables, constants etc meaningfully. It may seem like a quick and easy task, but, is usually quite the opposite. Names are important because they tell the story of the code. I believe, readable code requires minimal to no documentation. Similar to a good story, the challenge is in finding succinct and yet meaningful names.

UNIFORMITY
Code uniformity starts with setting up code formatting rules (not guidelines, but, rules), such as, line indentation, spacing between language constructs such as (, {, etc and keywords. It is important to develop rules for where things will be found, such as, constants. Very minute details can make or break code uniformity. For example, in a java class, if ‘this’ is explicitly used to refer to an instance of a Java class, then, it should be done consistently throughout the class. Code uniformity directly affects code readability.

MODULARITY/DRY (Do not repeat yourself)
Functions/methods are the essence of programming languages. As a rule of thumb, if the same piece of code is used more than once, then, it should be written as a function. But, often times, it is also good practice to encapsulate code in a function even if the code is used once. It mostly boils down to readability. Any code reader using a laptop will appreciate if a block of code fits the size of their screen. There are other benefits too, such as, creating units of testable code.

CLEVER
Being clever with code is achieving a desired result with fewer (or least) lines of code. But, if clever code reduces or distorts readability, it is better to refrain from being clever. Clever code can leverage good, but, rarely used features of a programming language – can act as a purveyor of knowledge.

PERFORMANCE
Performance should be the most important consideration if it is practically hindering/slowing the experience for the consumer of code or is the value proposition of a business. But, in most cases, the performance degradation that comes at the cost of code readability is negligible.

Writing a piece of code is like writing a short story in english. There are rules for writing in english, which, help ensure the writing is easy to understand and enjoyable. Well written sentences maintain tense, don’t introduce ambiguity, organize different thoughts in paragraphs etc. Maintainable code too, follows principles that help make it clear and easy to read and understand.

JavaScript – Primitive vs Reference Types

Two areas of confusion around JavaScript primitive vs reference types -
1. If every thing in JavaScript is an object
2. Passed by value vs passed by reference

1. If every thing in JavaScript is an object

This is untrue since JavaScript clearly defines the following primitive types -
1. Number
2. Boolean
3. String
The confusion arises because JavaScript allows us to call methods on primitive types. For example, these are all legal statements -

1['toString']() // outputs 1 as a String

1..toString() // outputs 1 as a String. Note: 1. means 1 followed by decimal

true.toString() // outputs true as a String

"Some Str".toString() // outputs Some Str as a String

It is important to understand how this works. The Number 1, the Boolean true and the String “Some Str” are truly primitive types by themselves, but, when a method is called on them, JavaScript creates a transient or temporary object for the primitive type and tries to call the method. For example, in the case of the Number 1, a transient object is created as follows -

new Number(1) // Transient object

It is also important to understand that the transient object is ‘transient’ and is garbage collected as soon as the method has returned.
From the explanation and example above, we can see, this object like behavior of primitive types is a feature of the language and not of the primitive types themselves.

2. Passed by value vs passed by reference
As a rule of thumb in any programming language, primitive types should be passed by value, whereas, reference types, passed by reference. In JavaScript this is true, except for Strings.
So, Number and Boolean are passed by value. Whereas, everything else, including Array and Function( represented as objects in JS) are passed by Reference. So, what is the deal with Strings? Here is an explanation –

Since a String can be of infinite size, passing it by value will be inefficient, therefore, JavaScript chooses to pass Strings by reference. The good part is, Strings in JavaScript are immutable, meaning once a String object is created it cannot be modified. There is no method available on String that allows us to modify it. For example, Strings do not provide us any such method – insertCharAt or replaceCharAt. This also means, as Javascript developers, we do not have to worry about Strings ever getting modified, even though, they are passed by reference. Also, note, although, Strings are passed by reference for efficiency, they maintain their primitive nature when we compare two Strings. Take the following for example -


"abc" === ("ab" + "c") // true, since values are compared

In short, the issue of how Strings are passed in JavaScript is really not an issue because Strings are immutable.

Follow

Get every new post delivered to your Inbox.