Avoid complex conditionals using the ternary operator

?: is a ternary operator introduced to write elegant if-else clause.

It is a concise way of writing simple conditionals. However, those should be easily understandable by any human. It should not be used to write deeply nested complex conditionals that hamper the readability.


When to use?

When you have very simple if-else that could be covered in one line and returns value.


Example:

Display text as “Weekend” if it’s a Sunday otherwise “Working day”

Another one:

Determine the restaurant to visit depending upon cash in your wallet.

When NOT to use?

As said earlier, they are used to simplify the conditional so that they add value and make code simple and elegant.

However, that does not mean you should blindly rewrite ALL if-else clause with the ternary operator. Please avoid them when expression becomes complex and difficult to understand.


Bad Example

The implementation of the fizz buzz generator.



const output = number % 3 === 0 && number % 5 === 0 ? "FizzBuzz"
 : number % 3 === 0 ? "Fizz" 
 : number % 5  === 0 ? "Buzz" 
 : number;

In my career, I have seen people writing deeply nested clauses using the ternary operator. I kept the above example to convey my thoughts.

The above snippet adds unnecessary mental mapping to remember and process each conditional and symbols ?: ?: ?: more like a machine.

Please don’t be a human code compressor.

Better alternative

Conventional if-else over ternary when a condition becomes complex.

Day by day, high-level languages are introducing more features so that developers could write more human-readable expressive code. We should keep this point in our mind and avoid a few things like writing deeply nested complex ternary conditionals. Instead, go for conventional control flow statements like if-else or if-return-early.

Thoughts mentioned in this post are based on my personal experience. It is just a guideline. IMO, we should be compassionate about our co-worker while writing the code and should avoid clever-complex clauses using ternary operators and rather should focus on elegance.

Primitive Obsession – The code smell

https://www.collinsdictionary.com/dictionary/english/primitive

Programming languages divide their types mainly into two categories.

  • Primitive types (A built-in types like string, boolean, int, decimal…)
  • Objects (class/function): User-defined types using class-based/prototype-based objects.

A primitive data type is a data type for which the programming language provides built-in support. Example: number, string, boolean, date and so on.

There are situations when developers should represent their idea/concept using user-defined types (Abstraction or encapsulation).

Whereas they choose to use primitive types (inbuilt int, string…) to represents the concept.

“Talk is cheap. Show me the code.” ― Linus Torvalds

Consider the above API for scheduling meetup.

If you observe carefully, all the parameters: topic, description, date, location id, and max participants when they stand together represent the concept/idea called meetup.

Almost all the data types are primitive types (Built-in types: string, int, DateTime and so on).

Problem?

Overutilization of these primitive types to solve a problem makes the code more verbose/procedural and logic to deal with them is scattered.

Solution:

Since all method parameter stands together to represent the concept called Meetup.

Here, we could group all these parameters together to represent the idea/concept called meetup. So, introduce an object to gather these data values.

Upon replacing data values with an object API would look like:

This is how the API should have been. However, the developer chooses to go with all built-in types (segregated). IMO, this overutilization of primitive types in almost all cases can be treated as an obsession about primitives which can be called a primitive obsession.

I have explained only one scenario and there are other scenarios too.

Test case structure

A commonly applied structure for test cases has

  • Setup: Arrange the state of the unit under test in order to run the test.
  • Execution: Act on the unit under test so that it performs the expected behavior and receive output if needed.
  • Validation: Assert/Verify the outcome of execution.
  • Cleanup: Restore unit under test to a pre-test state.

Test-driven development benefits

  • Design first: You understand requirement first via analysis, create use cases for it. Thus, the focus is on the requirement before writing the code.
  • Good enough code for now: You write sufficient code against use cases that fulfills the user requirements. You don’t write extra lines of unnecessary code.
  • Avoid rework: Due to design first approach, most of the doubts are cleared before writing code hence rework is avoided.
  • Developer confidence: Continous delivery of requirement in small cycles gives developer a confidence.
  • Regression catching.
  • Safe Refactoring: Once the code is covered by multiple tests, a developer can safely improve code structure with confidence and can focus on simple and elegant design.
  • A shared understanding of the business: Tests are the live documentation that is the communication channel between you and your future version or other developers that talks about business rules.
  • Clean code reminder: IMO, TDD always reminds you to make your code better than you found it. Of course, after covering your code with test, make it better.

Rest parameter under the hood…

You know the rest parameter (usually prefixed with ...) allows functions or methods to accept indefinite numbers of parameters.

This parameter is actually gathering the values from arguments and creates an array of values from it.

How? Let’s see with code using ES6 rest parameter and it’s corresponding transpiled version.


Simple snippet with rest parameter

First snippet: The function with Rest parameter ‘…days’

Obviously, line 2 will print an array:

[ 'Monday', 'Tuesday', 'Wednesday' ].

You wonder, How it’s an array? Let’s inspect it via transpiled version.

Below code is transpiled using BABEL.


Transpiled version:

Transpiled version of first code snippet. The days variable is initialised as an array and copies element from argument object.

