AK

Configuration Management

Sep 25 2020
One thing I am learning as a developer working on enterprise software is the importance of a configuration management system. When you have a software system that's installed on-premises for each customer, that is configured and customized separately, managing configuration becomes a challenge. You can't just use environment variables or simple files to store config. You need to have a good strategy to deal with the configuration.  

When code relies on values that may change after the application has gone live, keep those values external to the app. When your application will run in different environments, and potentially for different customers, keep the environment- and customer-specific values outside the app. 

Common things you will probably want to put in configuration data include: 
  • Credentials for external services (database, third party APIs, and so on)
  • Logging levels and destinations
  • Port, IP address, machine, and cluster names the app uses
  • Environment-specific validation parameters
  • Externally set parameters, such as tax rates
  • Site-specific formatting details
  • License keys
Basically, look for anything that you know will have to change that you can express outside your main body of code, and slap it into some configuration bucket. In this way, you’re parameterizing your application; the code adapts to the places it runs. 

Parameterize Your App Using External Configuration.
If the configuration is simple, you can store it in JSON or XML files. For more complicated ones, you might need an application that stores the config in the database. When your application starts, it reads this configuration as a data structure in-memory and uses throughout the life of the application. If you change the configuration, the application needs to restart to fetch the new values. This is how we manage configuration at CityView.

Though this is a common approach to managing configuration, the pragmatic programmers recommend against it. Instead, their suggestion is to wrap the configuration information behind a thin API. This decouples your code from the details of the representation of configuration.

Configuration-as-a-Service

In this approach, the config is still external to the application, but instead of storing in a file or database, it's stored behind a service API. This has following benefits:
  • Changing configuration doesn't require the application to restart. Then next API call will fetch the latest configuration value. 
  • Multiple applications can share configuration, with correct authentication and authorization. 
The first benefit is important. Modern applications are expected to be up and running all the time. You shouldn't have to stop and start the whole app to change a single config value. Using config-as-a-service, the application always fetches the latest value from the configuration, dynamically. When config changes, there's no need to rebuild the code. 

However, I am not totally sold on this benefit. If I expose my configuration as a service behind an API, my application becomes chatty, making a lot of HTTP calls with the API, which would have been available in-memory if they were loaded as a data structure when the application started. An HTTP call is always going to be slower than an in-memory call. 

You have to use your best judgement and choose the strategy that suits the needs of the users and application and what's important to you. If the config is changing all the time and you don't want to restart app each and every time, use config-as-a-service. If the config is done initially, and changes rarely, use a static configuration which gets loaded when the application boots up.

Learning PowerShell

Aug 28 2020
For a long time, I avoided learning powershell, instead relying on the good old command prompt and/or using the bash emulators like Cmder or ConEmu. I thought PowerShell was a clunky shell where you have to type longer commands with PascalCases for the same tasks that you could do with two characters in bash. For example, cd in bash vs. Set-Location in PowerShell.

I was sooooo wrong.

Couple of days ago, I stumbled across Jeffrey Snover's (inventor and the architect of PowerShell) 2018 talk on 'PowerShell: State of the Art' at the PowerShell conference, and I was really fascinated by the philosophy behind PowerShell and all the things that it allows you to do as a system administrator.

Most importantly, I understood why PowerShell is so different than a bash shell. As Jeffrey Snover expresses so eloquently, Unix/Linux based systems primarily operate on text. That's why you have commands like awk, sed, grep, etc. that make text manipulation so easy. In contrast, Windows' primary focus is on GUI-based applications, which communicate using APIs and objects, not text. Hence you need a different way of thinking if you are managing a Windows machine, compared to a Linux machine.

PowerShell allows you to do just that.

After listening to a few more talks from Jeffrey Snover on YouTube and on Hanselminutes, I was really hooked and realized that learning PowerShell is the best investment I can make right now that will pay huge returns over a long term. Microsoft is embracing the open source, .NET 5 is coming soon in a few months, and IT infrastructure is moving more and more towards Azure. PowerShell is one piece of glue that holds all these pieces together. As a software developer interested in the DevOps, PowerShell is a tool that I should have.

One thing that I didn't used to like about PowerShell is the UI it came with. For some reason, it wasn't aesthetically pleasing for me, and I didn't see myself writing scripts in that editor environment. However, with the new Windows Terminal on a Dracula theme, with the fun Cascadia Code font, I've got everything I need from a terminal. This is how my terminal looks now, and I just love it.
Terminal
It can be frustrating to learn PowerShell in the beginning, especially if you are coming from a Unix/Linux background. If you are used to typing cd, ls, mv, cp, etc. on a bash, you will find Set-Location, Get-ChildItem, Move-Item, Copy-Item too verbose. No worries. All your basic bash and cmd incantations work just fine on PowerShell. It has aliases for the common commands to make you feel comfortable when beginning to learn PowerShell.

It's only when you start writing bigger scripts for automation you start realizing the true power of the verbosity of the PowerShell cmdlets. It's much easier to read Get-Job and understand what the script is doing, compared to reading gjb and having to search the manual to find what it's doing. It helps to write maintainable scripts.

Last night, I got Bruce Payette's (co-author of PowerShell) book, "Windows PowerShell in Action" to get a more formal training in PowerShell. The more I get familiar with PowerShell, the more I keep amazed with all the things that it can do. It's like having really sharp knives. You can do a lot of useful things, but you can also cut yourself if you are not careful.
PowerShell in Action

I also came across the MSDN course on "Getting Started on PowerShell", offered by Jeffrey Snover himself, along with Jason Helmick. It's a really fun course, something that I wouldn't have expected from an MSDN course. Really enjoying it.
MSDN
Learn PowerShell. It's worth the effort. 

Event Pattern in .NET

Aug 24 2020
First, define the structure of the data that you want to send when the event happens. 
public class ThresholdReachedEventArgs : EventArgs
{
    public int Threshold { get; set; }
    public DateTime TimeReached { get; set; }
}
Then, define the Publisher, i.e. the class that wants to raise an event
public class Counter
{
    // 1. Define an event
    public event EventHandler<ThresholdReachedEventArgs> ThresholdReached;

    // 2. Do something that raises the event, and pass the EventArgs custom data 
    public void DoSomething()
    {
        ThresholdReachedEventArgs e = new ThresholdReachedEventArgs
        {
            Threshold = 10,
            TimeReached = DateTime.Now
        };
        
        // 3. Raise the actual event
        ThresholdReached?.Invoke(this, e);
    }
}
Finally, create one or many subscribers. Classes that want to listen to an event raised by the Publisher.
class Program
{
    static void Main(string[] args)
    {
        // 1. Create an instance of the publisher, which you want to listen to
        Counter counter = new Counter();

        // 2. Attach an event handler on the publisher
        counter.ThresholdReached += OnThresholdReached;
        
        // 3. Do something that will raise the event. Now you are ready to listen to the event. 
        counter.DoSomething();
    }

    // 4. Handle the event which is raised by publisher
    static void OnThresholdReached(object sender, ThresholdReachedEventArgs e)
    {
        Console.WriteLine($"Reached Threshold {e.Threshold} at {e.TimeReached.ToString()}");
        Console.ReadLine();
    }
}

Protect Your Users

Aug 19 2020
As software developers, we have more power than we realize. Our programs directly affect people and influence their behaviour. It's a good idea to take a break from coding from time to time, and ask yourself this question.

