[ASPeKT] Oriented Programming

I recently had the pleasure of doing a podcast, with Matthew D. Groves, of Cross Cutting Concerns blog. He essentially “wrote the book”, so to speak, on Aspect Oriented Programming. It’s called AOP in .NET, without pumping his tires too much, I will say that his book is pretty great. I just recently finished reading it, and came to the conclusion that Matthew and I are on the same page regarding a lot of Software Development Fundamentals. Specifically, his take on AOP (Aspect Oriented Programming) and the benefits of it. The ability with AOP to factor out common code that crosses all areas of your code base, and encapsulate it so that you have a single point of change, is a very powerful concept. He illustrates concepts like these, and many others in his book. It also gives a nice overview into the different tools available in the AOP world. Even after writing my own AOP library, I was still able to learn a lot from this book. If you’re interested in AOP or Software Development in general, you should definitely check it out.

To follow up with Matthew’s Podcast, featuring me and the library I created called [ASPeKT] (no relation to ASP, I just liked the way it looked). I wanted to write a post that overviews AOP, and some of the benefits of this powerful programming paradigm. I want to talk about [ASPeKT], the benefits and costs of using a simple AOP library. Then detail some of the challenges I faced as I wrote it, as I work to make it more known, and as I continue to make it better.

Why Aspect Oriented Programming?

AOP is a little known, yet very widely used programming paradigm. How can it be little known, yet very widely used, you ask? Mostly because it’s built into a lot of .NET libraries and frameworks that people use every day, but they just don’t know they’re actually using AOP concepts. Interestingly enough, .NET ASP MVC Authentication, uses AOP patterns. Most people just go about programming and using the Authenticate attribute, without knowing they’re actually hoisting a cross-cutting concern up with a more declarative (cleaner) approach, and letting the framework deal with it.  For me, as a skeptic of AOP at the beginning, it was a huge eye opener to realize that these concepts are actually applied all over in the .NET world. We just don’t realize it. This also brings to light, the power of being able to spot cross-cutting concerns, and be able to encapsulate them, using a library like [ASPeKT]. Thus, removing the need for clunky boilerplate code, and copy-pasta patterns that live in documentation, or worse yet only the minds of your more senior developers.

What is Aspect Oriented Programming, really?

In order to really understand what AOP is, we have to first understand what a “cross-cutting concern” (CCC) is. A CCC is, is the fundamental problem AOP looks to solve. These CCCs typically tend to be the non-functional requirements of your application. They’re code, that spreads across your code base, but they’re not easily factored into their own units. The canonical CCC is logging or auditing. Your application can function, business wise, without it. Yet, if you were to implement the need for “logging” across your application, you would end up with logging code, that pollutes your actual business logic. Things like logging the entry and exit of functions. You end up with code like this.

class Foo 
{
    public void Bar() 
    {
        Console.WriteLine("Entered Bar");
        Console.WriteLine("Pour a drink.");
        Console.WriteLine("Exiting Bar");
    }
};

You can see how this can get tedious, you end up having ‘rules’ or ‘patterns’ that define how and what you log. “This is how we log entry into a function, with it’s parameters. ‘Entering Function – Function. The format lives in a document, stored in SharePoint.” Now imagine when one day that needs to change, and you’re forced to update the 43 million different log lines across your application. Welcome to Hell. Talk about why they call these things ‘concerns’.

Logging isn’t the only concern that spreads and tangles across your code. Things like Authorization, what I call function ‘contracts’ or defensive programming, threading, and many other patterns. These patterns are often overlooked as cross-cutting and don’t always speak to boilerplate, but with a keen eye and some creativity can be teased out into their own re-usable aspects.

Using an AOP tool, allows you to hoist this boilerplate code into its own encapsulated class, where it belongs. Then it allows you to place it declaratively, which makes the code read more explicitly. But also, removes the clutter from the actual business logic of the function. These tools make it so you don’t have to weed through the logging, defensive programming, authorization, etc. Just to find out what the actual intention of the function is. You’ll end up writing code more akin to this.

class LoggedAttribute : Aspect 
{
    public override void OnEntry(MethodArgs args)
    {
        Console.WriteLine($"Entering {args.MethodName}");
    }
    public override void OnExit(MethodArgs args)
    {
        Console.WriteLine($"Exiting {args.MethodName}");
    }
};

class Foo
{
     [Logged]
     public void Bar()
     {
          Console.WriteLine("Pour a drink.");
     }
};

This code effectively functions the same as above. However,  it is substantially cleaner, and the biggest benefit is the ease of change. Now, if I’ve used the LoggedAttribute across my code base and I want to make a change. I only need to make the change in one spot, as opposed to everywhere we copied and pasted the logging lines. AOP allows you to offload the tedious boilerplate code, on the machine. Who is much, much, much faster at typing than humans. The machine also, never makes a typo.

Now that you know what a cross-cutting concern is, I can explain AOP. Effectively AOP is a tool, set of tools, or a paradigm to deal with cross-cutting concerns. In order to prescribe to an AOP model, you need the following 3 things.

  1. A Join Point – this is the point at which our AOP model allows us to interject code. In the case of [ASPeKT], the join-points are method boundaries. i.e. Entering / Exiting of a function. Other libraries like Castle DynamicProxy, and PostSharp allow for actual method interception, so you can say the join-point is this instead of that. This can be useful for things like error handling, retry logic, or threading models.
  2. A Point Cut – this is the way in which you specify, where you want to apply code to the Join Points. Think of this as a sentence describing where you want the code to run. I know my Join Point is Entry/Exit of function. My Point Cut could be “every function that starts with My”, or simply, “every function in the application”. [ASPeKT] uses attribute placement as the Point Cut definition. So where you place the attribute, determines how it will apply the code to the Join Points.
  3. Advice – essentially, the code you want to run at the Join Points. So for [ASPeKT], this is the code you write in OnEntry / OnExit / OnException.

Given these three things, you can start to encapsulate the CCC, which then allows you to start applying that code to other code. You don’t need to copy-pasta, you don’t need to find the document that says how to do logging or auditing. You just apply logging, you apply auditing. It becomes very powerful, because these concerns are now tools in your development toolkit. They’re easily tweaked, they’re modifiable without the daunting overhead of find and replace in every file in the solution. Now, they make sense.

So hopefully now you see the benefit of AOP, and can maybe start to see places where AOP could benefit your projects or workplace. I’ll be honest, it’s not always the easiest sell. So if you’re interested and you want more information, please feel free to reach out. I love talking about these kinds of things.

[ASPeKT] In a Nutshell

My first real intriguing look at AOP, was as I was reading the book Adaptive Code via C# — Gary Maclean Hall. He gave a brief introduction into AOP, mostly to describe its use with logging. Which at the time, I laughed and thought, ‘there’s really no other use than logging’. Later on in the book, he describes a pattern to reduce dependencies on lower layer APIs, by translating API level exceptions into higher level exceptions. This is so higher level components can make decisions based on the exceptions, without being explicitly tied to the lower level library. Consider the use of a library that is encapsulating sending data to a webserver for storage. Something like Office 365 Drive.

You might have code like this.

