Garbage Collection Internals (Part 3 – Java)

In Part 1 and Par 2 we saw that there is no Garbage Collection at language level in C and C++, even though we can use “smart” pointers in C++ to carry out deallocation when it goes out of scope.

Languages which came after C/C++ understood the problems of memory leaks and developers putting substantial efforts in managing memory that they implemented Garbage Collection at the platform/VM level.

Java equivalent of earlier C++ program
/*
 * File:      GCJava.java
 * Project:   CPP
 * Author:    Sanjay Vyas
 * 
 * Description:
 * 
 * Revision History:
 * 2020-Jun-21	[SV]: Created
 */

class AllocatedResource {
    private int data;

    public AllocatedResource(int x) {
        this.data = x;
    }

    @Override
    protected void finalize() throws Throwable {
        System.out.println("Deallocating " + this.data);
    }
}

public class GCJava {
    public static void main(String[] args) {
        AllocatedResource resource = new AllocatedResource(5);
        System.out.println("End of program");
    }
}
And here is the output
End of program

That’s it!!
If we were expecting the finalize() method to blurt out something, well, it didn’t even get called. Not even when the program came to an end. In fact, there is no gaurantee that finalize will ever get called. Morover, starting from Java version 9, it has been deprecated.

Let’s make our code put some pressure on GC and create thousands of objects and see what happens

/*
 * File:      GCJava.java
 * Project:   CPP
 * Author:    Sanjay Vyas
 * 
 * Description:
 * 
 * Revision History:
 * 2020-Jun-21	[SV]: Created
 */

class AllocatedResource {
    private int data;

    public AllocatedResource(int x) {
        this.data = x;
    }

    @Override
    protected void finalize() throws Throwable {
        System.out.println("Deallocating " + this.data);
    }
}

public class GCJava {
    public static void main(String[] args) {
        
        // Put pressure on GC
        for (int i = 0; i < 1000000; i++) {
            AllocatedResource resource = new AllocatedResource(i);
        }
        System.out.println("End of program");
    }
}
And what do we get?
:
Deallocating 822025
Deallocating 822024
Deallocating 822023
Deallocating 822022
Deallocating 822021
Deallocating 822020
Deallocating 822019
Deallocating 651277
Deallocating 822013
Deallocating 822012
Deallocating 822011
Deallocating 822010
:
End of Program

Finally! The Garbage Collector ran… but only when it started to run out of heap because we allocated 1000000 objects.

So, don’t use finalize() because there is no guarantee that it will be called and also its deprecated now.

So how does Java manage Garbage Collection?

Java has multiple heaps – Eden, Survivors, Tenured, Permanent Generation

Java, unlike C/C++, has multiple heaps like Eden, Survivors, Tenured and Permanent generation. It’s stack is also slightly different with operand stack part for computation (not shown in the Concept Visual, maybe topic of another blogpost).

Java Garbage collector works across 4 heaps (Eden, Survivor 1&2 and Tenured) to keep track of “unreachable” objects which it marks-sweeps-moves across these segments.

HeapPurpose
EdenNew object allocations are stored here
Survivor 1After GC, objects from Eden are moved here
Survivor 2After GC, objects from Survivor 1 are moved here
TenuredLong surviving objects are moved here
PermanentNot really object heap but keeps class artefacts

So what, happens when GC runs?
Let’s say we release two rerefences a and d by setting them to null. As a result, objects containing “5” and “8” and now “unrechable”, i.e. no one is pointing to them. So what happens? GC will come running and remove them? NO! From the first example in this post we know that GC doesn’t run as soon as a single object is orphaned. In fact, the GC wont run unless it starts to run low on heap memory. So the object will keep lying around in the heap.

However, let’s assume that the GC runs, then what happens? Well, GC will mark those objects which are still “reachable”, in this case “6” and “7”, move them to Survivor generation (S0) and then clear the Eden heap.

Mark-Sweep and Move From Eden to Survivor 0 heap

As a result, Eden now becomes empty and surviving objects are “compacted” into Survivor 0. Why not let object remain is just one heap and remove those which are unreachable? Well, if they remain where they are, the free space between them will be fragmented and if there is a larger object is to be allocated, we may not have enough “contiguous” free space in the heap. That’s the reason existing objects are “moved” to a different heap and “compacted”.

So what does the Process Map looks like now?

Post GC, object’s are moved and compacted in Survivor 0

Efficient, isn’t it? Periodically, Garbage Collector removes unreachable objects and moves the remaining in a compacted manner in Survivor generation. So why 2 Survivor generations? Survivor 0 and Survivor 1?

Well, if memory gets fragmented in Survivor 0, then is moves and compacts to Survivor 1 and vice versa. This way new (and may shortlived) objects can be allocated in Eden space while long surviving objects osciallte between S0 and S1. Huh? They will oscillate forever? Hehe.. no. If an object survives a threashold, it’s finally promoted to Tenured generation, where it will no longer be moved around (old people, you see :-)).

Here is what it might look in Tenured.

Tenured Generation

An object reaches “Tenured” generation if it survives N GC passes threshold. Interesting, isn’t it?
We have compared non-GC languages like C and library based GC like C++ Smart pointer. Java was one of the first commercial language to bring in Garbage Collection (the other was Python) and .NET followed with its own Garbage Collection system. In fact, it has 8 heaps (compared to 4 heaps of Java) and 9th has been just added to .NET 5. So, another post?

Garbage Collection Internals Series

  1. Part 1 – C language
  2. Part 2 – C++ Language
  3. Part 3 – Java

Garbage Collection Internals (Part 2 – C++)

In the previous post we saw that C progamming language does not have a built-in garbage collector, but what about C++? Yes and No.

C++ does NOT have a built-in garbage collector at language level but over a period of time it has added “smart” pointers, which deallocate memory when they go out of scope. This at least stems the memory leaks caused in typical C++ program, provided the developer uses these smart pointers.

How smart are these pointers?
/*
 * File:      SmartPointer.cpp
 * Project:   CPP
 * Author:    Sanjay Vyas
 * 
 * Description:
 * 
 * Revision History:
 * 2020-Jun-20	[SV]: Created
 */

#include <iostream>
using namespace std;

// Resource we will allocate on heap
class AllocatedResource
{
private:
    int data;

public:
    // Constructor
    AllocatedResource(int x)
    {
        this->data = x;
        cout << "Allocated " << x << "\n";
    }

    // Destructor
    ~AllocatedResource()
    {
        cout << "Deallocated " << this->data << "\n";
    }

    void print()
    {
        cout << "Resource: " << this->data << "\n";
    }
};

int main()
{
    unique_ptr<AllocatedResource>
        {new AllocatedResource(5)};
    return 0;
}

And here is the output
Allocated 5
Deallocated 5

As we can see, unique_ptr automatically deallocates the pointer when it goes out of “scope”, in this case, when main ends. This frees us up from keeping track of allocation and manually calling delete when it’s not longer needed.

unique_ptr is an object itself and keeps track of allocation it does
So what happens if we dont deallocate
and simply reallocate a unique_ptr
/*
 * File:      AutoPtr.cpp
 * Project:   CPP
 * Author:    Sanjay Vyas
 * 
 * Description:
 *      GC is not at language level in C++
 *      We can use auto_ptr/unique_ptr to automate it    
 * 
 * Revision History:
 * 2020-Jun-20	[SV]: Created
 */