Would I use this product myself?

Or, its corollaries:
  • Do I want my personal and sensitive info shared? 
  • Do I want my data be given to big tech companies, sold to the highest bidders? 
  • Would I be happy to be driven by this autonomous vehicle? 
  • Am I comfortable doing this? 
If the answer is no, take action. Make change in the software to protect your users.

At CityView, I am building an application that allows city inspectors to conduct virtual video inspections with the contractors, without having to drive all the way to the location. The inspector, from his home or office can talk face-to-face with the contractor, just using the browser, without having to install Skype, Zoom, or WhatsApp. It's a really useful application, and I am really having so much fun programming it, using WebRTC and Twilio Programmable Video.

The latest feature I implemented allows the inspector to record the entire virtual meeting just by clicking a button. The easier way to implement this recording feature would have been just to use a third-party library, or use a video framework from a big Silicon Valley company, record the video, and store the video on the cloud, which is just someone else's computer. I would have finished in a couple of hours and life would have been great.

Except, when it came time to testing the feature, I was hesitant. I faced the phone camera away from me, outside the window to not record myself or my personal space. I didn't even turn on the webcam on my desktop. I didn't want my video to get uploaded to cloud, no matter how safe and password protected it was. 

Which bring us back to the question in the beginning. If I am not willing to use this feature, how can I expect the poor inspectors and contractors to use it, record their homes and offices, and trust that the app is not selling the recording to the highest advertisers online, or storing it in an insecure way, vulnerable to hacking, or exposing their private lives to the world?

Once that realization set in, and I got over the shame caused by the question, I redesigned the complete recordings architecture, and re-implemented the entire workflow. Now, the entire recording is captured and stored on the inspector's computer, safe in the city's servers. Their IT staff knows which physical machine it's on, and delete it permanently if not needed. It's not getting uploaded to a cloud server farm in somewhere far away, or sitting on a cheap laptop waiting to get hacked; but it's on their machine, in their hands, and they take the responsibility for it. The contractors can ask the city to delete the recording, if it contains any sensitive information, knowing that it will be done according to the data privacy act.

Implementing the second design was much harder than the first one. I had to think hard about it, use the native apis provided by the browsers, worry about synchronizing the audio and video streams of multiple users at the same time and storing them on the inspector's machine. The design became more complex, and the code size increased by a factor of five. However, the assurance I had when testing the video was priceless. I didn't hesitate while recording, knowing that the video is going to be stored safely on my computer, and I can delete it whenever I want.

As software developers, we are literally building the future. Each line of code we write can have massive impact, both for good and bad. Given that responsibility, we should think about the long term effects of the code we are writing and take responsibility and ownership for it.

Here is Joel Spolsky, founder of Fog Creek, creator of Stack Overflow and Trello, and a very influential programmer that I admire and respect so much talking on this topic.

Understanding Code

Aug 08 2020
When you are programming, you can have two types of understanding about what the code is doing. The first is the understanding in your head. This is fragile and temporary, residing in your short-term memory. You read code, you understand, but you forget about it a few days later. When you come back to the same code after some time, you have to again make an effort to understand the code.

The second type is the long term understanding, and it's not in your head. You persist the first type of understanding by moving it from your head to the codebase itself. By doing this, the code tells you what it's doing, and you don't have to figure it out again.

The way you do this is by extracting that piece of code into a new function and give it an intention revealing name. A name that tells you what it's doing. You can always go to that function to see how it's doing it, but you don't have to. You just abstracted that code to something simpler. The next time you are reading the code, you just need to glance at the name to understand what it's doing. 

Put everything you should remember back into the code, so you don't have to remember it. 
For example, consider this piece of code from Martin Fowler's Refactoring. The code on the left does everything in a single method. As you can see, it's complicated, and needs comments in some places to explain what it's doing. The code on the right does exactly the same thing, but has well-named functions abstracting the tasks they are doing. It also needs fewer comments to explain its purpose.
Refactor
Usually, after you move your understanding of the program into the code itself, the code becomes clearer to read and easy to understand and hence to modify. That in turn leads to deeper understanding and makes way for better refactoring to improve the structure and performance.

Bugs = Mistakes

Aug 07 2020
Ever since Ad. Grace Murray Hopper found the first computer bug in the Mark ll computer's log book, programmers have been calling abnormal software behavior as bugs.
first_bug
As long as we call our mistakes as bugs, it may give us the comforting feeling that these bugs just crawled spontaneously into our programs. However, that only means we take no responsibility whatsoever for our mistakes that caused these bugs. 

It's time we stop sugar-coating our mistakes by calling them bugs, and call them by what they are. Just mistakes. 

What makes a URL?

Jul 16 2020
<scheme>://<username>:<password>@<host>:<port>/<path>?<query>#<fragment>
scheme
  • http, ftp, etc.
  • separated from the rest of the url by :
username and password
  • common in ftp, not so much in http
host
  • can be a domain name or an IP address
  • identifies the server machine we're trying to access
port
  • tells us what network port a particular application on the machine we're connecting to is listening on. 
  • for http, the default port assumed is 80, for https it is 443.
path
  • separated from the url components by /
  • tells us where on the server machine a resource lives. 
query
  • preferred way to send some parameters to the server
  • key=value pairs, separated from the rest of the url by ?
  • separated from each other by &
fragment
  • usually used to link to a particular section of an html document
  • separated from the rest of the url with a #
For example,
https://www.akshaykhot.com/some/crazy/path.html?param1=foo&param2=bar
Special Characters:
  • characters that have special meaning within a url are known as reserved characters, 
  • ; / ? : @ & = + $ ,
  • If a url is likely to contain one of these characters, it should be escaped before being included in the url. 
  • To url encode/escape a character we simply append its ascii hex value to the % character. 
  • url encoding of " " is %20
  • a url should always be in its encoded form. 
  • each part of the url must be encoded separately
  • don't encode a completely constructed url
absolute vs relative urls
  • if a url contains a scheme, e.g. http then it is an absolute url.
  • relative url is always interpreted relative to another url, known as a base url.

Closure in C#

Jul 15 2020
A lambda expression can reference the local variables of the method in which it is defined. 
void DoStuff() 
{
  int factor = 2;
  Func<int, int> multiplier = x => x * factor;
}
In the above example, the outer variable factor is captured by the lambda multiplier.

A lambda expression that captures variables is called a closure.

An interesting fact about the closures is that the captured variables are evaluated when the delegate is actually invoked, not when the variables are captured.

For example, this code prints 333 to the console, instead of 012.
Action[] actions = new Action[3];

for (int i = 0; i < 3; i++)
{
    actions[i] = () => Console.WriteLine(i);
}

foreach (var action in actions)
{
    action();
}
Every time we create the new Action in the first for loop, it captures the same variable i.

However, it's only evaluated when when we actually invoke each action delegate. At that point, the value of the i is 3, as that was the final value that forced the control out of the loop. Hence it prints 3 three times.  

The above code can be re-written as follows, for a better understanding. 
Action[] actions = new Action[3];

int i = 0;
actions[0] = () => Console.Write(i);

i = 1;
actions[1] = () => Console.Write(i);

i = 2;
actions[2] = () => Console.Write(i);

i = 3;
foreach (var action in actions)
{
    action(); // 333
}