// MyStorage.dll - our internal wrappers, depends on OfficeWebDrive.dll
interface IStorage 
{
      public void Store(string name, Stream stream);
}


class OfficeDrive : IStorage
{
    public void Store(string name, Stream stream)
    {
         // use OfficeWebDrive.dll third party library
         // make requests to store data,
         // can throw "OfficeWebDrive.StorageFullException"
    }
};
// Application.exe - depends on MyStorage.dll, 
// but should have no dependency on OfficeWebDrive.dll

class Book 
{
    public void AddText(string text)
    {
        // Code to append text.
    }

    public void Save() 
    {
        storage_.Store(Title, Data);
    }
   
    Stream Data { get; }
    string Title { get; }
};

class Application 
{
    public void SomethingHere()
    {
         try
         {
             Book book = new Book("AOP in .NET");
             book.AddText("Lorem Ipsum");
             book.Save();
         }
         catch(OfficeWebDrive.StorageFullException e)
         {
               // Deal with the StorageFullException
         }
    }
};

As you can see, we’ve done our best to program to an interface, using the IStorage interface. Our application should have no dependencies on the actual underlying storage libraries. Except that because we need to deal with the StorageFullException, we need to now explicitly make a dependency between our application and the lower level third party API.

The sentiment then, from Adaptive code, is to wrap the 3rd party library calls, and translate the exception. Like so.

class OfficeDrive : IStorage
{
    public void Store(string name, Stream stream)
    {
        try 
        {
            // use OfficeWebDrive.dll third party library
            // make requests to store data,
            // can throw "OfficeWebDrive.StorageFullException"
        }
        catch(OfficeWebDrive.StorageFullException e)
        {
             // translate the error
             throw new MyStorage.StorageFullException(e.Message);
        }
    }
};

Now, the higher level code can make the same decisions about what to do when the storage is full, but no dependencies on the low level libraries. If we wanted, we could completely change the underlying storage mechanism. Without needing the Application to rebuild.

‘Hey Gary, this is a great spot for AOP’ I thought being clever.

class OfficeDrive : IStorage
{
    [TranslateException(typeof(OfficeWebDrive.StorageFullException), 
     typeof(MyStorage.StorageFullException))]
    public void Store(string name, Stream stream)
    {
        // use OfficeWebDrive.dll third party library
        // make requests to store data,
        // can throw "OfficeWebDrive.StorageFullException"
    }
};

Now, we let the AOP framework handle the boilerplate try/catch code. This also really calls out what is happening, and why.

Where does [ASPeKT] come in?

Well — after I thought about this, I wanted to build it. I guess I could’ve easily used the PostSharp Express version and whipped it out really quickly. But that’s not me. If I’m going to understand something, I’m going to understand it. So I set off to write a small AOP library, where I could solve this problem. It was a rather simple concept, or so I thought.

I didn’t even really know what an AOP library did. That’s where the research started, “open source AOP libraries”, “how does PostSharp work”, etc, etc. Just some of the multitude of search terms I used while I did research into how to build an AOP library.

I had the concept of what I wanted. I wanted something that I could declare an attribute, that would translate an exception. Easy.

Let’s go down the rabbit hole.

At it’s core, AOP is actually allowing a machine to write code for you. You’ve moved the copy and paste from your fingers Ctrl+C / Ctrl-V to the machines apt fingers. Allowing the computer to ‘weave’ the code for you.  You define the boilerplate as an aspect, and you let the machine do the work for you, because that’s what they’re good at (no offense computer).

You’ve got three options for when this can happen.

  1. In the source code, before you compile. Using some type of marked up code in your source, you could run a pre-compiler that will insert code snippets into the source. Before the compiler does it’s work.
  2. After the compiler — though not impossible on native assemblies. It is far easier on languages like C# and Java, which use an intermediate language, between source code and assembly. We can post-process the compiled intermediate language (IL), to apply the code we want.
  3. At runtime. Well this has somewhat of an over-watch pattern, where something is watching the calls as they run through and interpreting whether or not to run our aspects.

Now — knowing this, which one do you choose? My thought process was as follows.

  1. Option 1: Modify the source — I don’t want to write a compiler. Well, I do, but not for this. So that was off the table, at least for now. You also have dependency on language syntax, not that I would expect much of C# syntax to change, but still.
  2. Option 3: At runtime – I don’t want this. I come from a native background, specifically C++. I don’t want to pay overhead where I don’t have to. I didn’t want to have something that is monitoring functions as they run, or building code at runtime. Just wasn’t what I wanted.

So that left option 2, what exactly is that? How does it even work?  I need something that will run, after the binary compiles, and modify it to add in the CCC code.

Let’s go deeper…

To understand post compile weaving, we must first understand how the .NET runtime operates, at a high level. The .NET Runtime is what’s called a “virtual machine”. The draw towards these “virtual machines”, was started with JAVA created by Sun Microsystems. The large benefit to JAVA, was that it was a compile once, run anywhere language. This was hugely powerful, when you consider the alternative of compiling for every architecture, as is the case with C and C++.  The virtual machine, allows you to compile to a well known set of instructions (IL), which then will output machine specific instructions for the hardware when run through the virtual machine. This way, you only need to write a virtual machine for the hardware, and you open yourself up to all the applications available for that runtime. This is one of the reasons JAVA became so hugely popular, because you could write a JVM for your VCR and all of a sudden pow smart VCR, with lots of apps available.

Obviously, Microsoft saw the benefit and flexibility in this and took advantage, so they started shipping JAVA in Visual Studio. They had their own JVM, and JAVA compiler as well. They also saw an advantage to extend this language, for the Windows operating system. Enter J++, Microsoft’s implementation of Java with extensions for the Windows OS. With J++, came a lawsuit from Sun Microsystems. Microsoft had a non-compliant JVM and they were violating the terms of the license agreement (who reads those things anyways?). Wah. Wah. So what does Microsoft do? They do what any billion dollar software development company would do. They eat the lawsuit, and take J++ and turn into what we now know as C#.  They also see the immense power in this .NET Runtime, and see that they can compile a whole multitude of different languages into IL. With the release of .NET Runtime 1.0, there was support for 26 languages (I think). To be completely honest, I’m glad that Sun sued Microsoft, because I hate JAVA as a language, and I love C#. So it was a win, in my opinion.

Anyways — aside from that little lesson in history, we can understand how ‘weaving’ works in a .NET language. Like I said, C# is a language that compiles to IL, aka CIL or MSIL. An intermediate language, is on the fence. Between a language that is “compiled” to actual assembly (hardware instructions). And an interpreted language like JS, that is completely interpreted at runtime. The C# compiler, takes the C# language and outputs a binary form of instructions that complies to the .NET runtime standard. These instructions are then interpreted, and compiled Just-In-Time to output hardware instructions. This means, that after we compile to IL, and before running, we can insert some extra IL instructions, then voila.

How do you weave IL?

Weaving IL is actually pretty straight forward, if you know what you’re doing. Which I didn’t. Ha. At first, I kind of flew by the seat of my pants. I knew I needed to re-write the IL, and I had heard about tools like Roslyn and Mono.Cecil. Roslyn being a compiler, wasn’t exactly what I wanted. I needed at tool to modify the IL, which is exactly what Mono.Cecil is. It not only uses the built in Reflection.Emit, but also adds a lot of ease to manipulating the IL.