#include <iostream>
#include <memory>

using namespace std;

// Resource we will allocate on heap
class AllocatedResource
{
private:
    int data;

public:
    // Constructor
    AllocatedResource(int x)
    {
        this->data = x;
        cout << "Allocated " << x << "\n";
    }

    // Destructor
    ~AllocatedResource()
    {
        cout << "Deallocated " << this->data << "\n";
    }

    void print()
    {
        cout << "Resource: " << this->data << "\n";
    }
};

int main()
{
    // Raw pointer (C style)
    AllocatedResource *rawPointer;
    cout << "Raw pointer allocation\n";
    for (int i = 0; i < 5; i++)
    {
        // This will allocate and fire constructor
        rawPointer = new AllocatedResource(i);
        // WARNING! Memory leak occuring on rawPointer
    }
    cout << "Raw pointer causes memory leak\n\n";

    // Unique pointer (C++ style)
    unique_ptr<AllocatedResource> smartPointer{};
    cout << "Automatic pointer allocation\n";
    for (int i = 0; i < 5; i++)
    {
        // This will allocate and fire constructor
        // When assigned again
        //  It will fire destructor on previous allocation
        //  and fire constructor on new allocation
        smartPointer = unique_ptr<AllocatedResource>
            { new AllocatedResource(i + 100) };
    }
}

And here is the output
Raw pointer allocation
Allocated 0
Allocated 1
Allocated 2
Allocated 3
Allocated 4
Raw pointer causes memory leak
Automatic pointer allocation
Allocated 100
Allocated 101
Deallocated 100
Allocated 102
Deallocated 101
Allocated 103
Deallocated 102
Allocated 104
Deallocated 103
Deallocated 104

As we can see, the C style “raw” pointer allocates memory but if we don’t call delete on it, the memory will not be deallocated, causing it to become “garbage” which is not “garbage collected”.

However, unique_ptr is a class which automatically deallocates when it goes out of scope (basically does a delete when its destructor is called), or when we assign a new allocation to it. This brings some semblance of sanity in deallocating unused memory allocations in C++. However, let me repeat… the is NO built-in Grabage Collector in C++, instead we have to use unique_ptr or shared_ptr and make sure we reduce memory leaks from our code.

If unique_ptr is again allocated, it auto deallocates the previous allocation

C and C++ both don’t have built-in garbage collector, but at least C++ provides built-in classes like unique_ptr and shared_ptr which automatically manage the allocation. Internally shared_ptr uses reference counting to keep track of how many pointers are pointing to a given allocation. However, this is not language level Reference counting (Swift or Python).

Garbage Collection Internals Series

  1. Part 1 – C language
  2. Part 2 – C++ Language
  3. Part 3 – Java

Garbage Collection Internals (Part 1 – C)

Why do programs produce garbage? πŸ€”

Well, we first have to understand memory internals of programming languages to understand what is dynamic memory and what constitutes “garbage”. So let’s take a look at this Digital ConceptVisual video which explains Process Map, Segments, Global Data area, Stack and Heap, the last one being the focus of our attention.

Compilation Process of C/C++ and Process Map

As we can see from the above video, global variables (if any in the language) are stored in DATA/BSS segment, local variables are in the STACK and any data created at run time are stored in HEAP.

Languages like C/C++ were mostly Global and Local variables and only when the developer specifically called malloc/calloc or new, it allocated memory in the HEAP.

One great thing about HEAP allocation is that it’s allocated at runtime and can be “released” by the developer. If the developer stops using the allocated memory and does not release it, well, that’s when it’s called “Garbage” memory.

Different languages have different strategy for releasing heap allocated memory once it’s no longer needed

TechnologyGrabage Collection
CYou clean up your own mess
C++You clean up your own mess
JavaMark and Sweep Garbage Collector (GC)
SwiftAutomatic Reference Counting (ARC)
COMReference Counting (RC)
C#Mark and Sweep Garbage Collector (GC)
PythonAutomatic Reference Counting (ARC) + Mark and Sweep Garbage Collector (GC)
JavaScriptEarlier was ARC but now most JS Engine implement Mark and Sweep (GC)
Language/Technology and Garbage Collection

So there are 4 Garbage collection strategies

  1. No automatic Garbage Collection – C/C++
  2. Manual Reference Counting (RC) – COM
  3. Automatic ReferenceCounting (ARC) – Swift
  4. Mark and Sweep (Compact or Copy) – Java, .NET, JavaScript
1. No Automatic Garbage Collection - C/C++
/*
 * File:      NoGC.c
 * Project:   CPP
 * Author:    Sanjay Vyas
 * 
 * Description:
 *      C program to demonstarte No GC
 * 
 * Revision History:
 * 2020-Jun-20	[SV]: Created
 */

#include <stdio.h>  // printf/scanf
#include <stdlib.h> // malloc/qsort

// Maximum random number
#define MAX (100)

// Helper function to print array
void print(int *array, int size)
{
    int offset;

    // Print comma (upto 2nd last)
    for (offset = 0;
         offset < size-1;
         offset++)
    {
        printf("%d, ", array[offset]);
    }

    // Print last element
    printf("%d\n", array[size-1]);
}

// Compare function required for qsort
// Return
//      0 if both are equal
//     <0 if lhs is < rhs
//     >0 if lhs is > rhs
int intcmp(const void *lhs, const void *rhs) 
{
    // We are given 2 elements as void *
    // We need to typecast them back to int
    return *(int *)lhs - *(int *)rhs;
}

int main()
{
    int *pointer = NULL;    // Defensive programming πŸ™‚
    int size;
    int offset;

    while (printf("Enter size (0 to quit): "),
           scanf("%d", &size),
           size)
    {
        // Allocate heap memory
        pointer = (int *)malloc(size * sizeof(int));

        // Randomize it
        for (offset = 0;
             offset < size;
             offset++)
        {
            pointer[offset] = rand()%MAX;
        }

        // Now print the array
        print(pointer, size);

        // Let's sort it using built in function
        qsort(pointer, size, sizeof(int), intcmp);

        // And print it again
        print(pointer, size); 

        // WARNING! Memory is LEAKING here
        // We did not free(pointer)
        // The loop will use same pointer
        // to malloc again, losing the previous address
    }
}
What happens we do a malloc or new
This is what happens when we do a malloc
And what is a memory leak?
Losing address without doing free is MEMORY LEAK

What we see in the above image is a result of not deallocating memory (free or delete) and losing the address. Over a period of time, the application will fill up its heap area and would no longer be able to allocate more memory as previously unused allocations are occupying the heap area. These unused allocations are called GARBAGE.

Remember to free your allocations
/*
 * File:      FreeMem.c
 * Project:   CPP
 * Author:    Sanjay Vyas
 * 
 * Description:
 *      C program to demonstarte No GC
 * 
 * Revision History:
 * 2020-Jun-20	[SV]: Created
 */

#include <stdio.h>  // printf/scanf
#include <stdlib.h> // malloc/qsort

// Maximum random number
#define MAX (100)