If we want the closure to print each value of i, we need to store it in a temporary variable. This variable will get created every time the loop runs, which forces the closure to capture the latest value of the i. 
Action[] actions = new Action[3];

for (int i = 0; i < 3; i++)
{
    int scoped = i;
    actions[i] = () => Console.WriteLine(scoped);
}

foreach (var action in actions)
{
    action();
}

Go Pointers!!

Jun 20 2020
One of big myths in software industry was perpetuated by Joel Spolsky in his 2006 classic The Guerilla Guide to Interviewing. I love and respect Joel, and fully agree with the article, except the following paragraph. 

I’ve come to realize that understanding pointers in C is not a skill, it’s an aptitude.

In first year computer science classes, there are always about 200 kids at the beginning of the semester, all of whom wrote complex adventure games in BASIC for their PCs when they were 4 years old. They are having a good ol’ time learning C or Pascal in college, until one day the professor introduces pointers, and suddenly, they don’t get it. They just don’t understand anything any more. 90% of the class goes off and becomes Political Science majors, then they tell their friends that there weren’t enough good looking members of the appropriate sex in their CompSci classes, that’s why they switched.

For some reason most people seem to be born without the part of the brain that understands pointers. Pointers require a complex form of doubly-indirected thinking that some people just can’t do, and it’s pretty crucial to good programming. A lot of the “script jocks” who started programming by copying JavaScript snippets into their web pages and went on to learn Perl never learned about pointers, and they can never quite produce code of the quality you need.
For a long time, I believed this. Whenever I tried learning pointers in C, I'd struggle for a while, remember the above words and finally give up thinking pointers are not just not my cup of tea.

Then I started learning Go

One of the things that make Go syntax beautiful is how variables are declared. In most C-based languages, you write the type of the variable first, then the name of the variable. When reading a sentence, you have to read it from right to left. For example,
int x, y;     // x and y are integers
int *p;       // p is a pointer to an integer
However, in Go, the name comes first, followed by a type. So you read it from left to right. For example,
var x, y int;    // variables x and y are integers 
var p *int;      // variable p is a pointer to an integer
That brings me back to the subject of pointers and why I don't agree with the above paragraph, especially the line understanding pointers in C is not a skill, it’s an aptitude

When you are learning a new concept, especially a hard one like pointers, it matters a lot how it's being presented to you. When the concept doesn't make sense at first, it's easy to blame yourself and give up, rather than try to find a new teacher, tackling it from another angle, or learn it using a different approach. 

That's what happened with me when learning pointers in C. Often I'd start on solid grounds, understanding what is a pointer, and how it points to another object in memory, by containing the actual memory address of the location where that object resides. The trouble came when de-referencing that pointer to get the underlying value of that object. I'd always get confused between the meaning of * of de-reference and the * of declaration. 

In C, you'd do this:
int x, y;
int *p;
p = &x        // so far so good.
y = *p        // ???
In Go, you do it as shown below. Notice the second line, where we are defining p (not *p) as a pointer to an integer. This is not confusing (for me, at least) as it looks different from the pointer declaration. There's a clear distinction between a pointer and a de-reference from a pointer. 
var x, y int
var p *int
p = &x
y = *p       // de-reference p to get the value at the memory address it's pointing to
Agreed, you can do this in C:
int* p;
But this is not the same: 
int* p, q    // p is a pointer to an int, q is an int
In Go, this is how you declare two pointer to integers:
var p, q *int 
It was not until I started learning Go, that I finally understood how pointers work. That opened new doors into how computer memory works, why strings are immutable in C#, the difference between Value Types and Reference Types in C#, and much more, which would have been next to impossible without learning pointers.

So if you are a new developer, and struggling with pointers in C, I'd recommend learn them in Go first. Once you understand the basic idea, you can go back to C and the pointers start to make sense. But don't think, for a moment, that you are born without the part of the brain that understands pointers, just because Joel said so. 

How Open Source Started

Jun 11 2020
In 1974, Dennis Ritchie and Ken Thomson published the first paper on Unix. 

After the paper, research labs and universities wanted to try out Unix. 

At&T was forbidden from entering the computer business, under a 1958 consent decree in settlement of an antitrust case. 

Hence, Unix could not be turned into a product. 

Bell Labs was required to license its non-telephone technology to anyone who asked. 

Ken Thompson quietly began answering requests by shipping out tapes and disk packs - with a not signed "love, ken".

Thus began UNIX. 

From: The Art of Unix Programming

On Programming

Jun 01 2020
I started reading the Mythical Man-Month by Fred Brooks this morning, and the first chapter expresses beautifully why programming is an art that provides so much joy to a programmer, if done right. 

Just reading the chapter made me so happy. It captures my exact feelings towards programming and software development in general, in beautiful prose that just flows. Here it is, in words from Fred Brooks,  

THE JOYS OF THE CRAFT

Why is programming fun? What delights may its practitioner expect as his reward?

First is the sheer joy of making things. As the child delights in his mud pie, so the adult enjoys building things, especially things of his own design. I think this delight must be an image of God's delight in making things, a delight shown in the distinctness and newness of each leaf and each snowflake.

Second is the pleasure of making things that are useful to other people. Deep within, we want others to use our work and to find it helpful. In this respect the programming system is not essentially different from the child's first clay pencil holder "for Daddy's office."

Third is the fascination of fashioning complex puzzle-like objects of interlocking moving parts and watching them work in subtle cycles, playing out the consequences of principles built in from the beginning. The programmed computer has all the fascination of the pinball machine or the jukebox mechanism, carried to the ultimate.

Fourth is the joy of always learning, which springs from the nonrepeating nature of the task. In one way or another the problem is ever new, and its solver learns something: sometimes practical, sometimes theoretical, and sometimes both.

Finally, there is the delight of working in such a tractable medium. The programmer, like the poet, works only slightly removed from pure thought-stuff. He builds his castles in the air, from air, creating by exertion of the imagination. Few media of creation are so flexible, so easy to polish and rework, so readily capable of realizing grand conceptual structures. (As we shall see later, this very tractability has its own problems.)

Yet the program construct, unlike the poet's words, is real in the sense that it moves and works, producing visible outputs separate from the construct itself. It prints results, draws pictures, produces sounds, moves arms. The magic of myth and legend has come true in our time. One types the correct incantation on a keyboard, and a display screen comes to life, showing things that never were nor could be.

Programming then is fun because it gratifies creative longings built deep within us and delights sensibilities we have in common with all men.

Reclaiming Memory

May 15 2020
In programming, garbage collection refers to the process of programmatically cleaning up the memory allocated to objects that is not correctly in use.

For a long time, I thought that the variables defined in a block or a function are garbage collected when the program control reaches the end of the block, or when that function returns. I was surprised to learn that it's not the case, while having a fresh look at the pointers in Go.

A variable is garbage collected only when no path/reference to that variable exists from other members of the program, i.e. it can no longer affect the rest of the program.

Because the lifetime of a variable is determined only by whether or not it is reachable, a local variable may continue to exist even after its enclosing function has returned. A simple example demonstrates this.
var global *int
func f() {
    var x int
    x = 1
    global = &x
}
Here, x is not garbage collected when the function f() returns. The reason is, it's still reachable from the variable global, which is a pointer to an int, or x. As global has a reference on it, the garbage collector knows not to clean it, as it will break global, and it's allocated on a heap, not on stack. 
func g() {
    y := new(int)
    *y = 1
}
In contrast, when the function g() returns, the variable *y becomes unreachable and can be garbage collected, as no other variable is holding a reference to it. The compiler allocates *y on the stack. 