The task at hand for me, was to open the binary, find the spot that I had declared my “TranslateExcepton” and then insert the instructions for that, into the method where I declared.  I just decided to make it generic, to work with any Aspects I created. I will spare the gory details, but the high-level was as follows.

  1. Open the compiled .NET assembly
  2. Find functions decorated with Aspekt.Aspects
  3. Write IL to instantiate the Aspect, and make the entry call
  4. Write IL to wrap the existing code in a try/catch
  5. Execute the existing code
  6. Write IL to make the exit call

I could write an entire post on weaving IL, but not today. If you’re interested in that, please drop me a line and let me know. I can describe, in detail, all the pain I felt while I was learning how to do this.

Once, I had figured out how to do this. I had an executable that I could run against my compiled .NET binaries, which would weave aspect code, where I place attributes. Then all I needed to do was write the aspect, to translate the exception. You can actually find this aspect in the [ASPeKT] code. Kind of like an ode to the beginning, for me.

What came next?

Now that I had the start of this framework. I thought to myself, that I had actually built something that could be useful. “People might actually want to use this”. I had also always wanted to author an open source library. So I started reaching out on Reddit, and making the foundation more easily accessible for people to use. I made the core more stable. Then I started writing new features, like [ASPeKT] Contracts. It was a surprising journey. In the past I had written many throw away libraries, and many small tools that have never seen the light of day. Always just to prove to myself, well, that I could. There was just something to this one, it was a niche library and I thought there was something to it.

I guess the reality is that I’m still in the middle of this journey, with [ASPeKT] core having 588 downloads, and Contracts having slightly less at 416. I’m still working towards my goal of 1000 downloads for each. Realistically, a project that uses [ASPeKT] could be the spark that it needs to ignite. Until then though, I will just keep plugging away and making it cooler and easier to use.

Why should you use [ASPeKT]?

Well — if you’re at all curious in the inner workings of an AOP library, the code is public on my GitHub or you can easily get the package on NuGet. The second, is maybe you have a project that could benefit from AOP? [ASPeKT] is pretty lightweight, and easy to get started with. Though, if you’re looking for a robust, feature complete, production ready library — [ASPeKT] isn’t there yet. If you’re looking for a library to contribute to, or a library that can be adapted into something production ready, then shoot me an email!

“Man cannot discover new oceans unless he has the courage to lose sight of the shore.”
― Andre Gide

As always, thanks for reading. Happy Coding!

PL

Template<T> vs. Generic<T>

The other day I was discussing the differences between C++ templates and C# generics. In my opinion, C++ templates reigns supreme. Not because I’m one of those guys with a “My compiler compiles your compiler.” shirt. But because in general abstractions in C++ tend to ‘cost’ lest than the same abstractions in C#. For instance, the foreach exists in both languages, but the iterator concept is far lighter weight then the IEnumerable concept. Both of these concepts make use of generics to be able to support iterating a collection of “things”.  Having one single ‘concept’, that works across a multitude of different containers, allowing for traversal. The iterator concept is a bit more in-depth, in that it allows for more than forward traversal unlike IEnumerable.

The discussion came down to “why?”, why I thought that the template system in C++ was better than that of C# generics. Why is right. At the time, my statement was rather off the cuff, and somewhat tongue-in-cheek. Granted I had my reasons, but not backed by research. Only backed by my overview knowledge of the operations of the two systems. So now that I’ve had time to mull it over, and solidify my arguments. I’ll explain my point-of-view, grounded in my initial thoughts.

Let me ask you something? When was the last time someone wrote Tetris “in” C# generics? No, I don’t mean “with” C# generics, I mean “in” C# generics.

Spoiler: the answer is never.

Why? Let’s explore reason numero uno, which admittedly wasn’t the first reason to my head at the time. The C++ template system is Turing complete. That’s right, it’s Turing complete. Wait what does that even mean? Well, the definition for Turing complete is along the lines of  “A system of data-manipulation, is said to be Turing complete, when it can simulate a Turing machine.” Thank you Wikipedia for that ever so enlightening statement. Basically, what this means is that the meta-language built into the C++ template system, is actually a full blown programming language. One where if you’re brave enough, or crazy enough, you can even implement Tetris. Remember, that the C++ template engine runs at compile time, so you guessed it — it’s compile time Tetris.

You don’t need to use the template system only for silly things like Tetris. You can also use it for actually useful things as well. Things like specific implementations of your generic algorithms based on traits about a type. Or how about even finding traits about a type?  You can use the template system, to choose different implementations based on the type you’re using, or rather traits about the group of types you’re using. As well as do computations at compile time.

template <int N>
struct sum
{
    static const int value = N + sum<N-1>::value;
};

template<>
struct sum<0>
{
    static const int value = 0;
};

int main()
{
    std::cout << sum<5>::value << "!\n";
}

Figure 1 – A simple example of a summation recursive template meta-program

All of this for “free” at compile time. When I say free, I mean run-time free. The C++ template engine does its work at compile time, and will make heavy use of the type system. Don’t get me wrong, it’s not all roses. If you make heavy heavy heavy use of the template system, you can have really long compile times and even bloat your binaries. I’ve seen code generation times upwards of 30 minutes. The code actually only took about 5 or so minutes to compile, but the code generation was ~30 minutes. Imagine writing all those classes, TGFCPPT (Thank God for CPP Templates).  So at this point, C++ templates have delivered a knock-out punch to C# generics. KO! Generics down for the count. However, I am still going to proceed with examining my initial reasoning, because I like to “beat dead horses” so to speak. I think it can be said that generics are like the template systems little brother. They look similar, but one is about half as useful and twice as fat.

So the second reason, and the first that came to my head (not surprisingly) was overhead. The C++ template system doesn’t have run-time costs, because it’s a compile time operation. Whereas the generic system must have some run-time overhead, just due to its nature.  I wouldn’t say I was stabbing in the dark, but I definitely didn’t have research to back up my claim. I had read about the generics system in a few blogs, I understood how it worked, sort of. Anyways, the claim was contended. Fair enough, I didn’t have the research in my back pocket to prove it. For most, it would’ve ended there. However, on my never ending quest to remove misinformation and search down the truth, I couldn’t let it go. So really, what is the cost of the C# generics vs. the C++ template engine?

First, lets look at how the C++ template engine actually works. To be honest, I couldn’t find all that much real information on how C++ templates work. So I will have to share my understanding, which admittedly is naive, but get’s the point across . When you have some code like the following.

template <typename T>
void print(T value)
{
    std::cout << value;
}

print(5);
print("Hello World");

The compiler will for all intents and purposes, generate two functions for you.

void print(int value)
{
    std::cout << value;
}

void print(const char *value)
{
   std::cout << value;
}

Now, there’s little value in this example. But as you can see, the compiler is basically saving you the keyboard time. The compiler will only generate those functions that are needed, so it doesn’t just go out and create functions for every type. Only the ones that need to be created. Given this happens compile time, by the time you’re running those template definitions are a thing of the past, and you’re running the code that was generated by the compiler. These functions each have their own unique addresses, and their own ability to be optimized.

