Decoupling Software Components with Orthogonality

As a Software Developer, you need to add a new feature into a Web App you have been working on for quite a time now. To add that one feature, at how many places will you be required to make a change?

If the answer is more than one, Orthogonality is your solution.

So what is Orthogonality?

In mathematics, Orthogonality is the relation of two lines meeting at right angles to one another. For vectors, it means that they are independent. Moving along either of the two does not change your position projected onto the other.

In computing, Orthogonality is defined as software features which are mutually exclusive to one another.

Okay, can you give me some examples?

A database layer completely independent from the user interface of a Web Application is an example of an orthogonal system.

More so, your computer monitor has orthogonal controls. You can change the brightness independently of the contrast level, and (if the monitor has one) the color balance control will be independent of both. Imagine how much more difficult it would be to adjust a monitor on which the brightness knob affected the color balance: you’d have to compensate by tweaking the color balance every time after you changed the brightness.

How is this idea helpful in software?

Orthogonality lets you make complex programs manageable. When you need to make a change in a software program, it helps you to not be forced to keep the entire program in your head, but that one module or the class where the change needs to be made. After the change is made, the rest of the program just works fine. In a purely orthogonal design, each change in the program causes no ripple effects onto the other parts.

With the localization of changes, the code is easier to understand, document and reuse thus reducing the time for other developers to be able to contribute to the project.

I have a Big Codebase, how do I identify if it’s Orthogonal?

If you have the following in your project, it is highly likely to not be Orthogonal:

  • Thousands of classes where classes do more than they are meant to and the responsibilities of a class don't have a strong justification

  • Changes in one logically separate part of the codebase breaks something elsewhere

  • Same constants defined at multiple places

  • A lot of effort is involved in order to make a small change in the codebase

  • Lots of global data

  • Coupled code - modules share a lot of information with other modules

  • Similar functions

How to make Software Modules Orthogonal?

There is no one-shot answer, but if some design practices could be followed religiously, a codebase could be make orthogonal. To start with, one needs to make sure that there is no duplication in the system, and all modules expose data no more than that is required, hence ensuring that there is strictly one authoritative source of information. One must avoid the use of global data, since their values could be changed from any part of the system, hence increasing the the cohesion among multiple modules. Also, one of the best ways to improve orthogonality is to reduce software entropy as soon as any code smell is encountered.


Naming the return parameters!

Moving to Golang after using Ruby came with a host of surprises for me and one of them was the way you could return values from the functions. Multiple return values was definitely one of those wonders but here I will talk about named return parameters for the functions -yes, there is such a thing.

In Golang, we can explicitly state the name of the return object along with its type in the following way and just have a naked return that will automatically return this named-parameter: 

In the above example, we have not just specified that the function will return an int type but also that only the variable named nextPos is going to be returned - note that any named return parameter will be initialised to its zero-value automatically. We will discuss the merits of using named returned parameters in a while but first I want to point out something that might appear confusing.

What do you reckon the above function to return? Well, the answer is 5 because as long as the actual return value is of the same type as the named-return-parameter it becomes the value of the named-return-parameter nextPos. So then what is the point of naming the return types in advance?

One of the foremost uses is to assist in readability and documentation which all developers will swear by as one of the most essential features especially in a large codebase. Also, since functions in Golang can have multiple return and defer statements, if we use named return parameters, we won't have to change the return statements everywhere.

Interestingly, GNU C++ (one of the inspirations of Golang) also has this feature and using it actually results in performance improvements, for example:

The first function causes implicit call to copy constructor of MyClass (a constructor of the form MyClass(MyClass&)') is applied to obj which is causing unnecessary overheads. The call to a copy constructor is avoided in the second case and will be particularly useful if the classes are large. More can be read on the GNU C++ docs.

One cannot not overshadow the occurrence of shadowing (pun intended :P) when talking about returning named parameters. According to Godocs -

Shadowing: the result variable has been shadowed by another variable with the same name declared in an inner scope

Shadowing can be demonstrated with a trivial example: 

To avoid buggy code, the rejection will take place in the form of the compiler throwing an error and will have to be fixed manually.

What we can take away from this is that Golang gives us features to make our code better and more efficient but using them without a deep understanding of the edge cases could lead to some head-scratching surprises!


Testing in GoLANG

Coming from a ruby background and having done a lot of TDD using the sweet RSpec framework prompted me to look out for the testing frameworks available in Go.

Go comes with a default testing library called “testing”.

First of all, we need to create a _test.go file in the same folder as the file you want to test. Both the files should also be in the same package. Inside the _test.go file, any function-name starting with Test will be tested. Such functions are expected to take a pointer to testing.T.

Here we use expected and actual values to evaluate the condition.

To run the test use the command go test in the folder where this file resides, you should see that all tests are running. On running the test we get a PASS message.

Test written in this way lacked the verbosity of typical Rspec Unit Test. To improve the situation there exist options like "Testify".

It is a assertion based testing framework. It includes packeges for:

  1. Easy assertions
  2. Mocking
  3. HTTP response trapping
  4. Testing suite interfaces and functions

The above spec demonstrate an example of assertion based test using assert package in testify.

There are other frameworks available too like "Ginkgo" which is a BDD testing framework with functionalities very similar to Rspec.

Prashant Mittal is an engineer at C42 Engineering. If you liked this post, please consider...


It's About Time

The date and time is important for an application which is used in different timezones. For example, consider what happens if a user from India enters some data with its own local timestamp at 5:30 a.m and a user from U.S.A wants to see the data. If the timezone is not changed then time which is entered is in the future for the user in U.S.A.

Before getting into actual coding to handle date and time, let us understand the time terminology:

  • UTC - The reference time.
  • Standard Time - The local time without a daylight saving time offset. For example, in India, standard time(IST) is UTC+5:00.
  • Daylight Saving Time(DST) - The local time with a daylight saving time offset. This offset is typically one hour, but not always. It is typically used in most countries away from the equator. In India, daylight saving time is UTC+05:30

Ruby provides two special Libraries to handle time and date:

  1. Time: It is usually sufficient for everyday programming needs because the class uses the time provided by the operating system. It may not be able to display dates before the year 1970 and after the year 2038 and is based on library time.
  2. Date: It consists of two classes Date and DateTime

There are many solutions to managing the timezones and one of them is to store the time in a standard format like UTC and converting it to the user's time-zone.

The code given below can display all possible date-time formats:

Praveen Shukla is an engineer at C42 Engineering. If you liked this post, please consider...


Crystal for rubyists

For last few weeks I have been exploring a relatively new language (about 2 years old) Crystal (hasn’t hit 1.0 as of today). Crystal is inspired by Ruby and it has Ruby like syntax that we all love. It is a statically typed language, so you won’t have runtime bugs since the compiler will catch type related bugs during compilation. 

Crystal is very efficient in compiling code to native code which can be distributed as binary.

Crystal has a modern standard library which has implementations of markdown and websockets baked into it. 

And while we are in introduction territory, it’s important to know that Crystal is self-hosted. That means 

The Crystal is 100% written in Crystal. 

Crystal Basics

  • Everything is a object just like Ruby.
  • There are two types of objects, Values and References.
  • Value objects includes Number, Bool, Nil , Char, Struct, Tuple and Pointer.
  • Rest all objects are References including String, Array and Hash.
  • Value objects are passed by value and Reference objects are passed by reference.

Now that we’re over with the introductions, let’s dig a little deep into language core constructs and concepts.

Global Type Inference

Crystal determines the type of objects and return types of functions using mechanism called global type inference. The process includes traversing the whole AST and assigning type to each node based on type expression it represents. 

Let’s catch up on curious case of Union Types. 

In above code snippet the type of variable name is determined by type inference. The AST node representing first conditional expression will have type of String associated with it while the AST node representing second expression will have Boolean type associated with it. The variable name hence will have a union type String | Boolean associated with it.

Let’s take another example of Union Type.

foo = ["foo", false, 1, "bar"] typeof(foo) #=> Array(String | Int32 | Bool)

In above code variable foo will have type Array(String | Int32 | Bool).

Moving on.

Method Overloading

Method overloading has three different criteria.

  • Number of arguments.
  • Types of arguments.
  • If methods accepts a block or not.

Let’s take an example of addition.

The last line in above code snippet will throw below error.

no overload matches ‘String#+’ with types Int32
Overloads are:
 — String#+(other : self)
 — String#+(char : Char)

During the compile time Crystal determines all the possible overloads and throws errors if type of arguments supplied doesn’t match the possible argument types available in overloads. 

You can also pass type of arguments in methods like this

Let’s try to fix the String and Number overloads situation.

This works perfectly fine since now we have a overload that can handle argument of type String and Number.

Moving right along!


Structs are 

  • stack allocated
  • passed by value since Struct inherits from Value.

while class is heap allocated and passed by reference since it inherits from Reference. These features makes struct more suitable for defining a type in. For example if you want to build a vehicle, the implementation would look something like this.

This is just a very brief overview of crystal. This is missing many concepts like macros, generics, pointers, slice and much more, which I’ll try to cover in next blog.

You can help

  • by contributing to crystal.
  • by funding crystal's development and help it become production ready at bountysource.

Vijay Dhama is an engineer at C42 Engineering. If you liked this post, please consider...