Why does that matter?

In a garbage collected language, such as C# or Go, you may wonder why knowing when a variable is garbage collected is important while programming, when you have so many other things to keep in your head at the same time.

Well, though I don't need to explicitly allocate and free memory, as the GC is taking care of that, but to write efficient programs, I still need to be aware of the lifetime of the variables.

For example, keeping unnecessary pointers to short-lived large objects, especially global variables, I am preventing the garbage collector from cleaning up these objects, which are taking up space, either in my RAM, or on L1 or L2 cache memory. It might not matter when we have gigs of free RAM nowadays, but it does matter when programming for embedded devices where each and every byte of memory is scarce.

Now that I think of it, garbage collection seems like a wrong choice of words for such valuable piece of data as RAM. I think reclaiming memory expresses the intent better, than collecting garbage. What do you think?

Naming in Go

May 14 2020
Go takes a radically different approach to defining the visibility of members.

There is no "public" or "private" label for items. The case of the initial letter of the identifier determines the visibility of that item.

If the initial character is an upper case letter, the identifier is exported (public); otherwise it is not. 

  • upper case initial letter: Name is visible to clients of package
  • otherwise: name (or _Name) is not visible to clients of package
This rule applies to variables, types, functions, methods, constants, fields. That's all there is to it. 

There's also no method overloading. For a given type, there's only one method with that name. 

This results in clarity and readable programs. The code itself expresses the programmer's intent. 

I love Go. 

Learning Go

May 13 2020
While learning about Docker, I kept hearing about the Go programming language, and why it's so awesome, fast, fun, and productive, again and again. So finally, as my bedtime read, I started browsing through Brian Kernighan's book, The Go Programming Language.

I have to say that I am thoroughly impressed with both the language and the book. In contrast to other programming books, it doesn't introduce you to the syntax and the basic concepts such as loops, conditions, etc. right from the first chapter. Instead, it takes you through a series of small to medium sized, but very real and powerful programs, to give a feel for the language. Instead of spending few days immersing into the basic syntax of the language and learning the beginner topics, the reader can decide if they do want to program in this language, and if they do want to keep reading. I think it's similar to showing a teaser for a movie.
gopher
For me, it was a great, tasty teaser for the language, which does fit my brain nicely. I was hooked after reading the first few pages of the book. The syntax seemed too enticing to lay in my bed and just keep reading the examples. 

So, I turned on my PC at 11 pm, downloaded a fresh install of Go, and started programming. In a couple of hours, I had written programs from a simple 'Hello, world' to a full-fledged web server, including a concurrent URL processor. 

Go has its unique idioms and style. If only you can liberate yourself from your current programming language and look at Go with a fresh set of eyes and a clear mind, you'll find it easier to understand and appreciate the Go's elegance. 

After the head-first dive into the deep end of the sparkling blue ocean that is Go programming language, I am now looking forward to the second chapter of the book, which gives a much formal introduction to the language. 

Software Design

Apr 29 2020
You have to "solve" the problem once in order to clearly define it and then solve it again create a solution that works.   

The finished software design should look well organized and clean, but the process used to develop the design isn't nearly as tidy as the end result. Design is a sloppy process, you take many false steps, and make a lot of mistakes while designing software. 

The purpose of design is to identify the mistakes early. It's cheaper to find mistakes during design phase and correct them, than having to correct implemented code. 

At the same time, until your software fails in production, you don't really know the true requirements. So it's a delicate balance of upfront design vs. on-demand design. 

An ideal program runs instantly, takes zero storage, use zero network bandwidth, doesn't have any errors, and costs nothing. In the real world, there are trade-offs. A good design should try to find a balance among various competing factors. 

A good design emerges out of the iterative process of thinking about the program, writing the program, and rewriting the program. 

Query Method

Jan 30 2020
Problem
  • You are trying to evaluate/execute a complicated boolean expression, involving multiple steps
Solution
  • Provide a method that returns a boolean by evaluating the above complicated expression. 
  • Give it an intention-revealing name, usually in the form of a question. e.g. IsDate(), HasMarkups(), etc. 
  • If the functionality it's trying to execute is a concern of the object itself, make it a property/method on the object itself, rather than the caller code. 
Benefits
  • Simplify complicated boolean tests. Understanding complicated boolean tests in detail is rarely necessary for understanding program flow. 
  • Putting such a test into a function makes the code more readable because
    • the details of the test are out of the way and 
    • a descriptive function name summarizes the purpose of the test. 
  • Both the main flow of the code and the test itself become clearer. 
Trade-off
  • If the test is very simple, keep it inline. 
Before
public void Process(Payment payment)
{
    if (payment.amount > 0 && payment.status != Status.Cancelled && payment.isDue)
    {
        // Process the payment
    }
}
After 
  1. Create a new method in the caller
public void Process(Payment payment)
{
    if (IsValid(payment))
    {
        // Process the payment
    }
}

public bool IsValid(Payment payment)
{
    bool isValid = payment.amount > 0 && payment.status != Status.Cancelled && payment.isDue;
    return isValid;
}
As validation seems more of a concern on the Payment, add a property IsValid on the payment. This is much more readable and flexible, in my opinion. 
public void Process(Payment payment)
{
    if (payment.IsValid)
    {
        // Process the payment
    }
}

class Payment
{
    public bool IsValid(Payment payment)
    {
        get
        {
            return payment.amount > 0 && payment.status != Status.Cancelled && payment.isDue;
        }
    }
}

Rethinking Agile

Jan 20 2020
Agile is the most common software development methodology used when building software. Ideally, it means that you don't do any big, upfront design. Instead, you work in sprints, and evolve your design as your understanding of the project grows. Design is part of the programming.

This sounds nice on paper, but in reality it's often a disaster. I have worked on some projects where I didn't do any design and planning before starting, and jumped straight into the code. The final design ended up being the sum of random decisions made while in the middle of programming, which don't make any sense when viewed as a whole system. It ended up in rigid code, which is hard to change and evolve, which is the essence of agile and extreme programming. As time passed, more bugs crept in, and they were almost always hard to find and fix.

In contrast, there were some projects where I did plan the design of the software I was building, in turn writing a spec, and they almost always turned out well. Planning in advance helps figuring out the big issues in advance and make changes if needed. Changes are always easy while designing, compared to coding.

Now, it's true that I can't think of all the issues that might come up while building software. But as Joel says, the goal of planning and specifying the software is not to find out all the details in advance, but to find out as many as possible to reduce the surprises when programming. 

The next question is how to plan and design software before starting coding. One way I have found really useful is to draw UML diagrams. Now, they might have been out of fashion for quite a while now, but that doesn't mean that they don't have any value. I personally, find them very useful. The important thing is to keep them simple. Draw only important classes, not all, and list only the important attributes and methods on each, and so on. 

The best thing about UML diagrams is that they allow me to capture the design. It's very hard to grasp the whole design of the system based on just looking at the code. If I come back to code I wrote last year, it might take me a day or two to find out the core design behind the system, but a UML diagram conveys that in minutes. And I can always update them, as the design changes. 