// Helper function to print array
void print(int *array, int size)
{
    int offset;

    // Print comma (upto 2nd last)
    for (offset = 0;
         offset < size - 1;
         offset++)
    {
        printf("%d, ", array[offset]);
    }

    // Print last element
    printf("%d\n", array[size - 1]);
}

// Compare function required for qsort
// Return
//      0 if both are equal
//     <0 if lhs is < rhs
//     >0 if lhs is > rhs
int intcmp(const void *lhs, const void *rhs)
{
    // We are given 2 elements as void *
    // We need to typecast them back to int
    return *(int *)lhs - *(int *)rhs;
}

int main()
{
    int *pointer = NULL; // Defensive programming πŸ™‚
    int size;
    int offset;

    while (printf("Enter size (0 to quit): "),
           scanf("%d", &size),
           size)
    {
        // Allocate heap memory
        pointer = (int *)malloc(size * sizeof(int));

        // Randomize it
        for (offset = 0;
             offset < size;
             offset++)
        {
            pointer[offset] = rand() % MAX;
        }

        // Now print the array
        print(pointer, size);

        // Let's sort it using built in function
        qsort(pointer, size, sizeof(int), intcmp);

        // And print it again
        print(pointer, size);

        // Remember to deallocate memory
        free(pointer);
    }
}

In C programming there is no built-in GC (Garbage Collection) and as developers we must keep track of the memory we are allocating and runtime and deallocate it when not required. This is tough given that the codebase may be huge and memory addresses may be passed around, losing track of who allocated it and who will deallocate it. Add to this, many developers do not have visualisation of what is happening in memory.

No wonder, languages which came after C/C++ implemented some from of Garbage Collection (Java, .NET, Python, Swift)

Garbage Collection Internals Series

  1. Part 1 – C language
  2. Part 2 – C++ Language
  3. Part 3 – Java

Private in JavaScript ESNext (Part 3)

In the previous two posts we talked about how to create “private” fields for a class. Those involved kind of convoluted mechanisms like closure or WeakMaps.

JavaScript is constantly evolving and in the new ES2019 standard there is a clean way of creating “private” fields of a class

Let's see how ES2019 creates private
class Account {

    // True private fields
    #id = 0;
    #name = "";
    #balance = 0;

    constructor(id, name, balance) {
        this.#id = id;
        this.#name = name;
        this.#balance = balance;

    }

    withdraw(amount) {
        this.#balance -= amount;
    }

    deposit(amount) {
        this.#balance += amount;
    }

    print() {
        console.log(
            `ID: ${this.#id}`,
            `Name: ${this.#name}`,
            `Balance: ${this.#balance}`
        );
    }
}

let eich = new Account(1, "Brendan", 10000);
eich.print(); 

// This doesn't work
eich.#balance = 50000;
And here is the output
ID: 1 Name: Brendan Balance: 10000

eich.#balance = 50000;
^
SyntaxError: Private field '#balance' must be declared in an enclosing class

That’s it! No more closures, Symbols or WeakMaps to implement private in JavaScript latest version.
But JavaScript… why oh why, did you not use the reserved word private??? It would have been so simple to write something like

// Warning: This is NOT valid syntax

class Account {

    // What it COULD have been
    private id = 0;
    private name = "";
    private balance = 0;

    constructor(id, name, balance) {
        this.id = id;
        this.name = name;
        this.balance = balance;

    }

    withdraw(amount) {
        this.balance -= amount;
    }

    deposit(amount) {
        this.balance += amount;
    }

    print() {
        console.log(
            `ID: ${this.id}`,
            `Name: ${this.name}`,
            `Balance: ${this.balance}`
        );
    }
}

However, there is one thing STILL elusive, even in the latest version of JavaScript.. private functions. There is still no way to mark a function as private. So the following still doesn’t work

class Account {

    // True private fields
    #id = 0;
    #name = "";
    #balance = 0;

    constructor(id, name, balance) {
        this.#id = id;
        this.#name = name;
        this.#balance = balance;
    }

    // Cannot create private functions
    // # works on variables but not functions
    #sendSms() {
        console.log(`Sms Sent: Updated balance=${this.#balance}`);    
    }

    withdraw(amount) {
        this.#balance -= amount;
    }

    deposit(amount) {
        this.#balance += amount;
    }

    print() {
        console.log(
            `ID: ${this.#id}`,
            `Name: ${this.#name}`,
            `Balance: ${this.#balance}`
        );
    }
}

let eich = new Account(1, "Brendan", 10000);
eich.print();

So, the question remains… what is the most elegant way of creating private functions in ES6 or later such that we don’t land up adding the same function in EVERY instantiated object.

If you have ideas, drop me a comment

Private in JavaScript Series

Private in JavaScript ES6 (Part 2)

JavaScript ES6 brought a lot of changes like const, let, default arguments, spread operator, classes..
Wait WHAT? JavaScript now is a “class” based OO instead of “prototype” based OO???

Relax! class is just syntactical sugar coating and it’s still “prototype” based OO language

I repeat.. internally JS is NOT class based OO language

Hey, but there is a class keyword! Yes, and it still creates objects in memory.

Everything in JavaScript is an “Object” inside memory

Let’s compare ES5 “class” with ES6 class

How to create a "class" in ES5
// The following is NOT ES6 class keyword
// But if we "imagine" a class
// function looks like a constructor πŸ™‚
// class Account
// {
        function Account(id, name, bal) {

            // Public "fields"
            this.id = id;
            this.name = name;

            // Private "field"
            // NOT stored in the object
            // Stored in a "closure"dictionary
            // Which is visible ONLY inside this scope
            let balance = bal;

            // Operations
            this.deposit = function (amount) {
                
                // Inner functions can access
                // closure variables like balance
                balance += amount;
            }

            this.withdraw = function (amount) {
                // balance is NOT a field
                // But we can access outer variables
                balance -= amount;
            }

            this.print = function () {
                console.log(
                    `ID: ${this.id}`,
                    `Name: ${this.name}`,
                    `Balance: ${balance}`
                )
            }
        }
// }

let eich = new Account(1, "Brendan", 10000);
eich.print();
And here is the output
ID: 1 Name: Brendan Balance: 10000

So how do we create class in ES6?

I repeat.. internally JS is NOT class based OO language
/*
 * ES6 has a class keyword
 * But internally there are no classes
 */

// Using ES6 syntax
class Account {

    // Instead of function Account(...)
    constructor(id, name) {

        // Public "fields"
        this.id = id;
        this.name = name;
    }

    // Member function
    print() {
        console.log(
            `ID: ${this.id}`,
            `Name: ${this.name}`,

        )
    }
}

let eich = new Account(1, "Brendan");
eich.print();
Here is the output
ID: 1 Name: Brendan

Now let’s add a “private” field called balance in our Account class. Hmm.. where?
In our ES6, we just defined a closure variable in the outer function Account and that was available to inner functions like deposit and withdraw. So let’s try that

/*
 * ES6 has a class keyword
 * But internally there are no classes
 */

// Using ES6 syntax
class Account {

     balance = 10000;

    // Instead of function Account(...)
    constructor(id, name) {

        // Public "fields"
        this.id = id;
        this.name = name;
    }