Now, compare this to how C# generics work. Consider List<T>, you could have instantiation for List<int>, List<string>, even List<Object>. How does this work?

Well, for a minute we can brainstorm a couple of different ways this could be achieved.

  • We could do something similar to the C++ template engine, and for every unique instantiation we could generate IL. Meaning that List<int>, List<string>, and List<object> would each get their own set of instructions.  This could be referred to as code specialization.

Let’s be honest with ourselves, this isn’t a good approach here. It would lead to HUGE binaries, and would be hugely inefficient. Given that C# objects are references, the code would be duplicated for a large portion of instantiations.

  •  We could ignore the type of the target. Effectively erasing it from our implementation. I don’t care if it looks like a duck, or quacks like a duck, it’s a duck. Then we only need to maintain ONE version of the code, and at run-time, we just ignore the type so the List<int>, List<string>, and List<Object> all use the same instructions. They’re just ignorant to the type.

This has issues too, because since we’ve erased the type, we’ve lost that information about the objects. Then we need to do extra work, to make sure that List<Object> != List<string>. As a note, this is the approach JAVA takes to its generics. The benefit to this approach, is that we only have one master set of IL for the implementation. There’s not duplication, like the approach above. It also means, that you need to treat POD types, that are stack based, as heap values.

  • We could use one shared implementation like JAVA, but at the same time use run-time techniques to manage our types. So this way we’re respecting the types of the objects. So List<int>, List<string>, and List<Object> all would use the same code, except there would be some overhead to store the information about the types.

This last approach is the approach that C# takes for their generics. Now, this isn’t exactly 100% true, because I believe that C# generics use a mixture of code specialization, as well as code sharing. Because when we talk about “objects” vs. “primitives”, in C# one is heap allocated and referenced, and the other lives on the stack. Therefore, if you treated something like an int the same as a string, you would need to do what is called “boxing” and allocate that int on the heap. Which is mega overhead and not cheap. So there is a combination of code specialization and code sharing going on.

One of the goals of the design of generics, was that it should be as efficient as code that is hand specialized. Using these two techniques, the implementation is equally as efficient as hand specialized code, and much much more efficient that type erasure. This is due to the boxing thing I mentioned earlier. That’s a lofty goal, and I’ll say an admirable one, taking from the spirit of C++. However! There are definitely other costs that are paid, the cost of memory overhead for storing the vtables, and other RTTI data. Making generics, not exactly free. Clever techniques for loading this information saves execution time, but we still have to pay for the memory used. Contrary to popular belief, memory isn’t always free. Although, at the C# level, it can pretty much be assumed to be. Like C++ code generation, C# generics can also basically explode when being evaluated. In one blog that I read, the author mentions that a single instance of List<T> will explode out into 28 different types, where 5 unique List types could cost upwards of 70K in the working set.

It’s not to say that C# generics don’t have some neat features. Specifically type constraints, and the ability to constrain types to interfaces. This is something that can be done with C++ templates (slightly easier post C++11), but the reality is that it’s not for the faint of heart. The second upside of this, is that the compiler errors you get when you violate a type constraint on a generic, they’re readable by a human. One of the downsides of C++ template usage and definitely of template meta-programming, is that the compile errors are pretty much non-coherent for anyone who isn’t a compiler writer or demigod.

In conclusion, I still think that C++ templates are far superior to C# generics. That said, they both have their benefits and costs. It is like anything, you need to understand the cost of something before you use it, and you should always pick the right tool for the job.

“Price is what you pay. Value is what you get.” — Warren Buffet

As always — keep calm and code on.

Happy Coding!

 

References:

[1] On generics and (some of) the associated overheads 

[2] Design and Implementation of Generics for the .NET Common Language Runtime

[3] Turing Completeness – Wikipedia

 

The Zero Cost Abstraction of Iteration

I’ve been hooked on C++ for about 10 years now. Since CMPUT101, I’ve been attracted to the syntax of the language, the simplicity of use, and later the driving ideals behind the language. C++’s author Bjarne Stroustrup, stands alone when it comes to preaching language ideals and pushing the language forward all while respecting these ideals. This is no easy task, especially when the language is designed by a committee. I’ve always been convinced one of the key reasons C++ is such a large success, and has remained so timeless; is the fundamental guiding principles behind the language. The principle that I believe reigns supreme is the ‘Zero Cost Abstraction’.

What is the ‘Zero Cost Abstraction’? Also called a ‘Zero Overhead Abstraction’. Well — it’s an abstraction, that costs nothing. Not like monetary currency; or a favour. Instead resource or runtime cost. Bjarne’s definition is “an abstraction that imposes no space or time overhead in excess of  what would be imposed by careful hand coding of a particular example of the abstraction.” So in other words, an abstraction that doesn’t use any more resources than if you carefully crafted the assembly yourself.

Well then, what is an ‘abstraction’? Well an abstraction is a concept that you can work with, that ignores the details of operation. A good metaphor for this is a steering wheel on a car. You turn the wheel left and right, to turn left and right, but you’re not concerned with the details of actually moving the wheels of the car on the road. In fact, you don’t want to be concerned with those details at the level of driving.  You want to be more focused on the bigger task at hand — driving the car.

So abstractions in computing allow us to work with concepts, craft algorithms and structure code, so that we don’t have to worry about the details. Programming languages themselves are abstractions, they allow us to work with logical operations, classes, English words, and common symbols to create instructions that cause computer hardware to do things. Languages like C and C++, are considered ‘close to the metal’, this means that they only thinly abstract the assembly that is run on the processor, only thinly abstract the management of memory (either directly to the MMU or through the OS), and only thinly abstract the other pieces of hardware. Languages like C# and JAVA (shudder), are higher level languages, meaning they have many layers between the code and the actual instructions that execute on the CPU. These higher level abstractions give way for more flexibility, but often have a cost. In the case of JAVA, the flexibility of portability, at the cost of run-time and space overhead. Garbage collection adds the flexibility of not having to worry about memory management, at the cost of run-time, and space overhead. Not to mention the cost to developers, as the become brainless in the areas of memory lifetime, and ownership rules.

[Coming Soon – a post on Virtual Machines]

So what does any of this have to do with the ‘Zero Overhead Abstraction’ principle? Well, obviously I have a story to go along with it. So some time ago I was working on my library [ASPeKT] and I was soliciting the help of the internet for advice on how to work better with the IL I was crafting. The comments I got, were, well, unexpected to say the least. The majority of the criticism I received was my use of direct for loops for iteration. As opposed to the cooler C# foreach loop or even better LINQ-to-everything!! Now, I can take critiquing of my code, after all that’s how you learn. So I pondered this for quite some time. I reviewed some of the pull requests which had transformed some of my boring for-loops, into beautifully crafted LINQ queries. I wasn’t buying it. I just couldn’t. It hid some of the intent of what I was trying to do, and call me old school, but I found it harder to read.