So, to summarize, I find it useful to have both waterfall and agile mindsets when developing software. Start with a design, and revise it as I am writing code. Ultimately, that results in software that solves real problems. 

Base64 Encoding

Jan 14 2020
While programming, it's easy to get by with a superficial understanding of lot of things and fooling yourself by thinking that you are programming when you are blindly copy+pasting Stack Overflow answers and/or using the framework libraries.

I am guilty of this, too. There are many times during the day when I will come across a new concept when programming, that's what makes programming fun. At these moments, the temptation is to just use that nice framework method to get the job done, or just copy the answer from a Stack Overflow question. But that robs you from using a better implementation or discovering bugs, if there are any, from that SO answer. It also doesn't build your understanding of that concept. Next time you run into similar problem, you have to repeat the process.

Base64 encoding was one of these topics that was bugging me for a while. I often came across Base64 data, such as Base64 encoded image, or URL, and had no idea whatsoever that meant, or why it was even used. Finally, I decided to do some research to fill that knowledge gap. Here's a brief summary of what/why/how of Base64 encoding.

Basically, Base64 encoding takes binary data and converts it into text, specifically ASCII text. The resulting text contains only letters from A-Z, a-z, numbers from 0-9, and the symbols '+' and '/'. As there are 26 letters in the alphabet, we have 26 + 26 + 10 + 2 = 64 characters, hence the name Base64.   

As there are only 64 characters available to encode into, we can represent them using only 6 bits, because 2^6 = 64. Every Base64 digit represents 6 bits of data. Now, there are 8 bits in a byte, and the closest common multiple of 8 and 6 is 24. So 24 bits, or 3 bytes can be represented using 4 6-bit Base64 digits. For example, the text
My name is Akshay
can be encoded as a Base64 string 
TXkgbmFtZSBpcyBBa3NoYXk=
The next question is why do we do this encoding. The most obvious use case is when we have to transmit some binary data over the network that's supposed to handle text. Base64 can also be used for passing data in URLs when that data includes non-url friendly characters.

That is all well and good, but how do you actually convert data to Base64? Here's a simple algorithm that converts some text into Base64:
  1. Convert the text to its binary representation. 
  2. Divide the bits into groups of 6 bits each.
  3. Convert each group to a decimal number from 0-63. It cannot be greater than 64 as there are only 6 bits in each group. 
  4. Convert this decimal number to the equivalent Base64 character using the Base 64 alphabet. 
That's it. You have a Base64 encoded string. If there're insufficient bits in the final group, you can use '=' or '==' as padding. 

Here's an example that converts my name "Akshay" to its Base64 equivalent string. 

  • Convert "Akshay" to binary, which looks like:
01000001 01101011 01110011 01101000 01100001 01111001
  • Divide the bits into groups of 6 bits in a group, instead of of 8 bits
010000 010110 101101 110011 011010 000110 000101 111001
  • Convert each group to a decimal number
16 22 45 51 26 6 5 57
  • Now use the above Base 64 alphabet to convert each group to its Base 64 representation
QWtzaGF5
Here is a program in C# that takes some text as input and converts it into Base-64 encoded string.
public static string ToBase64(string value)
{
    byte[] bytes = Encoding.ASCII.GetBytes(value);

    string base64 = Convert.ToBase64String(bytes);

    return base64;
}
For more information, see the RFC for Base64 which describes the encoding in detail. Also, next time you meet me, don't hesitate to call me "QWtzaGF5", instead of Akshay :)

Write a Spec

Nov 09 2019
I had an interesting experience at work this evening. It was late afternoon, and I was tasked with a somewhat important feature, the details of which were not so clear to me. There was significant work involved in both back-end and front-end, including the database. I have been procrastinating on this for almost an hour.

Normally, I just buckle down and start coding. I have found that once I start coding, it usually gets better, pretty quickly. If I can just ignore the distractions around me, it doesn’t take me very long to reach the cherished flow state, where you are so engrossed in the task at hand, you literally lose the sense of time.

However, this was a hairy feature. There were a few uncertainties involved and I had to go back and forth with more senior developers to smooth out some rough edges. I was still not a hundred percent confident to implement the complete feature on my own. So instead of diving into code, I opened a text file and started writing a detailed specification.

It took me some time to come up with specific requirements for the feature. But as I wrote them down, I noticed the feature getting sharper in my mind. By the time I finished writing the spec, I had a pretty good idea of what the feature was supposed to do, and had a good plan for implementing it.

Once I had the specification, I opened visual studio and started writing code. And then an amazing thing happened. It felt like I had a clear path in front of me. My mind was clear, and my fingers were just spewing out lines and lines of code. Though my original estimate was at least a day, I was able to implement the whole feature in under 2 hours.

Hardcore agile developers usually tend to avoid detailed specs in favor of writing code, and I will admit that I haven’t followed spec-driven development rigorously. However, I have found the benefits of having a specification are huge, and any time spent writing a spec is time well invested, and ultimately saves a lot of time during development.

The reason for writing a spec is not to come up with a perfect requirements document to solve as many problems as you can in advance. The real reason is to solve as many problems as you possibly can in advance to minimize the number of surprizes when you are actually writing the code.

A lot of times, when I write the requirements for a feature, it saves me significant headaches later on during the development stage. Almost all the time, when I dive head-first into code without having a specification at hand, I write lower quality code. The act of writing a detailed specification forces you to think about the design of the program. That helps in narrowing down the scope, fishing out the edge cases, and sharpening the functionality in your mind. That ultimately improves the design of the software.

Once you write a specification, you can revisit it later, only to discover bugs and potential enhancements. It can also serve as documentation, not only for you as a developer, but also for the QA department, when they are testing the functionality. It can be used as release documentation by technical writers. Managers can use it so they can communicate with upper management. Ultimately, a detailed specification benefits everyone.

As I write this, I have decided to be more disciplined and write a detailed specification for most, if not all the features I work on.

Method Object Pattern

Sep 30 2019
The behaviour at the center of a complex system is often complicated. That complexity is generally not recognized at first, so the behaviour is represented as a single method. Gradually that method grows and grows, gaining more lines, more parameters, and more temporary variables, until it is a mess.

If you apply composed method and extract parts of code to different methods, it only obscures the situation. Since all parts of such a method generally need all the temporary variables and parameters, any piece of method you break off requires six or eight parameters. 

Problem
  • You have a method that does not simplify well with the composed method
  • How do you refactor a method where many lines of code share many arguments and temporary variables, that are hard to isolate from each other?
Solution
  • Transform the method into a separate class so that the local variables become fields of the class. Ideally, the name of this class relate to a verb, e.g. Processor, Executor, etc. 
  • Then you can split the method into several methods within the same class. 
  • Replace the body of the original method in the original class by creating a method object and calling its executor method. 
Benefits
  • Isolating a long method in its own class prevents a method from ballooning in size. 
  • This also allows splitting it into methods on the new class, which have shared access to the class instance variables. 
Trade-offs
  • You have to add a new class, which might add to the complexity. 
  • If the method you are trying to refactor is not hard to understand and the code is not duplicated, even though it's big, leave it. 
Example

Refactoring