Under the hood, the rest parameters are actually derived from arguments object of called function, `print`. Please notice carefully variable days on line# 5.

It’s value is set to an array whose length is equal to number of arguments passed.

Later, elements from arguments are copied to variable days (element by element from line# 8 to 10).


Another Example

Second snippet

In the second code snippet, please note there is a parameter multiplier apart from rest parameter ...numbers. Hence, copying will not begin from first element instead it started from second element till last one.

See transpiled version for more details.


Transpiled version

Transpiled version of second snippet. Please note argument objects first element is skipped.

const does not mean value it holds is immutable

I see many JavaScript developers have started replacing var with const just because some linter forces them to do so.

const in JavaScript is not only blocked scope but also const variable cannot be reassigned with new content.

It creates readonly reference. It means you cannot reassign value to the const variable. It does not guarantees immutability of the content that it holds.


const person = { name: 'John Doe', age: 33};
person = { name: 'John'} 
// Above line will throw Uncaught TypeError: 
// Assignment to constant variable.

// However, you can change the content of object
// that is referenced by person variable.
person.age = 40;  

So, If you really want to mark your object as immutable then use some other API’s like `Object.freeze`.

There are specific use cases about const variable. Make sure you are intentionally marking some variable as const and not because some linter has that rule.


Fizz-Buzz generator using test driven development

Photo by Kevin Grieve on Unsplash

This is a Fizz Buzz generator using test driven development.

Problem statement:

The Fizz buzz generator is a simple program, it’s method say generate accepts the numeric input and produces the output string based on the rules and input number.

Rules

The generate method returns the string

  • FizzBuzz when input parameter is divisible by 3 and 5.
  • Fizz when input parameter is divisible by 3.
  • Buzz when input parameter is divisible by 5.
  • String representation of given number when input parameter neither divisible by 3 or 5.

It is clear that there are four use cases to implement

  • FizzBuzz As a fizz buzz generator, I should be able to generate a string FizzBuzz for a given input number when the number is divisible by 3 and 5.
  • Fizz As a fizz buzz generator, I should be able to generate a string Fizz for a given input number when the number is divisible by 3.
  • Buzz As a fizz buzz generator, I should be able to generate a string Buzz for a given input number when the number is divisible by 5.
  • Number (converted to stringAs a fizz buzz generator, I should be able to generate a string format of input number for a given input number when number is neither divisible by 3 or 5.

Visit the github repository fizz-buzz-generator for TDD implementation.

Don’t forget to go through commit by commit to witness the test driven development journey.


Naming query variables

After working with the different framework and libraries like Laravel, PHP, ASP.NET MVC, ExpressJS and other technologies, I realized that I should write about naming query variables. Perhaps, variable that holds the query and executes it later (Deferred execution).

Sometimes, when developers of any language or framework choose to write the query that gets data using deferred execution, they don’t include the word “query” in the variable name.

Due to exclusion of word `query` in such a variable name, the maintenance developer presumes that the query will be executed immediately. This assumption leads them to introduce bugs in their code.

Please ensure to include the word `query` in the variable name so that it conveys the reader that it is NOT to be executed immediately.

As always, we have to provide meaningful and intuitive names to query variables. See some of the examples below:

Naming query variable examples

  • puneCustomersQuery: When I want to fetch the customers in Pune locations.
  • allPackagesQuery: When I want to fetch all the packages.
  • evenNumberQuery When I want to fetch even numbers from a given data source.
  • damagedPackagesQuery: When I want to fetch packages that are marked as damaged.
  • customersByCityQuery: When I want to fetch customers that are grouped by their city.
  • customerNameQuery: When I want to fetch customer names from a given data source.
  • soldOutProductsQuery: When you are fetching the sold-out products.

Be declarative wherever possible

Imperative programming focuses on describing how a program operates. Take an example of the below function “ isPresent “.

First example: Imperative way, Look implementation of isPresent function.

Of course, it searches a number (search term) in the numbers array and replies with true or false.

If you observe carefully, it focuses on how the number is searched.

It iterates each number one by one in an array of numbers and checks if criteria are fulfilled (HOW part: for/if). Eventually, it tells you if the number is present/not in the array.

Declarative programming, on the other hand, expresses the logic of a computation without describing its control flow.

Let’s look at the declarative way of searching a number in an array.

Declarative way: Any function from LINQ.

In the above code, the method Any (present on array data type), is an extension method provided by LINQ.

It determines whether any element of a sequence contains a given number. It does not tell you how it is searched. That part is hidden behind API: Any.

The benefit of a declarative approach over the imperative approach is improved readability of code.

Another example:

Second example: Imperative way. See containsAllMen function: focuses on describing how a program operates (Control flows are involved: iterate and if)

This function “ containsAllMen “ tells you how searching is implemented and control flow like if clause determine the condition.

Now see the declarative way, it is using lodash’s every to determine the condition.

The declarative way: Using every function from lodash.

This technique is language agnostic.

You search libraries that do such work for you instead of implementing it by yourself.