Enter foreach, this one I liked. C++11 introduced new semantics for it and I liked the clarity that it gave. When you’re iterating a collection using an indexer, the first thing you do is get the item at the index. The foreach, just abstracts this and your boundary checking in a nice syntax package. Color me smitten. Now, I didn’t actually refactor much in my library to use foreach. Honestly, I like it but I wrote the code already and it worked. However I started using foreach, pretty much everywhere I could, just like I did in C++ now. I know that C# probably had this before, and I obviously adopted it backwards, but I do a lot of shit backwards. So sue me. 

Fast forward a couple of months, I’m reading “Writing High-Performance .NET Code” by Ben Watson. He’s got a little section on loops for iteration. The section I think was on comparing C++ to C# for performance. When we’re talking speed of execution, less instructions is more. The less instructions you have to run, the faster your program will be. The fastest program you can write, is one that does nothing.

There was a snip on comparing a loop in C# to a loop in C++, and the generated ASM instructions. He was making the statement that C# doesn’t ALWAYS have much overhead over a language like C++. He showed how old skool for loop iteration, was virtually the same instructions for C++ and C#. But the foreach, it was something else. I was floored, I had never really thought about it, but at that moment I did. What does a foreach in C# actually do?

His example was something like this

[C++]
int sum2()
{
    int range[4] = { 1, 2 , 3 , 4};
    int sum=0;
    for(auto i=range; i<range+4; ++i)
    {
        sum+=*i;
    }
    return sum;
}

[ASM]
//-O2 Disabled so it wouldn't optimize the loop out
sum2(): # @sum2()
  push rbp
  mov rbp, rsp
  lea rax, [rbp - 16]
  mov rcx, qword ptr [.L_ZZ4sumvE5range]
  mov qword ptr [rbp - 16], rcx
  mov rcx, qword ptr [.L_ZZ4sumvE5range+8]
  mov qword ptr [rbp - 8], rcx
  mov dword ptr [rbp - 20], 0
  mov qword ptr [rbp - 32], rax
.LBB1_1: # =>This Inner Loop Header: Depth=1
  lea rax, [rbp - 16]
  mov rcx, qword ptr [rbp - 32]
  add rax, 16
  cmp rcx, rax
  jae .LBB1_4
  mov rax, qword ptr [rbp - 32]
  mov ecx, dword ptr [rax]
  add ecx, dword ptr [rbp - 20]
  mov dword ptr [rbp - 20], ecx
  mov rax, qword ptr [rbp - 32]
  add rax, 4
  mov qword ptr [rbp - 32], rax
  jmp .LBB1_1
.LBB1_4:
  mov eax, dword ptr [rbp - 20]
  pop rbp
  ret
.L_ZZ3sumvE5range:
  .long 1 # 0x1
  .long 2 # 0x2
  .long 3 # 0x3
  .long 4 # 0x4