Aug 20 2019
Very little time is spent in writing code. Most programmers spend their time debugging and figuring out what's going on in the codebase they are working with. Fixing the bug is usually pretty quick, but finding it is usually hard. Refactoring is a skill that every software developer must have.
refactoring
Refactoring needs tests. Read the code, gain some insight, and use refactoring to move that insight from your head back into the code. The cleaner code then makes it easier to understand it, leading to deeper insights and a beneficial positive feedback loop. This process will improve your conceptual mental models of the codebase and simplify your understanding of the domain. 

Code Smells
  1. Mysterious Name, that doesn't indicate the purpose of a variable, function, class or a module.
  2. Duplicated Code
  3. Long Function, Large Class
    • Difficult to understand and change
    • Does too many things
  4. Long parameter list
  5. Data clumps, 3/4 items together in lots of places
  6. Primitive obsession

Fundamental Refactoring Techniques

  1. Extract Method
    1. If you have to spend effort looking at a fragment of code and understand what it’s doing, then extract it into a function and give it an intention-revealing name. 
    2. Then, when you read it again, the purpose of the function leaps right out at you, and most of the time you won’t need to care about how the function fulfills its purpose (which is the body of the function).
    3. Extract small pieces first. Before you extract this small piece of a monster method, it looks like it won’t make any difference at all. After you extract more pieces, you’ll probably see the original method in a different way. You might see a sequence that was obscured before or see a better way for the method to be organized. When you see those directions, you can move toward them. 
    4. This is a far better strategy than trying to break up a method into large chunks from the beginning. Too often that isn’t as easy as it looks; it isn’t as safe. It’s easier to miss the details, and the details are what make the code work.
  2. Extract Variable
    1. Expressions can become very complex and hard to read. In such situations, local variables may help break the expression down into something more manageable. 
    2. In particular, they give me an ability to name a part of a more complex piece of logic. This allows me to better understand the purpose of what’s happening. They also improve debugging. 
  3. Rename Methods and Variables
    1. So that the code is more expressive and reads better like a prose. 
  4. Introduce Parameter Object
    1. For groups of data items that regularly travel together, appearing in function after function. 
    2. If you create a class for these items, you can capture the common behaviour over this data into class methods and add validation. 
  5. Combine Functions Into Class
    1. When I see a group of functions that operate closely together on a common body of data (usually passed as arguments to the function call), I see an opportunity to form a class. 
    2. Using a class makes the common environment that these functions share more explicit, allows me to simplify function calls inside the object by removing many of the arguments, and provides a reference to pass such an object to other parts of the system.
    3. This refactoring also provides a good opportunity to identify other bits of computation and refactor them into methods on the new class.

Encapsulation
    Identify secrets that modules should hide from the rest of the system. 

  1. Encapsulate Record
    1. Favour objects over records/tuples. You can hide what is stored and provide methods to access the data. 
  2. Encapsulate Collection/Mutable data
    1. This makes it easier to see when and how data is modified. You can simply put a breakpoint on the setter. 
    2. Common mistake: Access to a collection variable may be encapsulated, but if the getter returns the collection itself, then that collection's membership can be altered without talking to the encapsulation.
    3. Force changes to the collection go through the owning class, giving you the opportunity to modify such changes as the program evolves. 
    4. Ensure that the getter for the collection does not return the raw collection, so that the users cannot accidentally change it. Instead, return a copy of the underlying collection. (watch out for huge collections)
  3. Replace Primitive with Object
    1. Often in the beginning, you represent simple facts as simple data items, such as numbers or strings. As development proceeds, those simple items aren't so simple anymore. 
    2. Create a new class for this data. Initially, it does little more than wrap the primitive, but you have a place to put behaviour specific to its needs. 
  4. Replace Temp with Query
    1. If you are breaking up a large function, turning temporary variables into their own functions makes it easier to extract parts of the function, as you no longer need to pass in variables to the extracted functions. 
    2. Allows you to avoid duplicating calculation logic everywhere, if the variables are calculated in the same way in different places. 
  5. Extract Class
    1. Classes grow as development goes on and become bloated. A class with many methods and a lot of data is too complicated to understand easily. Split it. 
    2. A good sign to know when to split a large class is when a subset of the data and a subset of the methods seem to go together. 
  6. Move Function 
    1. If a function references elements in other contexts more than the one it currently resides in, move that function together with those elements. 
    2. Move all the data and elements used by the chosen function if they fit in the new context. 
    3. Rename the function to fit the new context. 

Simplifying Conditional Logic

  1. Extract Conditional to a Function
    1. Complex conditional logic is one of the most common sources of complexity in a program. 
    2. Move the complicated conditional logic to a function with an intention-revealing name. 
    3. If you are doing a series of conditional checks where each check is different yet the resulting action is same, consolidate them into a single conditional check with the resulting action. 
  2. Replace Conditional with Polymorphism
    1. If you have several functions that have a switch statement on a type code, 
    2. Remove the duplication of the common switch by creating classes for each case and using polymorphism to bring out the type-specific behavior. 
  3. Introduce Special Case / Introduce Null Object
    1. If you find many parts of a code base having the same reaction to a particular value, bring that reaction into a single place. 
  4. Introduce Assertions
    1. Often, sections of code work only if certain conditions are true. 
    2. Such assumptions are often not stated, but can only deduced by looking through the algorithm, sometimes the assumptions are stated with a comment. 
    3. A better technique is to make the assumption explicity by writing an assertion. 
    4. An assertion is a conditional statement that is assumed to be always true. Failure of an assertion indicates a programmer error. 

Refactoring APIs

  1. Separate Query from Modifier
    1. A function should do only one thing. Differentiate between functions with side effects and those without. 
    2. Any function that returns a value should not have any side effects. 
    3. If you come across a method that returns a value but also has side effects, always separate the query from the modifier. 
  2. Remove Setters if not needed
    1. If you don't want a property to change once the object is created, don't provide the setter and make it immutable (read-only)
    2. Initialize the property in the constructor. 
  3. Replace Constructor with Factory Function/Class
    1. Factory function will call the constructor, but you can replace it with something else while testing. 
  4. Replace Function with Method Object / Command Object
    1. There are times when it's useful to encapsulate a function into its own object, called a command object. 
    2. The sole purpose of the command object is the execution of the method it's replacing. 

Inheritance

  1. Pull Up Method/Data
    1. If methods/data are duplicated in the subclasses, pull them up into the super class. 
  2. Push Down Method/Data
    1. If a method/data is only relevant to one subclass, removing it from the super class and putting it only on the subclass makes that clearer. 
  3. Replace Type Code with Subclasses
    1. This allows you to use polymorphism to handle conditional logic. This is most useful when you have several functions that invoke different behavior depending on the value of the type code. 
    2. With subclasses, you can apply "replace conditional with polymorphism". 
  4. Extract Superclass
    1. If you see two or more classes doing similar things, then pull their similarities together into a superclass. 
    2. Use 'Pull up data' and 'Pull up method' refactorings to move the common behavior. 

Guidelines
  1. Save the code you start with. Make sure you are using version control. 
  2. Make sure you can get back to the code you started with. 
  3. Make sure you have a test for the piece of code you are trying to refactor
  4. Keep refactorings small, and do them one at a time. 
  5. Don't mix different refactorings into a single commit. If you find one, add a comment to come back to it later. 

The bugs you didn't see