    // Member function
    print() {
        console.log(
            `ID: ${this.id}`,
            `Name: ${this.name}`,
            `Balance: ${balance}`
        )
    }
}

let eich = new Account(1, "Brendan");
eich.print();
And here is the output
`Balance: ${balance}` 
          ^
ReferenceError: balance is not defined

Huh? What just happened? Isn’t balance a “closure” variables like ES5? NO!
class is NOT a function and variables inside are not local variables. In fact, balance=10000 has become a class level static field. It’s NOT in some closure.

Oh ok, SO? Even if it’s part of the class object, should I be able to acccess it? Yes and No.
class object itself is not part of eich object’s prototype chain (topic for another blog?), so it wont show up. Even if it did, there would be just one balance field for ALL objects. Hey, it would be nice to share such Account implementation with some billionaire – YOUR balance is now MINE! πŸ™‚

Ok ok, so how do we create “private” variables in ES6? Unfortunately, there is no direct way!
But we can store data in closure variables, just like ES5, though it would have to be outside the class.

/*
 * ES6 has a class keyword
 * But internally there are no classes
 */

// Local variable to module
let balance = 0;

// Using ES6 syntax
class Account {

    // Instead of function Account(...)
    constructor(id, name, bal) {

        // Public "fields"
        this.id = id;
        this.name = name;

        // Closure variable
        balance = bal;
    }

    // Member function
    print() {
        console.log(
            `ID: ${this.id}`,
            `Name: ${this.name}`,
            `Balance: ${balance}`
        )
    }
}

let eich = new Account(1, "Brendan", 10000);
eich.print(); // Should print 10000

let ray = new Account(2, "Romano", 20000);
ray.print(); // Should print 20000

eich.print(); // ?
And here is the output
ID: 1 Name: Brendan Balance: 10000
ID: 2 Name: Romano Balance: 20000
ID: 1 Name: Brendan Balance: 20000

Oops.. eich seems to be using ray’s balance!
Well, that’s because there is only ONE closure variable called balance, so whoever sets it last.. wins!

Fixing it.. with Map!!
/*
 * ES6 has a class keyword
 * But internally there are no classes
 */

// Local variable to module
let balances = new Map();

// Using ES6 syntax
class Account {

    // Instead of function Account(...)
    constructor(id, name, bal) {

        // Public "fields"
        this.id = id;
        this.name = name;

        // Closure map
        // each object (this) has its own balance
        balances.set(this, bal);
    }

    // Member function
    print() {
        console.log(
            `ID: ${this.id}`,
            `Name: ${this.name}`,
            `Balance: ${balances.get(this)}`
        )
    }
}

let eich = new Account(1, "Brendan", 10000);
eich.print(); // Should print 10000

let ray = new Account(2, "Romano", 20000);
ray.print(); // Should print 20000

eich.print(); // Should print 10000
ID: 1 Name: Brendan Balance: 10000
ID: 2 Name: Romano Balance: 20000
ID: 1 Name: Brendan Balance: 10000

There is however ONE problem… balances map will live on forever (technically until the process end). That’s because even after eich and ray objects are long gone, balances map keeps waiting that someday they will return and ask for their balance, but they are dead and long gone!

Hmm.. so what do we do? How can we ensure that if an object dies, it’s balance is also released?

WeakMap!!!

A WeakMap is a Map which does hold reference to other objects, but when it realises that it’s the only one holding on to that reference, it releases it. Problem SOLVED!

/*
 * ES6 has a class keyword
 * But internally there are no classes
 */

// Local variable to module
// WeakMap releases reference
// If it's the only one holding it
let balances = new WeakMap();

// Using ES6 syntax
class Account {

    // Instead of function Account(...)
    constructor(id, name, bal) {

        // Public "fields"
        this.id = id;
        this.name = name;

        // Closure map
        balances.set(this, bal);
    }

    // Member function
    print() {
        console.log(
            `ID: ${this.id}`,
            `Name: ${this.name}`,
            `Balance: ${balances.get(this)}`
        )
    }
}

let eich = new Account(1, "Brendan", 10000);
eich.print(); // Should print 10000

let ray = new Account(2, "Romano", 20000);
ray.print(); // Should print 20000

eich.print(); // Should print 10000