[C#]
static class Program
{
     static int sum()
    {
          int[] range = new int[]{ 1, 2 , 3 , 4};
          int sum=0;
          for(var i=0; i<4; ++i)
          {
                 sum+=range[i];
           }
          return sum;
   }

}

[JIT ASM]
Program.sum()
    L0000: push ebp
    L0001: mov ebp, esp
    L0003: push edi
    L0004: push esi
    L0005: mov ecx, 0x717168e2
    L000a: mov edx, 0x4
    L000f: call 0x58f3200
    L0014: lea edi, [eax+0x8]
    L0017: mov esi, 0x251c084c
    L001c: movq xmm0, [esi]
    L0020: movq [edi], xmm0
    L0024: movq xmm0, [esi+0x8]
    L0029: movq [edi+0x8], xmm0
    L002e: xor esi, esi
    L0030: xor edx, edx
    L0032: mov ecx, [eax+0x4]
    L0035: cmp edx, ecx
    L0037: jae L0049
    L0039: add esi, [eax+edx*4+0x8]
    L003d: inc edx
    L003e: cmp edx, 0x4
    L0041: jl L0035
    L0043: mov eax, esi
    L0045: pop esi
    L0046: pop edi
    L0047: pop ebp
    L0048: ret
    L0049: call 0x73a52b10
    L004e: int3

As you can see 25 instructions in C++ vs.  30 instructions for C#. So your standard for loop in C++ and C# are running essentially the same instructions.

The foreach was a different story — he wouldn’t even show the instructions. He only showed the generated IL, and let me tell you, it was a lot.

In my own research, the ASM generator that I used, generated 150+ instructions, which didn’t seem like a lot. However, I did notice is that it didn’t generate ASM for the actually calls to MoveNext(), it just used the syntax ‘call’ MoveNext(). Which likely has a lot more instructions under the hood.

Let’s compare that to the pure C++, range foreach.

[C++]
int sum()
{
    int range[4] = { 1, 2 , 3 , 4};
    int sum=0;
    for(auto i : range)
    {
        sum+=i;
    }
    return sum;
}

[ASM]
sum(): # @sum()
  push rbp
  mov rbp, rsp
  mov rax, qword ptr [.L_ZZ3sumvE5range]
  mov qword ptr [rbp - 16], rax
  mov rax, qword ptr [.L_ZZ3sumvE5range+8]
  mov qword ptr [rbp - 8], rax
  mov dword ptr [rbp - 20], 0
  lea rax, [rbp - 16]
  mov qword ptr [rbp - 32], rax
  mov rax, qword ptr [rbp - 32]
  mov qword ptr [rbp - 40], rax
  mov rax, qword ptr [rbp - 32]
  add rax, 16
  mov qword ptr [rbp - 48], rax
.LBB0_1: # =>This Inner Loop Header: Depth=1
  mov rax, qword ptr [rbp - 40]
  cmp rax, qword ptr [rbp - 48]
  je .LBB0_4
  mov rax, qword ptr [rbp - 40]
  mov ecx, dword ptr [rax]
  mov dword ptr [rbp - 52], ecx
  mov ecx, dword ptr [rbp - 52]
  add ecx, dword ptr [rbp - 20]
  mov dword ptr [rbp - 20], ecx
  mov rax, qword ptr [rbp - 40]
  add rax, 4
  mov qword ptr [rbp - 40], rax
  jmp .LBB0_1
.LBB0_4:
  mov eax, dword ptr [rbp - 20]
  pop rbp
  ret

Hmmm…. 30 instructions. So as you can see, this is an illustration of a ‘Zero Cost Abstraction’. The code has been shrunk by quite a few characters. It becomes easier to read and reads with more intent, yet it doesn’t carry any overhead over the original loop.

So, what’s the development cost of writing your own foreach enumerable collection in C#. Implementing the IEnumerable concept.

Well — first you need to implement the IEnumerable interface, which returns an IEnumerator. The IEnumerator class is really the meat and potatoes. It contains your iteration state and a reference to your collection. You need to implement the MoveNext() call to increment the enumerator, which returns true or false based on whether it incremented. Then you need to implement Reset(), which resets the enumerator. You need to implement the ‘Current’ field to return the current object.

Vs.

What’s the development cost of making something enumerable in C++. Implementing the iterator concept.

You need to implement the iterator concept. Iterator concepts are described here, the minimum you need is the ForwardIterator. Which you need to be able to read and increment with multiple passes. The iterator concept models the pointer, so you need to implement operator++() and operator*(), and operator==(). Like the IEnumerator the iterator is the brains of iterator (fancy that), and contains some reference to the collection as well as iteration state.

In order for your collection to work with C++ foreach, you need to implement a begin() and end() method, which return an iterator.

begin() => returns an iterator to the first object
end() => returns an iterator of one past the last object

It’s as easy as that.

The moral of this story, just because an abstraction makes the code cleaner, doesn’t mean you’re not paying for it, someway. Of course, the flip-side is, if there is careful thought put into the abstraction — you can eat your cake and have it too.

“Small leaks sink big ships” – Benjamin Franklin

Happy Coding!

PL

Ye Olde Double Dispatch; The Invasive Visitor Pattern; and Pattern Matching.

As the title suggests we’re exploring The Ol’ Double Dispatch, Visitor Pattern and Pattern Matching. Given this topic can be language agnostic, I’ll choose C++ for examples. We all know it’s the language of languages. Kind of like Latin. It also gives me a good framework to work with because it’s close to the metal, which hopefully makes things less complicated, and way better than JAVA because, well… JAVA. Need I say more?

I’ll get to the back story, and an architecture choice which leads to a pervasive (invasive) design pattern, but first I’ll start with some history. Practitioners of C, would remember the paradigm of separating function from data, they remember this; because they have no other choice. In C, your tools are functions and structs, so that’s really all you got. Along the way some clever individuals invented something called virtual function dispatching. This allows you to have different function implementations based on the different type of data. This is a little something we like to call ‘polymorphism’ in the Computing world, you’ve probably heard of it. In fact, polymorphism is a fundamental pillar of Object Oriented programming. It is also, a form of what is called ‘single dispatch’.  Whereby you make a single function call and it’s dispatched to the proper implementation based on the data type.

By this point, you’re probably saying “You said you’d talk C++, but now you’re talking about C.” Well it’s important because it illustrates my point, and what would we be without C? Some type of cave person punching holes in cards? Give your head a shake. Anyways, the C++ compiler builds a virtual function table, and ensures that the correct function is called based on the type, all with the nice syntax of C++ to write it. So this example will be C++ syntax, to show virtual single dispatch.

// create a virtual base class
class base
{
public:
    virtual ~base() = default;
    virtual void do_something()
    {
        // do something
    }
};

// override the base class
class derived : public base
{
public:
   virtual void do_something() override
   {
       // do something derived
   }
}; 

int main()
{
     base b;
     derived d;
     base &a = b;
     base &c = d;
     
     // call the correct function, from the base, to the derived
     // base do_something
     a.do_something();

     // derived do_somethng
     c.do_something();
}

So Single Dispatch, virtual function table, and data / function segregation.

Now, there’s a second type of Single Dispatch, but it doesn’t exist in C (the latest C has it apparently), it’s called ‘function overloading’. In C++,  it’s done at compile time. Basically, the compiler picks the right function based on the type passed in. You know.. this.

void foo(int i)
{
    // do foo for int
}

void foo(double d)
{
    // do foo for double
}

int main()
{
   double pi{3.1415};
   int i{0};
   foo(i);
   foo(pi);
}

As I mentioned, this form of dispatching is only at compile time. The compiler has to know the type when selecting the proper overload. So something like this, won’t work.

class ibase
{
public:
    virtual ~ibase() = default;
    virtual void do_something() const = 0;
};

class derived1 : public ibase
{
public:
   virtual void do_something() const override
   {
   };
};

class derived2 : public ibase
{
public:
   virtual void do_something() const override
   {
   }
};

void foo(const derived1 &d)
{
    d.do_something();
}

void foo(const derived2 &d)
{
   d.do_something();
}


int main()
{
   // This won't compile, it's for illustration purpose
   derived1 d1;
   derived2 d2;
   ibase &b1 = d1;
   ibase &b2 = d2;
   foo(b1);
   foo(b2);
}

Now, I know what you’re thinking — ‘There’s no reason why you would ever do this. Just use polymorphism to solve this.’ You’re right! For this example.

However, the point is, that if you combine the two examples, you get ‘Double Dispatch’.  Now, if C++ supported this, that would be grand. But it doesn’t, and the problem lies with what’s illustrated above. You can’t use a runtime type to do function overloading.

From this point forward, we’re going to use a image system as an example. In our image system, the image can be of different types, and we want to be able to apply some different action to the image; adjust colour, crop, scale, black & white, etc. If we sketch our example in our fairytale C++ language that supports runtime type function overloading. It would look like this.

struct rgb
{
public:
  unsigned char red, green, blue;
};

class iimage
{
public:
    virtual ~iimage()  = default;
    virtual int height() = 0;
    virtual int width() = 0;
    virtual rgb get_pixel_color(int x, int y) = 0;
    virtual void set_pixel_color(int x, int y, rgb color) = 0;
};

class bmp_image : iimage
{
  // any none shared functions  & data
  // implement shared functions
};

class jpg_image : iimage
{
  // any none shared functions & data
  // implement shared functions
};

class iaction
{
public:
    virtual ~iaction() = default;
    virtual void apply(bmp_image &image) = 0;
    virtual void apply(jpg_image &image) = 0;
};

class adjust_color_action : iaction
{
    virtual void apply(bmp_image &image) override
    {
       // some specific algorithm for bmp images
    }
    
    virtual void apply(jpg_image &image) override
    {
       // some specific algorithm for jpg images
    }
};

void apply_action(iimage &image, iaction &action)
{
    action.apply(image);
};

int main()
{
    iimage &image = generate_image();
    iaction &action = get_user_action();
    apply_action(image, action);
}

So as you can see, if this was to compile, we’ve done two things, we’ve separated our algorithms from our data; actions & images, and given ourselves the ability to apply different algorithms based on the different types of data. We’re using both types of single dispatch at once, a runtime polymorphic virtual function dispatch, when we call ‘apply’. Then a runtime function overload, with the argument passed in. That right there — is Double Dispatch.

Unfortunately for us. That runtime function overload, doesn’t exist in C++. So we need to somehow invert our call, so that the compiler can be sure of the type when it compiles.

Enter Visitor Pattern.

By inverting the dispatch of the action, onto the image base, we can cause the dynamic dispatch to the action, while knowing at compile time the type getting passed in. It looks like this.

struct rgb
{
public:
 unsigned char red, green, blue;
};

class iaction;

class iimage
{
public:
 virtual ~iimage() = default;
 virtual int height() = 0;
 virtual int width() = 0;
 virtual rgb get_pixel_color(int x, int y) = 0;
 virtual void set_pixel_color(int x, int y, rgb color) = 0;
 virtual void apply(iaction &action) = 0;
};

class bmp_image;
class jpg_image;

class iaction 
{ 
public: 
    virtual ~iaction() = default; 
    virtual void visit(bmp_image &image) = 0; 
    virtual void visit(jpg_image &image) = 0; 
};
class bmp_image : iimage
{
    // any none shared functions & data
    // implement shared functions
    virtual void apply(iaction &action) override
    {
         // the *this, tells the compiler, that when you
         // call apply on the bmp_image, it will call the
         // bmp_image overload of the iaction
         action.visit(*this);
    }
};

class jpg_image : iimage
{
    // any none shared functions & data
    // implement shared functions
    virtual void apply(iaction &action) override
    {
        action.visit(*this);
    }
};

class adjust_color_action : iaction
{
  virtual void visit(bmp_image &image) override
  {
    // some specific algorithm for bmp images
  }
 
  virtual void visit(jpg_image &image) override
  {
   // some specific algorithm for jpg images
  }
};

void apply_action(iimage &image, iaction &action)
{
    image.apply(action);
};

int main()
{
   iimage &image = generate_image();
   iaction &action = get_user_action();
   apply_action(image, action);
}

Okay — so as you can see, in this example we’re emulating Double Dispatch, by inverting our calls. Which uses first polymorphism to make the correct call, and then a compile time overloaded function. Voila! Double Dispatch, kind of. This pattern lends itself very nicely when you need to separate your function, from your data. It allows you to easily expand data function, without having to change code in the data. However, additional data becomes a bit of a pain, because you need to change all of your function classes to support the new data class.

Now, I mentioned earlier that there is an architecture that the Visitor Pattern becomes quite pervasive, to a point of being almost invasive. It’s the dreaded ‘Anemic Domain Model’ architecture / pattern! Gasp! What is the ‘Anemic Domain Model’? Well according to Wikipedia, it is “Anemic domain model is the use of a software domain model where the domain objects contain little or no business logic (validations, calculations, business rules etc.).”

[ See Post In Defense of The Anemic Data Model ]

If you’ve architected your system in this way. You might start to see where the visitor pattern starts to become pervasive. Just because you chose to decouple function from data, doesn’t mean you throw OO out the window completely. Right? The issue you face, is that if a component in your data model wants to become a hierarchy, how do you deal with it? You can’t add function to the data. Because that’s the point of your model. You need a pattern where you can apply a dynamic algorithm, to a dynamic piece of data.

Enter Visitor Pattern.

Because RESTful APIs lend themselves nicely to this pattern, let’s reimagine our image processing example as a REST api.

Let’s say we want to PUT to a transform, in our image collection. We want to be able to 1) have multiple transforms, and accept different kinds of images.