Aug 15 2019
Every successful software product is the result of the collaboration between developers and the QA team. However, it’s the developers who get the lion’s share of the praise, and the testers are mostly ignored. Devs blame the QA for finding faults in their code, and management blames them for delaying the release. I think this is unfortunate and unfair.

We usually don’t notice what’s not there. When you see a flawless software product, it’s easy to notice all the bells and whistles and admire the technology and the development efforts that went into it. However, you are not seeing all the bugs that are not there, the countless bugs that were lurking in the version 1.0, and which were only discovered by QA by testing the software repeatedly, which can be perceived as a boring, mind-numbingly repetitive job by developers who like to solve new problems and take on new challenges everyday. However, testing is a skill in itself, which needs vast reserves of patience and a Stoic attitude in a sense, to do the negative visualization to find out all the paths to failure.

Testing the software you wrote can be very frustrating for developers. If I wrote a piece of code, I am only going to test it to make sure that it works. As a result, I am only going to test the best-case scenario. The QA’s job is to find out all the ways in which the product can fail. That makes the role of the QA very valuable in any software company. Next time, if a QA finds a bug in the software I wrote, I am going to thank them, because that’s one less bug that the customer will see.

Managing Complexity

Mar 29 2019
Software development is difficult. Especially if you are working on a 25-year old enterprise software that has gone through multiple platforms, technologies, and has seen multiple generations of developers. All of which makes it hard to understand and difficult to develop. What can we do as developers? Turns out, a lot.

As a developer, I spend a lot of time writing code. But I spend even more time maintaining that code. Often, I go back to the code I wrote just a week ago and find it a tangled mess that I almost cannot understand. Over time, entropy kicks in, and the code becomes so complex that it’s hard to even know what was I thinking.

In his landmark paper titled, No Silver Bullets, Fred Brooks describes two types of complexities which make software development difficult. Essential, and Accidental.
  1. Essential complexity: Complexity inherent to the software. Properties that a software must have in order to be that software. This includes a complex domain and complicated business logic.
  2. Accidental complexity: Complexity not related to the software. Properties that a software just happens to have, which don’t really bear on whether the software is what it is. The software could very well do without these.
In Code Complete, Steve McConnell argues that Managing Complexity is the most important technical topic in software development, making it the software’s primary technical imperative. The book essentially provides a two-part approach to managing complexity:
Minimize the amount of essential complexity that a developer’s brain has to deal with at any one time. Keep accidental complexity from needlessly proliferating.
Based on these principles, there are quite a few techniques we can use to reduce complexity.
  1. Isolate: As software developers, we shouldn’t try to cram whole programs into our heads at once. We should try to organize our programs in such a way that we can safely focus on one part of it at a time. The goal is to minimize the amount of a program you have to think about at any one time.
  2. Divide and Conquer: The complexity of a problem is reduced by dividing the system into subsystems. The goal of a software design technique is to break a complicated problem into simple pieces. The more independent the subsystems are, the more we make it safe to focus on one thing at a time.
  3. Abstractions: Writing programs in terms of the problem domain, rather than in terms of low-level implementation details, and working at the highest level of abstraction reduce the load on your brain.
  4. Simplify: Avoid making clever designs. They are hard to understand. Instead make ‘simple’ and ‘easy-to-understand’ designs. If your design doesn’t let you safely ignore most other parts of the program when you are immersed in one specific part, the design isn’t doing its job.
  5. Reusability: Designing the system so that you can reuse pieces of it in other systems.
  6. Non-leaky Abstraction: Trying to build the software in such a way so that you can view the system at any single level and get a consistent view. Design the system so that we can observe it at one level without dipping into other levels.
  7. Information Hiding: Asking ‘what details and information should I hide?’ solves many difficult design issues.
  8. Programming Tools: An effective use of variables, routines, classes and packages provided by the programming language can help reduce complexity tremendously. Design is needed at several different levels of detail, as follows:
I guess the many challenges involved in building a working software are what makes the activity so much fun, and a worthwhile pursuit to follow. If it was easy, it wouldn’t be fun, either. So I guess I am better off embracing and managing all this complexity. Happy coding!

Programming by Coincidence

Mar 15 2019
I was really struggling at work this week. Spent hours banging my head to parse a simple XML document. According to pragmatic programmers, I was programming by coincidence, without any clear plan, just hoping to get the code working somehow, and failing completely.

The weary soldier advances cautiously out of the brush. There’s a clearing ahead: are there any land mines, or is it safe to cross? There aren’t any indications that it’s a minefield—no signs, barbed wire, or craters. The soldier pokes the ground ahead of him with his bayonet and winces, expecting an explosion. There isn’t one. So he proceeds painstakingly through the field for a while, prodding and poking as he goes. Eventually, convinced that the field is safe, he straightens up and marches proudly forward, only to be blown to pieces.

The soldier’s initial probes for mines revealed nothing, but this was merely lucky. He was led to a false conclusion—with disastrous results.

As developers, we also work in minefields. There are hundreds of traps just waiting to catch us each day. Remembering the soldier’s tale, we should be wary of drawing false conclusions. We should avoid programming by coincidence—relying on luck and accidental successes—in favor of programming deliberately.
Yes, I was that soldier. Finally, after confronting my ignorance and admitting my complete lack of understanding of how XML works, I decided to do a deep dive into this topic. As always, I found a few good courses on PluralSight and started with Linq to XML, by K Scott Allen. The course taught me everything I needed to know about XML and much more, in just under 30 minutes.

It was mindblowing. At work this morning, I was able to crank out beautiful C# code using Linq to get it done exactly what I wanted with the XML. Linq-to-XML is like a genie. You wish for what you want to do with the XML, and it does it for you. All I needed to do was understand a few basic concepts and classes in the System.XML.Linq namespace.

According to the docs,

Linq-to-XML is an in-memory XML programming interface that enables you to modify XML documents efficiently and easily.
So true.

Here are a few of the essential classes we need:
  1. XDocument: This represents the XML document. It derives from XContainer and hence can contain child nodes. However, it can have only one child node, to follow the XML standard that there can be only one root element in an XML document.
  2. XElement: Represents an XML element. It is one of the fundamental classes in Linq-to-XML. We can use this class to create/read/modify/delete the XML elements, add attributes to existing elements, and much more.
  3. XAttribute: Represents an XML attribute, which is simply a name-value pair associated with an XML element.
  4. XNamespace: Represents an XML namespace. The most common way to create its object is to simply assign a string to it.
There are additional classes in the namespace. However, these four classes were enough for all my practical purposes. Let’s see how to use them.

Creating XML
public static void CreateXML()
{
    var doc = new XDocument();
    XNamespace ns = "https://www.akshaykhot.com";

    var friends = new XElement(ns + "Friends");
    
    var bandya = new XElement(ns + "Friend",
        new XAttribute("Name", "Akshay Darade"),
        new XAttribute("From", "School")
        );
    var abhiyash = new XElement(ns + "Friend",
        new XAttribute("Name", "Abhiyash Jain"),
        new XAttribute("From", "College")
        );
    var kunal = new XElement(ns + "Friend",
        new XAttribute("Name", "Kunal Veera"),
        new XAttribute("From", "Building")
        );
    
    friends.Add(bandya, abhiyash, kunal);
    doc.Add(friends);
    doc.Save("friends.XML");
}
To generate this beautiful XML:

<?XML version="1.0" encoding="utf-8"?>
<Friends XMLns="https://www.akshaykhot.com">
  <Friend Name="Akshay Darade" From="School" />
  <Friend Name="Abhiyash Jain" From="College" />
  <Friend Name="Kunal Veera" From="Building" />
</Friends>
To be honest, I think the C# code is as much, if not more, readable as the XML.

Parsing XML
public static void QueryXML()
{
    XDocument doc = XDocument.Load("friends.XML");
    XNamespace ns = "https://www.akshaykhot.com";
    
    // find all school frinds
    var schoolFriends = doc.Element(ns + "Friends")
                           .Elements(ns + "Friend")
                           .Where(friend => friend
                                            .Attribute("From")
                                            .Value.Equals("School"));

    foreach (XElement friend in schoolFriends)
    {
        Console.WriteLine(friend.Attribute("Name").Value);
    }
  
}
There is a gotcha in the above code, and I got burned by it. If you are not careful, and one of the friends don’t have an attribute From, it will throw the infamous object reference not set to an instance of an object exception.

To get around this, it’s better to create a common utility method, which you can use any time you want to read the attributes on the elements.
private string GetAttribute(XElement element, string attributeName)
{
    string value = string.Empty;
    XAttribute attr = element.Attribute(attributeName);

    if (attr != null)
        value = attr.Value;

    return value;
}
The code looks cleaner and is much more concise than the traditional .net XML manipulation libraries. I was able to replace most of the spaghetti code that I wrote during the week with lesser and more powerful code.

Always better to learn a new skill which helps you to solve the problems you are facing, and it just feels so damn good. Today was one of the happiest days at work for me, compared to the frustrating week I had so far. Here are some of the lessons learned:
  1. Always be aware of what you are doing.
  2. Don’t code blindfolded.
  3. Have a plan, before you start programming.
  4. If you don’t know why your code works, you won’t understand why it fails, which it will.

Joys of Programming

Dec 15 2018
My head hurts. It’s 11 pm at night, and I just finished a 3 hour debugging marathon to fix a bug that has been on my to-do for last 2 weeks. What began as a simple list of items not showing up in the browser ended up in an ill-formatted sql caused by mis-match of enumeration in a switch statement in the deep backend. The fix involved changing a single word, but the path I had to take was treacherous and equally fulfilling. The feeling is serene.

Functions as Objects

Apr 10 2018
In JavaScript, functions are objects. We can not only call them, but pass them to other functions and also receive them from other functions. 

What's cool, is that we can instantiate new functions by using the new syntax. 
let func = new Function ([arg1, arg2, ...argN], body);
The function func is created with the arguments as the first parameter, and the body as the second parameter. 
let log = new Function('val', 'console.log(val)');
log('test'); // prints 'test'
We can also create a function that doesn't take any parameters, 
let say = new Function(`console.log('saying')`);
say();  // prints 'saying'
Like objects, functions do have a few properties, including:
  • name: returns the name of the function, or an empty string
function log(val) {
    console.log(val);
}
log(log.name); // logs 'log'. Is your head spinning, too?
  • length: returns the number of function parameters, rest parameters are not counted. 
function log(val) {
    console.log(val);
}
log(log.length); // logs 1

Functions, functions everywhere

Apr 03 2018
Since getting exposed to functional programming, I have started seeing functions everywhere.

One of the list abstractions that I never really understood was the reduce function. Whenever I came across it, my eyes just used to glaze over it. Not anymore.

Here is a simple reduce function that operates over a list of numbers to return the total. 
let numbers = [1, 2, 3, 4, 5];

let total = numbers.reduce((prev, current) => prev + current, 0);
Here's how I can imagine a actual reduce implementation might look like, that I was able to write by thinking of functions as first-class constructs, which can be passed around like objects. 
let numbers = [1, 2, 3, 4, 5];
let total = summarize((prev, current) => prev + current, 0);
console.log(total);

function summarize(func, start) {    
    let prev = start;
    for(let i = 0; i < numbers.length; i++) {
        let current = numbers[i];
        prev = func(prev, current);
    }
    return prev;
}
Doesn't look that complicated now, does it?

.NET Interview Questions

Jan 26 2018

General

  • An application’s architecture consists of following layers
    • UI layer: web app, wpf, windows gui, etc.
    • Business Logic: How your application works
    • Data Access Layer: Provides communication with the databases, e.g. EF Core, Repository Pattern
    • Common functionalities and libraries
    • Database

Classes

  • Explain classes and objects in simple terms
    • A class is a template that specifies the data and operations for an entity
    • An object is an instance of that class created at runtime using the new keyword
  • What is a static class? Why is it used?
    • A Static class provides a cohesive set of functionalities/services, and doesn’t contain any internal data
    • It has a static keyword in the signatures
    • It can only contain static members, i.e. static fields, static properties and static methods
    • It doesn’t have an instance constructor, as we don’t need to initialize it
    • It acts as a container for utility methods/common code libraries, e.g. logging, email, etc. 
  • What is a Partial class? 
    • Partial class allows us to split the definition of a class or a struct, an interface or a method over two or more source files.
  • What is a Sealed class?
    • A sealed class cannot be used as a base class.
    • No other classes can inherit a sealed class. 
  • Null conditional operator ?.
    • Removes the need to explicitly check the null references
    • If null then null; if not then dot
  • What is lazy loading and when would you use it?
    • It is a technique of instantiating objects when they are needed and not before
    • Create the instance in the property getter for the related object
  • What is an interface?
    • It’s a specification for identifying a related set of properties and methods.
    • When a class implements an interface, it commits to supporting that specification by implementing code
    • By using interfaces, we can write more generalized code when defining method parameters, or method return values

Fields and Properties

  • Why use Nullable field?
    • Use Nullable field, i.e. string price? to differentiate between not set and default value 
    • You can use HasValue and Value properties on nullable fields
  • What’s the difference in const vs readonly
    • const provides compile time constant values. They must be hardcoded, or an expression that evaluates at compile time. 
    • readonly provides runtime constant values. They can be set via expressions evaluated at runtime, but don’t change them later. 

Methods

  • How can you increase the readability of a method call?
    • Use the named arguments, i.e. placeOrder(product, quantity: 12, sendCopy: false)
  • What is a delegate?
    • A delegate is a type that represents a reference to a method with with a parameter and a return type
    • A lambda expression can be passed to a delegate
  • What are extension methods?
    • Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type.

Strings

  • Strings are immutable reference types, that act as value types
  • What’s verbatim string literals?
    • If you put @ in front of the string, it will print \r or \n as it is, instead of new line
  • How do you build large blocks of string?
    • Use StringBuilder, it’s a mutable string(conceptually)

Collections

  • What’s the difference in for vs. foreach in C#? 
  • foreach is easier to read and write
  • for gives us more flexibility. We can update the element, as well as change the order or sequence of iteration

Generics

  • What are generics? Why are they used?
    • Generics is a technique that allows to define variable data types
    • Generics allow us to write more reusable code without fixing data types, and at the same time provide type safe collections

Tips for Code Review

Jan 19 2018
You want your code to be examined by a repairman, instead of an inspector. 

A repairman looks for flaws in the code with the intent of fixing them and avoiding them in the future. An inspector, on the other hand, only points them out. This might result in shame and avoidance of introspective tendencies. 

Much better to have a repairman looking at your code.