There! It’s done. We have implemented private fields in JavaScript ES6 with help of WeakMaps. Callers cannot access balance, as balance is not a “field” inside the object (ALL object properties are accessible, yes, even if you create them as Symbol, but balance being a closure variable, it’s accessible only within the class which has captured it.

Complete code with all fields as private
/*
 * ES6 has a class keyword
 * But internally there are no classes
 */

// Local variable to module
// WeakMap releases reference
// If it's the only one holding it
let _private = new WeakMap();

// Using ES6 syntax
class Account {

    // Instead of function Account(...)
    constructor(id, name, balance) {

        // Let's create an internal object 
        let _fields = {
            _id: id,
            _name: name,
            _balance: balance
        };

        // Now add it to closure variable
        _private.set(this, _fields);
    }

    // Nice lil touch... getters
    get id() {
        return _private.get(this)._id;
    };

    get name() {
        return _private.get(this)._name;
    };

    get balance() {
        return _private.get(this)._balance;
    }

    set balance(value) {
        throw 'balance is private';
    }

    // Account operations
    withdraw(amount) {
        
        // Modify our private field
        _private.get(this)._balance -= amount;
    }

    deposit(amount) {
        
        // _balance is in closure WeakMap
        // Not accessible from outside
        _private.get(this)._balance += amount;
    }

    // Member function
    print() {

        console.log(
            `ID: ${this.id}`,
            `Name: ${this.name}`,
            `Balance: ${this.balance}`
        )
    }
}

let eich = new Account(1, "Brendan", 10000);
eich.print(); // Should print 10000

let ray = new Account(2, "Romano", 20000);
ray.print(); // Should print 20000

// We can "access" balance thru getters
console.log(eich.id, eich.name, eich.balance);

// Cannot set balance though
eich.balance = 50000;      
console.log(eich.balance);
And here is the output
ID: 1 Name: Brendan Balance: 10000
ID: 2 Name: Romano Balance: 20000
1 Brendan 10000

throw 'balance is private';
^
balance is private

Yay! We have created “private” fields in ES6 class, but how about private functions?

Well, we can store functions also in the _fields object, but that would be wasteful because it will store a copy of the function in EACH object. The SAME function in EVERY object?

There has to be a more efficient way… If you have ideas about that, write them in comment

Private in JavaScript Series

Private in JavaScript ES5 (Part 1)

Did you know that private, protected and public are reserved words in JavaScript?
Really.. I mean it!!

Take a look at this MDN page – Reserved Identifiers.
Oh Wow! It means I can create private, protected fields and methods in JavaScript? Sadly NO!
These have been reserved since ages but JavaScript hasn’t used them.

Oh! So how do I create private field in JavaScript?
The answer is – It Depends!

Depends on what?
Depends on which version of ECMAScript you are writing code in.

Let's first understand why everything is public in JavaScript

JavaScript does NOT have classes (yea, yea.. that class keyword is just sugar coating)
JavaScript is a “prototype” object oriented language, which means there are ONLY objects.

Watch this DigitalCV video to find out How JavaScript Dictionaries look like

JavaScript Process Map and Dictionaries


And guess what these objects are? DICTIONARIES! That too with all members being visible, though you can change some properties to be non-enumerable, but it doesn’t really hide them.

So how do we hide properties of an object?

Even Object is made up of properties (keys in its dictionary)
Every property is again a dictionary (called Descriptors)

There are 4 descriptors

DescriptorDescription
valuevalue of the property
writable if false, the property is readonly
enumerableif false, the property does not show up in for..in or console.log
configurableif false, writable and enumerable can no longer be changed
Property Descriptors
Let's try hiding by property descriptor
/*
 * We are using old style for creating objects
 * Actually the "true" style as there is no class in JS
 */
function Person(id, name) {

    // Property descriptor for id property
    const idPropertyDescriptor = {
        value: id,
        writable: true,
        enumerable: false
    };
    Object.defineProperty(this, 
        "id", 
        idPropertyDescriptor
    );
    
    // Property descriptor for name property
    const namePropertyDescriptor = {
        value: name,
        writable: false,
        enumerable: true
    };
    Object.defineProperty(this, 
        "name", 
         namePropertyDescriptor
    );
}

// Let's create an object of type Person
let eich = new Person(1, "Brendan");

// id is enumerable false, hence won't show up
console.log('Printing entire object');
console.table(eich);

// But id exists and CAN be changed and printed
eich.id = 7;

// However, name is read-only... wont change
console.log('Trying to change name to Eich')
eich.name = "Eich";

// So id is not really private, just hidden
console.log('Printing properties by name')
console.log(`id=${eich.id}, name=${eich.name}`);

And.. here is the output!
Printing entire object
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ (index) β”‚  Values   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  name   β”‚ 'Brendan' β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Trying to change name to Eich

Printing properties by name
id=7, name=Brendan

Nope! Enumeration does not really make the property private, it merely “tries” to hide it, and that too is not very successfully because if you know the name, you can not only print it but even modify it.

We failed! πŸ˜”

Closures to the rescue

Huh? What is a closure?
When a function can “capture” (or close over) variables from outer functions, it creates a “closure” scope.

/*
 * Function is a way of creating objects in JS
 * Think of Account() as cosntructor
 */
function Account(id, name, bal) {

    // properties of the object
    this.id = id;
    this.name = name;

    // This is NOT a property
    // Local variable to Account
    let balance = bal;

    this.deposit = function(amount) {
        // deposit "closes over" balance 
        balance += amount;
    }

    this.withdraw = function(amount) {
        // balance is NOT a property
        // but local variable of outer function
        balance -= amount;
    }

    this.print = function print() {
        console.log(`ID=${this.id}, 
                     Name=${this.name}, 
                     Balance=${balance}`);
    }
};

Now lets runs this code
var eich = new Account(1, "Brendan", 10000.00);
eich.print();
eich.deposit(1000);
eich.print();
eich.withdraw(500);
eich.print();
And here is the output
ID=1, Name=Brendan, Balance=10000
ID=1, Name=Brendan, Balance=11000
ID=1, Name=Brendan, Balance=10500

Wait a minute… balance is behaving just like a field. We can update it, print it and YET it’s NOT a property of the object. So where is it?

The answer is – “It’s NOT inside the object dictionary but has been put in a different dictionary called “closure”, which is available to deposit and withdraw functions when they are called.

Sweet! So it it hidden from us? Like a private field? YES!

console.log(eich);
Account {
  id: 1,
  name: 'Brendan',
  deposit: [Function (anonymous)],
  withdraw: [Function (anonymous)],
  print: [Function: print]
}

YESS!! We have managed to “hide” balance and made it a “private” field of Account class.
But wait a minute.. what if we directly access it, like…

console.log(eich.id, eich.name, eich.balance);

Out of luck! It’s NOT inside the object, so we CANNOT access it at all. Only when the functions deposit and withdraw are called, they can “see” it in the closure dictionary

1 Brendan undefined
So, is this the way we create private methods too?

Absolutely! Just like local variables of outer function, even local functions are “captured” by closures.

Creating "private" functions
function Account(id, name, bal) {

    // properties of the object
    this.id = id;
    this.name = name;

    // Local variable to Account
    let balance = bal;

    // NOT part of the object
    // Local function (like private)
    // Cannot be called from outside
    function sendSMS() {
        console.log(`Sent SMS: Updated balance={balance}`);
    }

    this.deposit = function (amount) {
        // deposit "closes over" balance 
        balance += amount;

        // Can call local function
        sendSMS();
    }

    this.withdraw = function(amount) {
        // balance is NOT a property
        // but local variable of outer function
        balance -= amount;

        // Can call local function
        sendSMS();
    }

    this.print = function print() {
        console.log(`ID=${this.id}, 
                     Name=${this.name},
                     Balance=${balance}`);
    }    
};
Let's call it from outside
let eich = new Account(1, "Brendan", 10000.00);
eich.print();
eich.deposit(1000);
eich.print();
eich.withdraw(500);
eich.print();

// Try to sendSMS from outside the object
eich.sendSMS();

Nope! Does not work
ID=1, Name=Brendan, Balance=10000
Sent SMS: Updated balance=11000
ID=1, Name=Brendan, Balance=11000
Sent SMS: Updated balance=10500
ID=1, Name=Brendan, Balance=10500

eich.sendSMS();
     ^
TypeError: eich.sendSMS is not a function

Wonderful! We have managed to create private fields and functions using ES5 syntax!

Wait… what about ES6? class syntax?
Wait for the next blog post πŸ™‚

Private fields in JavaScript Series

Switch is EVIL! (Part 3b)

Its only fair that we did deworming of switch-case/if-else ladder from Java code, we should have equivalent C# code. But let’s take this opportunity to explore what .NET/C# have to offer in terms of deworming tools… like delegates, lambdas, Func<> and Action<>

Let's look at the beast
using System;
using System.Text;
class Evil
{
string changeCase(string caseType, params string[] words)
{
// Sanitize the input
caseType = caseType.Trim().ToLower();
// Accumulate result in StringBuilder
var result = new StringBuilder();
// We currently support lower and camel case
if (caseType == "lower")
{
// Every word is converted to lower
// And concatenated
foreach (var word in words)
{
result.Append(
word
.Trim()
.ToLower());
}
}
else if (caseType == "camel")
{
// First word is lower
result.Append(
words[0]
.Trim()
.ToLower()
);
// Subsequent words are Proper case
for (var offset = 1;
offset < words.Length;
offset++)
{
// First letter is uppercase
result.Append(
words[offset]
.Substring(0, 1)
.ToUpper());
// Rest of the letters are lowercase
result.Append(
words[offset].
Substring(1).
ToLower());
}
}
return result.ToString();
}
static void Main(string[] args)
{
Evil obj = new Evil();
Console.WriteLine(obj.changeCase("camel", "Two", "Words"));
}
}
view raw NetSwitch.cs hosted with ❤ by GitHub

The story is the same in all programming languages. Developers tend to use switch-case or if-else ladders as we were probably “taught” to use them when we started learning programming. It’s deeply ingrained into our brains, to the extent that we justify it as being simple.
I hear a a lot of people describe use of maps to eliminate switch as “OVER-ENGINEERING”.

So, we can use interface in C# (like we did with Java in Part 3a), but we could use something else this time… maybe delegate, lambda or Func<>

Get ready to Func
/**
* Func, Action and Predicate are generic deleagtes
* Action<int> -> takes one parameter and returns void
* Func<string, int> -> takes one parameter string and returns int
* Predicate<int> -> takes one parameter int and returns bool
*
* using in C# allows us to "typedef" a complex type
*/
using ConverterFunction = System.Func<string[], string>;
view raw TypeDef.cs hosted with ❤ by GitHub
How do we create a map of funcs?
/**
* Maps are called Dictionary in .NET
* We are creating a map between
* string -> "camel"
* Func<> -> camelConverter function
*/
Dictionary<string, ConverterFunction> converters =
new Dictionary<string, ConverterFunction>
{
{"lower", lowerConverter},
{"camel", camelConverter}
};
view raw Dictionary.cs hosted with ❤ by GitHub
We are set.. onward to refactoring
/**
* changeCase now uses converter Dictionary
* If a converter is found, it invokes it
* or else returns null
*/
public string changeCase(string caseType, params string[] words)
{
// Sanitize the input
caseType = caseType.Trim().ToLower();
// Lookup the converter function in dictonary
ConverterFunction converter;
converters.TryGetValue(caseType, out converter);
if (converter !=null)
return converter(words);
return null;
}
Now it's just a matter of creating converters
static string camelConverter(string[] words) {
var result = new StringBuilder();
// First word is lower
result.Append(
words[0]
.Trim()
.ToLower()
);
// Subsequent words are Proper case
for (var offset = 1;
offset < words.Length;
offset++)
{
// First letter is uppercase
result.Append(
words[offset]
.Substring(0, 1)
.ToUpper());
// Rest of the letters are lowercase
result.Append(
words[offset].
Substring(1).
ToLower());
}
return result.ToString();
}
static string lowerConverter(params string[] words) {
// Accumulate result in StringBuilder
var result = new StringBuilder();
// Every word is converted to lower
// And concatenated
foreach (var word in words)
{
result.Append(
word
.Trim()
.ToLower());
}
return result.ToString();
}
view raw Converters.cs hosted with ❤ by GitHub
It's all over... not!

In all the examples we have seen (JavaScript, Java and in this C# code), we have only used converter that are pre-defined. Which makes it difficult to add new converters at runtime. This means our code will have to be modified to include more converters. So what’s the use of eliminating switch-case if we still have to :manually” add the converter to the dictionary? Good point!

Let’s make our code flexible, so that apart from built in converters, we can add more converters at runtime WITHOUT having to modify our existing code.

It’s easy! Add two methods to our class which can add/remove converters.

Dynamism to the max!

Let’s first add a method to our Converter class, which will add more entries to the dictionary

/**
* Dynamically adding more converters
*/
public void AddConverter(string caseType, ConverterFunction func)
{
// That's it!
converters[caseType] = func;
}
Flexible client class
/**
* Client class can add a new converter
* either defined by itself or from some other source
*/
class ClientClass
{
// Snake case is very polular
// Where else? Python πŸ™‚
static string snakeConverter(params string[] words)
{
// snake_case_is_separated_by_underscore
var result = new StringBuilder();
// Convert each word to lower
// and separate using underscore
for (var offset = 0;
offset < words.Length1;
offset++)
{
result.Append(
words[offset]
.Trim()
.ToLower()
);
result.Append("_");
}
// Add the last word without _
result.Append(
words[words.Length 1]
.Trim()
.ToLower()
);
return result.ToString();
}
static void Main(string[] args)
{
var obj = new Angel();
// Add our own converter and call it
// No need to modify the coverter class
obj.AddConverter("snake", snakeConverter);
Console.WriteLine(obj.changeCase("snake", "Two", "Words"));
}
}

That’s it! We have created a Case Converter class which has a few built-in converters, like lower and camel, but we have also made it extensible, so that others can provide “plugins” for our class. third-party developers could come up with their own converters which the client can use plugin and call.

Here is the final code
using System;
using System.Collections.Generic;
using System.Text;
using ConverterFunction = System.Func<string[], string>;
class Angel
{
static string camelConverter(string[] words)
{
var result = new StringBuilder();
// First word is lower
result.Append(
words[0]
.Trim()
.ToLower()
);
// Subsequent words are Proper case
for (var offset = 1;
offset < words.Length;
offset++)
{
// First letter is uppercase
result.Append(
words[offset]
.Substring(0, 1)
.ToUpper());
// Rest of the letters are lowercase
result.Append(
words[offset].
Substring(1).
ToLower());
}
return result.ToString();
}
static string lowerConverter(params string[] words)
{
// Accumulate result in StringBuilder
var result = new StringBuilder();
// Every word is converted to lower
// And concatenated
foreach (var word in words)
{
result.Append(
word
.Trim()
.ToLower());
}
return result.ToString();
}
Dictionary<string, ConverterFunction> converters =
new Dictionary<string, ConverterFunction>
{
{"lower", lowerConverter},
{"camel", camelConverter}
};
public string changeCase(string caseType, params string[] words)
{
// Sanitize the input
caseType = caseType.Trim().ToLower();
ConverterFunction converter;
converters.TryGetValue(caseType, out converter);
if (converter != null)
return converter(words);
return null;
}
public void AddConverter(string caseType, ConverterFunction func)
{
converters[caseType] = func;
}
}
class ClientClass
{
static string snakeConverter(params string[] words)
{
// snake_case_is_separated_by_underscore
var result = new StringBuilder();
// Convert each word to lower
// and separate using underscore
for (var offset = 0;
offset < words.Length1;
offset++)
{
result.Append(
words[offset]
.Trim()
.ToLower()
);
result.Append("_");
}
// Add the last word without _
result.Append(
words[words.Length 1]
.Trim()
.ToLower()
);
return result.ToString();
}
static void Main(string[] args)
{
var obj = new Angel();
obj.AddConverter("snake", snakeConverter);
Console.WriteLine(obj.changeCase("snake", "Two", "Words"));
}
}

Are you now convinced that ALL switch MUST DIE! ?

Switch is EVIL Series

  1. Switch is EVIL! (Part 1) – Convert it to arrays
  2. Switch is EVIL! (Part 2) – Convert it to maps
  3. Switch is EVIL! (Part 3) – Create function maps
  4. Switch is EVIL! (Part 3a) – Implementing in Java
  5. Switch is EVIL! (Part 3b) – Implementing in C#

Switch is EVIL! (Part 3a)

Why 3a? Why not Part 4? Well, a lot of people have messaged me that I am writing code in JavaScript, which due to its dynamic nature can do such things conveniently, but how about static languages like C++, Java or C#? So this post is basically same as Part 3 but using static languages.

So let's get rolling

switch-case in any language leads to problems, especially modification of existing code, regression testing, not to mention that the code starts to bloat up when more cases are added

Let's look at the beast
class Evil {
public String changeCase(String caseType, Stringwords) {
// We support lower and camel cases
// Sanitize the user input
caseType = caseType
.trim()
.toLowerCase();
// Accumulate output in StringBuilder
StringBuilder result = new StringBuilder();
if (caseType.equals("lower")) {
// All words are converted to lower
// And then concatenated
for (String word : words) {
result.append(
word
.trim()
.toLowerCase()
);
}
} else if (caseType.equals("camel")) {
// First word is all lower
result.append(
words[0]
.trim()
.toLowerCase()
);
// Subsequent words are
// first -> upper
// rest -> lower
for (int offset = 1;
offset < words.length;
offset++) {
// First letter is upper
result.append(
words[offset]
.substring(0, 1)
.toUpperCase()
);
// Remaining letters are lower
result.append(
words[offset]
.substring(1)
.toLowerCase()
);
}
}
return result.toString();
}
public static void main(String[] args) {
Evil obj = new Evil();
String output = obj.changeCase("lower", "This", "Word");
System.out.println(output);
}
}
view raw SwitchCase.java hosted with ❤ by GitHub

Implementing function maps in Java and C# are nearly as easy as JavaScript. The simplest way is to use delegates in C#. Other ways include Action<>, Func<> and Predicate<>. Java too has Function<>, Consumer<> and Predicate<>. Everything else failing, we can still fall back to Interfaces (or abstract classes in languages like C++).

We will use the simplest of ways here.. interface
/**
* interface specifies just one method
* which converts the case and returns back
*
* Various converters will implement this
*. lower, camel, proper, snake etc
*/
interface CaseConverter {
String convert(Stringwords);
}

Now let’s refactor our application. We will cleave out code from individual if-else blocks and make them separate interface implementations. These implementation can be written in separate files, independent of other converters and make the unit testing much simpler

lower CaseConverter
/**
* LowerConverter implements CaseConverter
* and converts all words to lower case
*/
class LowerConverter implements CaseConverter {
@Override
public String convert(Stringwords) {
// Accumulate result in StringBuilder
StringBuilder result = new StringBuilder();
// All words are converter to lower
// And then concatenated
for (String word : words) {
result.append(
word
.trim()
.toLowerCase());
}
return result.toString();
}
}

Now we are focussing on ONE case at a time, which leads to better unit testing and no modification is required in a HUGE switch-case of if-else ladder

camel CaseConverter
/**
* CamelConverter makes
* first word all lower
* subsequent words firt letter upper, rest lower
* "TWO", "WORDS" -> "twoWords"
*/
class CamelConverter implements CaseConverter {
@Override
public String convert(Stringwords) {
// Accumulate result in StringBuilder
StringBuilder result = new StringBuilder();
// First word is all lower
result.append(
words[0]
.trim()
.toLowerCase()
);
// Subsequent words are
// first -> upper
// rest -> lower
for (int offset = 1;
offset < words.length;
offset++) {
// First letter is upper
result.append(
words[offset]
.substring(0, 1)
.toUpperCase()
);
// Remaining letters are lower
result.append(
words[offset]
.substring(1)
.toLowerCase());
}
return result.toString();
}
}

We have separated out each case (if block) into separate implementations, so nows it’s time to factor our main CaseConverter code. This is the crux of the whole exercise –
Replace switch-case/if-else ladder with a MAP

Convert EVIL into Angel
/**
* Our EVIL code has turned into an angel
* We now have a small and maintanable code
*/
class Angel {
// Get rid of old switch-case/if-else ladder
// Replace it with a sweet map
HashMap<String, CaseConverter> converters =
(HashMap<String, CaseConverter>)
Map.of(
"lower", new LowerConverter(),
"camel", new CamelConverter()
);
public String changeCase(String caseType, Stringwords) {
// We support lower and camel cases
// Sanitize the user input
caseType = caseType
.trim()
.toLowerCase();
// Lookup which converter the user wants
CaseConverter converter = converters.get(caseType);
if (converter!=null)
return converter.convert(words);
else
return null;
}
public static void main(String[] args) {
Angel obj = new Angel();
String output = obj.changeCase("camel", "This", "Word");
System.out.println(output);
}
}
view raw CaseAngel.java hosted with ❤ by GitHub

So there.. we have eliminated switch-case/if-else ladder from a static language like Java. We can do similar things in C#, C++ and others too.
I have not focussed on optimisation as the idea was to keep the code simple to understand the conversion process, but we can use Function<> or even SAM (Single Abstract Method) implementation, instead of creating ENTIRE class to implement individual converters.
You feedback, correction and improvement suggestions are welcome

Switch is EVIL Series

  1. Switch is EVIL! (Part 1) – Convert it to arrays
  2. Switch is EVIL! (Part 2) – Convert it to maps
  3. Switch is EVIL! (Part 3) – Create function maps
  4. Switch is EVIL! (Part 3a) – Implementing in Java
  5. Switch is EVIL! (Part 3b) – Implementing in C#

Switch is EVIL! (Part 3)

In the last two posts we got rid of switch cases by either converting them to array (simple value-replacement) or maps (disjoint value-replacements). But life is not always so simple, no? What if we have piece of code inside each case statement? Surely that can’t be stuffed in an array (Actually, It can be in a JavaScript array). *Note: I am using JavaScript but trying to keep code such that it can be implemented in any language*

Let's look at this beast of a code

This JavaScript program offers "case conversion" 
of a string or an array of strings. 

changeCase("IoT", "lower"); // iot
changeCase(["MY", "VAR], "camel"); // myVar

How it does is very pathetic - 
An if-else-if ladder, which will quickly 
grow huge with more conversions being added, 
not to mention the bugs that will be created 
when its modified and regression testing required after each modification.
/**
* A function with an if-else-if ladder
* to determine which case conversion is to be done
*/
function changeCase(caseType,words) {
// We support lower and camelCase
// e.g changeCase("lower", "IoT")
// or changeCase("camel", "MY", "VAR")
// Sanitize user input to "lower", "camel" etc.
caseType = caseType.trim().toLowerCase();
// Get ready to convert
let result = "";
// Lower case
if (caseType == "lower") {
// Concatenate each element as lower
for (word of words) {
result += word
.toString()
.trim()
.toLowerCase();
}
} else if (caseType == "camel") {
// first word is lower
result = words[0]
.toString()
.trim()
.toLowerCase();
// Now rest of the words are Proper case
for (let offset = 1;
offset < words.length;
offset++) {
// First letter upper
result += words[offset]
.slice(0, 1)
.toUpperCase();
// Rest all lower
result += words[offset]
.slice(1)
.toLowerCase();
}
}
return result;
}
view raw ifelseladder.js hosted with ❤ by GitHub

What an ugly piece of code (even though it seems well formatted and commented). We have first cousin of switch-case here … if-else-if ladder. Just like switch-case, if-else ladders tend to expand and add more else if’s to existing code. What makes it worse is that it’s not some value replacement which can be understood easily (case 1: result=”Mon”).

Where there is a switch, there WILL be more cases and where there is an else-if, there WILL be more else-if

Sanjay Vyas

What makes such “code” inside cases more worrisome is that during the maintenance phase, new set of developers will modify this code. The new developers are probably junior devs who do not have the awareness of this code. They are like Intern Doctors asked to do surgery on a patient. Guess what will happen most of the time? They will look at the existing code, try to figure out what is being done in other cases and BANG! copy-paste the existing code and then try to change it. That makes it worse

Copy-paste is the fastest way of creating Bugs.

Second fastest way is switch-case or if-else ladder

Sanjay Vyas
Taming the beast

Just like the disjoint set of values for case statement, where we used a map (JavaScript object), we can use a map here between the caseType and actual code. First we need to eliminate the individual if-else statements and separate the case converter code into separate functions.

/**
* Separate functions for each case conversion we support
* lower
* camel
* … more will be added in future
*/
function convertToLower(words)
{
let result = "";
// Concatenate each element as lower
for (word of words) {
result += word
.toString()
.trim()
.toLowerCase();
}
return result;
}
function convertToCamel(words) {
let result = "";
// first word is lower
result = words[0]
.toString()
.trim()
.toLowerCase();
// Now rest of the words are Proper case
for (let offset = 1;
offset < words.length;
offset++) {
// First letter upper
result += words[offset]
.slice(0, 1)
.toUpperCase();
// Rest all lower
result += words[offset]
.slice(1)
.toLowerCase();
}
return result;
}
view raw Convertors.js hosted with ❤ by GitHub
Now let's write the changeCase again
/**
* Our main function has simplied a lot
*/
function changeCase(word, caseType) {
// We create a map of caseType -> function
const caseMap = {
"lower": convertToLower,
"camel": convertToCamel
}
// Look up the caseType "lower", "camel"
// The map will return its function, call it
caseType = caseType.trim().toLowerCase();
var conversionFunction = caseMap[caseType];
// Do we have this conversion function?
if ( conversionFunction != null )
return conversionFunction(word);
else
return null;
}
view raw ChangeCase.js hosted with ❤ by GitHub

Wow! This looks so cool and maintainable. If we have another case conversion types, all we have to do is write that function and “plug” it into the map. So let’s do it.

Adding a new case converter 'Proper'
/**
* Adding a new case converter called Proper case
* Proper case is also called Pascal case
* Where every word begins with an upper case
* All the remaiing letters of the words are lower
*/
function convertToProper(words) {
// Proper case is also called PascalCase
// Every word starts with an upper letter
// All the remaining letters are lower
let result = "";
// Go thru every word
for (word of words) {
// First letter is upper
result += word
.slice(0, 1)
.toUpperCase();
// Rest all are lower
result += word
.slice(1)
.toLowerCase();
}
}
return result;
}
view raw ProperCase.js hosted with ❤ by GitHub

We are almost done. We have added a NEW function and not tried to modify existing code in a huge switch-case/if-else-if. In fact, the new set of developers don’t even have to look at the existing UGLY code. True, they can still create bugs in their code but guess what… we won’t have to do regression testing on our existing code. If there are bugs found in testing, they can ONLY be in the new code that the new devs have written. Well, they are kids… we can go easy of them and help them. But at least they are NOT creating chaos in our existing code.

So, what happens to our main function now? It’s so easy.. all we have to do is update our map with this new functionality.

Adding new functionality is a breeze now
**
* Adding new functionality does not require modify "code"
* We can simply update our map with new case converter
*/
function changeCase(word, caseType) {
const caseMap = {
"lower": convertToLower,
"camel": convertToCamel,
"proper": convertToProper
}
// Convert switch case to map(string, function)
caseType = caseType.trim().toLowerCase();
var conversion = caseMap[caseType];
// Make sure we got the conversion function
return conversion? caseMap[caseType](word) : null;
}
view raw UpdateMap.js hosted with ❤ by GitHub

Hey! That was easy, right? Once we understand what causes frequent modification to our code (duh! switch-case and if-else), we can refactor our application to become array or map driven. Regression testing is passe and new devs cannot create chaos in existing code. Life becomes so simple, no?

You may ask.. all this is easy because its JavaScript. How about languages like Java, C# or C++ (brr!). How do we implement these there? Well! The concept remains the same but the language may offer varying support. For example, in other languages, we can create map of string and function pointer.

In C++ we can create
map<string, string (*converter)(list<string> word)>

In C# we can create
Dictionary<string, Func<string, string>>(params string word);

In Java we can create
HashMap<string, ConverterInterface>(String[] word);

So the point is… In ALL languages, the switch MUST DIE!

Well, this is not the end of it. I don’t like the idea of even modifying the changeCase function to insert “proper” into the map. Even THAT is “modifying” the code.

True maintainable code should be when we can add new case converters WITHOUT even looking as changeCase or other conversion functions. You think you can do that? Let me know!

Stay tuned for more Switchzilla (Switch Killer) πŸ‘

Switch is EVIL series

  1. Switch is EVIL! (Part 1) – Convert it to arrays
  2. Switch is EVIL! (Part 2) – Convert it to maps
  3. Switch is EVIL! (Part 3) – Create function maps
  4. Switch is EVIL! (Part 3a) – Implementing in Java
  5. Switch is EVIL! (Part 3b) – Implementing in C#

Switch is EVIL! (Part 2)

In the last post we talked about evolution of languages and how switch got stuck in OO languages, causing code to be modified, leading to bugs and more regression testing.

It the first part we saw how “value-replacement” switch-cases can easily be converted into arrays but what if we don’t have contiguous range (1 – 7 weekdays, 1 – 12 month names). Let’s consider scenario where we have non-contiguous values for “value-replacement”.

// Get key label for given key code of keyboard
function keyLabel(keyCode) {
switch (keyCode) {
case 33:
name = "{PGUP}";
break;
case 45:
name = "{INS}";
break;
case 121:
name = "{F10}"
}
return name;
}

Unfortunately, we cannot use an array for this as we would have to create a sufficiently large array which will have most elements blank (undefined). That would not only be wasteful but would require extra checks whether the value is missing at a given element or not.

Maps to the rescue
// Convert switch-case to a "lookup map"
function keyName(keyCode) {
// Create a "map" (object in JavaScript)
const keyMap = {
33: "{PGUP}",
45: "{INS}",
121: "{F10}"
};
// Now look up keyCode in map
return keyMap[keyCode];
}
view raw LookupMap.js hosted with ❤ by GitHub

But what if the values can change dynamically? Maybe we want to change the keymap before we run this application next time? Or maybe we want to add new keys to the keymap while the program is running?

Dynamically load the keymap from JSON file (keymap.json)
{
    "33": "{PGUP}",
    "45": "{INS}",
    "121": "{F10}"
}
Update code to use external maps
// Convert switch-case to
// dynamically loadable map
function keyName(keyCode) {
// Load the keymap from a file
const keyMap = require("./keymap.json");
// Now look up keyCode in map
return keyMap[keyCode];
}

Wonderful! Now we have made this code maintainable by eliminating the switch-case and loading keyCode and keyName from an external source like JSON file. It could very well be an AJAX call or retrieval from a database.

Stay tuned for more Switchzilla (Switch Killer) πŸ‘

Switch is EVIL Series

  1. Switch is EVIL! (Part 1) – Convert it to arrays
  2. Switch is EVIL! (Part 2) – Convert it to maps
  3. Switch is EVIL! (Part 3) – Create function maps
  4. Switch is EVIL! (Part 3a) – Implementing in Java
  5. Switch is EVIL! (Part 3b) – Implementing in C#