Our API is

PUT api/images/transform
{
   "action":"adjust_color",
   "image":"bin_data"
}

Now, imagine we had some kind of mechanism, that would dispatch us the deserialization of our JSON blob to

void on_put_images_tranform(iimage &image, iaction &action);

You could design things differently, where you didn’t need the visitor pattern. Although, I think this is a nice blend of OO, patterns, and separation of concerns. So it nicely illustrates my point.

HOWEVER! The visitor pattern isn’t cheap, you need multiple classes, you need multiple interfaces and it does obfuscate data away from function.

Enter “Pattern Matching”.

What is Pattern Matching, you’re asking? How does it relate to the Visitor Pattern? Pattern matching, in regards to programming languages, is for all intents and purposes a switch statement on steroids.

Your average switch looks like this:

enum states { stopped, running, error };

std::string to_string(states s)
{
    switch(s)
    {
    case states::stopped:
         return "stopped";
    case states::running:
         return "running";
    case states::error:
         return "error";
    default:
         return "unknown";
    } 
};

Imagine this guy, if you could apply that to types.

I need to switch languages here. C++ has a library, called Mach7 which is a pattern matching library, and it allows for functionality similar to what I’m going to describe. I just find that the C# syntax is cleaner and easier to read. As of C# 7 pattern matching, and the ability switch on object type, is a thing. The first time I saw it, I thought ‘Honestly, who would ever use that??’ Apparently, me.

I’m going to reimagine our example, in a hybrid language. Because I want to use the C# pattern matching syntax, but I want to stick with the original C++ example.

Instead of needing to perform the inversion, we can use a runtime detection of type to dispatch to the right call.

Like so

void apply_action(iimage &image, iaction &action)
{
    switch(image)
    { 
    case bmp_image bmp:
         action.apply(bmp);
    case jpeg_image jpg:
         action.apply(jpg);
    default:
       throw unsupported_object_exception();
    }
}

int main() 
{ 
    iimage &image = generate_image(); 
    iaction &action = get_user_action(); 
    apply_action(image, action); 
}

As you can see, we’re very close to the initial Double Dispatch described at the start of the post. We’ve come full circle!

To recap, Double Dispatch is a form of multiple dispatch, allowing us to dispatch polymorphic function on polymorphic data. The Visitor Pattern, is a pattern that allows us to emulate Double Dispatch in languages that have no support for it. The Visitor Pattern is especially good at allowing us to separate function from our data. It becomes very pervasive in a pattern where we keep our data and logic separate (an anti-pattern), but want to have data hierarchies. Pattern Matching is a language construct that allows us use a switch statement on steroids, to switch on object type. Giving us almost Double Dispatch.

Happy Coding!

“The ultimate dream in life is to do what you love, and learn something from it” – Jennifer Love Hewitt

References

Virtual Functions in C [https://www.embedded.com/electronics-blogs/programming-pointers/4391967/Virtual-functions-in-C]

Double Dispatch with an Inverted Visitor Pattern [http://www.drdobbs.com/double-dispatch-with-an-inverted-visitor/184403497]

The Adventures of Dependency Injection and Inversion of Control.

I like to think my first words were ‘std::cout << “Hello World” << std::endl;’. The canonical C++ Hello World program. But alas, they weren’t. I cut my teeth on QBasic (Quick Beginners All purpose Symbolic Instruction Code, not to be confused with QuickBASIC). I did my time in QBasic, writing ‘viruses’ that would show download progress bars, and print ‘Ha Ha’ infinitely (sorry Dan).

Oh look, I’ve digressed; Back on topic — My first C++ experience was in CMPUT101. That’s when I fell in-love with the language. It was the :: that did it. Also, I always liked the simplicity of the language (Say what?). Anyways, as a young (and full of vigor, I might add) C++ software developer fresh out of school, I often found my code tangled and tightly coupled. Class design in C++ is hard. For me, often my class designs consisted of a lot of value members, and a lot of  concerns fused together.

A value member, is a instance of a class (or POD) as a member variable, of another class. In C++, value members are laid out in memory as they’re declared in the class.

class foo
{
public:
   int A;
   int B;
};

class bar
{
public:
   foo fooA;
   foo fooB;
};

If sizeof(int) == 4, then sizeof(foo) == 8 and sizeof(bar) == 16; Hopefully this makes sense.

[I’m getting there!]

So the thing about value members and call by value in C++, is that there is no polymorphism. You only get polymorphism, or virtual function calls, when you call on a reference or a pointer. Which means, when your class is full of value members, you’re EXTREMELY tightly coupled to the implementation of those members.

Here’s an example to illustrate what I’m talking about.

class file_to_database
{
private:
    file file_;
    database database_;
public:
    file_to_database(const std::string &filename, 
                    const std::string &connect_s)
    {
    }

    void parse()
    {
         std::string line;
         while(file_.read_line(line))
         {
              std::string tablename;
              std::string v1, v2;
              // do some parse work
              database_.insert(tablename, v1, v2);
         }
    }
};

int main(int argc, const char** argv)
{
    file_to_database ftdb(argv[0], argv[1]);
    ftdb.parse();
}

As you can see. We’re very very coupled to both the implementation of the file and database.

When you start delivering code for realz, and have to debug in the field. That’s about the time you remember back to school, and this thing called a ‘Unit Test’. Then it dawns on you, *that might not have just been a ploy to get me to do more homework, but actually useful!!!* So you think to yourself, *Self — I should probably unit test my code*. So you trudge down that road. Hi! Ho! Hi! Ho!

There’s only one problem with that. Everything in your class is a value member. Meaning no polymorphism. Meaning you’re stuck with the implementation you wrote, coupled to a database and all. *Shit.*

I headed on a path of discovery. I was going to solve this problem. How can I make my classes more testable and less coupled to implementation details?

If I boil down my research (and years of experience after). It comes down to 3 rules.

  1. Favour composition over inheritance – inheritance is the tightest coupling you can get. Unless you need it, don’t use it.
  2. Develop to an interface – use well designed interfaces to separate implementation from algorithms.
  3. Use Dependency Injection – dun. dun. dun.

Let’s see where I went wrong.

  1. Check. My classes were generally composed of other types, as value members.
  2. No polymorphism, no interfaces.
  3. What is this even??

Now, at this point I was part of the all mighty C++ development crew!! The language coursed through my veins. Oooh Rah. I had a major hate-on for Enterprise Developers and any type of managed languages. (I still hate JAVA, so if you’re a JAVA developer stop reading right now and go learn a real programming language. Just kidding! 🙂 No but seriously, my language compiles your language.) However, I had heard about this thing called ‘Dependency Injection’ from the Enterprise team at work. I also had read about it on the internet. I took a look at some ‘Dependency Injection’ code examples on the internet. Uhhh. Okay Mr.C-Sharp, where the heck does anything begin, who owns what? Wow. I’m going to stay as far from ‘Dependency Injection’ as I can.

By this time, I had solved my unit testing woes. I started using reference members to pure virtual classes (interfaces). Lastly I started taking all the implementations of the classes in my constructors. This allowed me to write tests against my classes, make sure they functioned correctly using mock implementations. Then in production, supply the real-world implementation. I could now mock out my databases and files, supply those in the constructor and test my classes. This also, really simplified my ownership models. I won. Check and mate, Mr. C-Sharp. No ‘Dependency Injection’ here.

  1. Check.
  2. Check.
  3. Hell no. Who needs that? I’ll control where things are created, destroyed and owned. Thank you very much.

It didn’t matter, because I was now cooking with dynamite, I could unit test! Hizuh! I don’t need your silly ‘Dependency Injection’ where I have no idea who made what, when or who owns anything.

Here’s the example above, re-imagined to suit my testing needs.

class ifile
{
public:
   virtual ~ifile() = default;
   virtual bool read_line(std::string &line)=0;
};

class idatabase
{
public:
   virtual ~idatabase() = default;
   virtual void insert(const std::string &tablename,
                       const std::string &value1,
                       const std::string &value2)=0;
};

class file_to_database
{
private:
     ifile &file_;
     idatabase &database_;
public:
     file_to_database(ifile &file, idatabase &database)
     :file_(file), database_(database)
     {
     }

     void parse()
     {
         std::string line;
         while(file_.read_line(line))
         {
              std::string tablename;
              std::string v1, v2;
              // do some parse work
              database_.insert(tablename, v1, v2);
         }
     }
};
class file : public ifile
{
public:
    file(const std::string &filename)
    {
    }
    virtual bool read_line(std::string &line) override
    {
        // implementation
    }
};

class database : public idatabase
{
public:
   database(const std::string &connect_s)
   {
   }
   virtual void insert(const std::string &tablename,
                       const std::string &value1,
                       const std::string &value2)
   {
        // implement
   }
};

int main(int argc, const char** argv)
{
    file f(argv[0]);
    database(argv[1]);

    file_to_database ftdb(file, database);
    ftdb.parse();
}

As you can see, this refactor takes the parsing code from near impossible to test without a file and a database. To extremely easy to test, by mocking out our inputs (ifile) and our outputs (idatabase). The awesome thing, I didn’t even touch the parsing algorithm. Just a couple smart interfaces, and introduce the dependencies in the constructor. Bingo. Bango.

So — a little while later, I’m attending CPPCON and I’m having a couple wobblies with a friend. He’s a C++ Guru and did some time at a C# shop. We got onto this topic. I tell him “Man, have you heard of this ‘Dependency Injection’ thing? What a nightmare. How do you even know when things are constructed? Who even owns what?”

He pauses. Then he delivers a mind-bottling statement. “Dependency Injection IS NOT Inversion of Control.” I said, “What?!?” He pauses again. “Dependency Injection IS NOT Inversion of Control. Dependency Injection is simple — just make your classes take what they depend on in the constructor…. When you use interfaces it makes it so you can replace the implementation of the dependencies, without modifying the class.” I think I almost fell off my stool (and it wasn’t the amount of wobblies I had). “No. No. No. Dependency Injection is this crazy-ass thing that obfuscates where objects get created and requires that everything on the planet be an interface, even simple things.” I cried.

He smiled, took a sip of his water — “You’re wrong. That’s an Inversion of Control container.” I take a sip of my beer. “Well. What’s an Inversion of Control container?”. He looked at me smugly, “What you just described. That is.”

It was this moment, when I learned the difference between ‘Dependency Injection’ and ‘Inversion of Control’. Dependency Injection is that simple, make your classes take their dependencies in the constructor. If those dependencies happen to be interfaces, you can swap out implementations as needed and your class won’t change. This is sometimes referred to as the ‘Hollywood Principle’ — Don’t call us. We’ll call you.

Inversion of Control, is succeeding control of object creation, and ownership to a framework. It utilizes ‘Dependency Injection’ in order to build up objects in a hierarchical fashion.  In my opinion, these were frameworks created because some developer had nothing better to do with his/her time. Enterprise developers, amirite!?! 😀 But in all seriousness, they really obfuscate ownership and creation. Which is my opinion are fundamental to software design. This is done in the name of modularity, so I understand. However, I’m not a fan. They do have their usage in large applications that need extremely customizable and modular foundations. Although, I’d argue these are few and far between.

Lastly, neither of these are to be confused with ‘Dependency Inversion’. Sometimes, people will confuse ‘Inversion of Control’ and ‘Dependency Injection’ and call it by some ugly step child name of ‘Dependency Inversion’. ‘Inversion of Control’, uses ‘Dependency Inversion’, so does ‘Dependency Injection’. Essentially, ‘Dependency Inversion’ is ensuring that your higher level components, don’t depend on your lower level components. The term though, is generally used to refer to architecture design, at the module level. By making both high and low level modules depend on a shared interface i.e. one caller and one implementer, the direct dependency is now ‘inverted’.

In summary, ‘Dependency Injection’ is the act of taking all class dependencies via the constructor. ‘Inversion of Control’ also called ‘Inversion of Sanity’, is the act of allowing a framework to control all of the important decisions of your program, and you pretending to control it via XML. ‘Dependency Inversion’ is neither of these, but an architectural pattern that helps to decouple modules within a system, by having high and low level components work through interfaces.

Happy Coding!

“Be yourself, because everyone else is already taken.” — Oscar Wilde