Learning from React series:

  • Part 1 - why examining React is useful even if you won't end up using it
  • Part 2 - what Facebook wanted to do with React and how to get a grasp on it
  • Part 3 - what is Reactive Programming all about?
  • Part 4 - is React functional programming?
  • Part 5 - Typescript, for better and for worse
  • Part 6 (this one) - Single Page Applications are not where they wanted to be

We cannot discuss React without talking about Single Page Applications, even if one can make a React based web site that isn't a SPA and SPAs that don't use a framework or library. What are SPAs? Let's start with what they are not.

SPAs are not parallax background, infinite scroll pages where random flashy things jump at you from the top and bottom and the sides like in a bloody ghost train ride! If you ever considered doing that, this is my personal plea for you to stop. For the love of all that is decent, don't do it!

SPAs are desktop applications for the web. They attempt to push the responsive, high precision actions, high CPU usage and fancy graphics to the client while maintaining the core essentials on the server, like security and sensitive data, while trying to assert full control over the interface and execution flow. In case connectivity fails, the cached data allows the app to work just fine offline until you reconnect or you need uncached data. And with React (or Angular and others), SPAs encapsulate UI in components, just like Windows Forms.

You know who tried (and continues to try) to make Windows Forms on the web? Microsoft. They started with ASP.Net Web Forms, which turned into ASP.Net MVC, which turned into ASP.Net Web API for a while, then turned to Blazor. At their heart, all of these are attempts to develop web applications like one would desktop applications.

And when they tried to push server side development models to the web they failed. They might succeed in the future and I wish them all the luck, but I doubt Microsoft will make it without acknowledging the need to put web technologies first and give developers full and direct access to the browser resources.

Ironically, SPAs (and modern web development in general) put web technologies first to a degree that makes them take over functionality already existing in the browser, like location management, URL handling and rendering components, but ignore server technologies.

It is relevant to make the comparison between SPAs and desktop applications because no matter how much they change browsers to accommodate this programming style, there are fundamental differences between the web and local systems.

For one, the way people have traditionally been trained to work on the web is radically different from how modern web development is taught.

Remember Progressive Enhancement? It was all about serving as much of the client facing, relevant content to the browser first, then enhancing the page with Javascript and CSS. It started from the idea that Javascript is slow and might not be enabled. Imagine that in 2021! When first visiting a page you don't want to keep the users waiting for all the fancy stuff to load before they can do anything. And SEO, even if nowadays the search engine(s?) know how to execute Javascript to get the content as a user would, still cares a lot about the first load experience.

Purely client tools like React, Angular, Vue, etc cannot help with that. All they can do is optimize the Javascript render performance and hope for the best. There are solutions cropping up: check out SSR and ReactDomServer and React Server Components. Or Astro. Or even Blazor. The takeaway here is that a little bit of server might go a long way without compromising the purity of the browser based solution.

Remember jQuery and before? The whole idea back then was to access the DOM as a singular UI store and select or make changes to any element on the entire page. Styling works the same way. Remember CSS Zen Garden? You change one global CSS file and your website looks and feels completely different. Of course, that comes with horrid things like CSS rule precedence or !important [Shudder], yet treating the page as a landscape that one can explore and change at will is a specifically browser mindset. I wasn't even considering the possibility when I was doing Windows Forms.

In React, when I was thinking of a way to add help icons to existing controls via a small script, the React gurus told me to not break encapsulation. That was "not the way". Well, great, Mandalorian! That's how you work a lot more to get to the same thing we have done for years before your way was even invented! In the end I had to work out wrapper elements that I had to manually add to each form control I wanted to enhance.

In the same app I used Material Design components, which I thought only needed a theme to change the way they look and feel, only to learn that React controls have to be individually styled and that the theme itself controls very few things. Even if there is support for theming, if you want to significantly change the visuals and behaviour you will have to create your own controls that take what they need (much more than what Material UI controls do) from the theme provider.

A local desktop application is supposed to take most of the resources that are available to it. You can talk about multitasking all you want, but normal people focus on one complex application at a time. At its core a SPA is still a browser tab, using one thread. That means even with the great performance of React, you still get only one eighth (or something, based on the number of processors) from the total computer resources. There are ways of making an application use multiple threads, but that is not baked in React either. Check out Neo.js for an attempt to do just that.

You can't go too far in the other direction either. Web user experience is opening many tabs and switching from one to the other, refreshing and closing and opening others and even closing the browser with all the tabs open or restoring an entire group of bookmarks at once. And while we are at the subject of URLs and bookmarks, you will find that making a complex SPA consistently alter the address location so that a refresh or a bookmark gets you to the same place you were in is really difficult.

A local Windows app usually has access to a lot of the native resources of the computer. A browser is designed to be sandboxed from them. Moreover, some users don't have correct settings or complete access to those settings, like in corporate environments for example. You can use the browser APIs, but you can't fully rely on them. And a browser tab is subject to firewall rules and network issues, local policies, browser extensions and ad blockers, external ad providers and so on.

You may think I am taking things to an unreasonable extreme. You will tell me that the analogy to desktop apps breaks not despite, but because of all of the reasons above and thus SPAs are something else, something more light, more reusable, webbier, with no versioning issues and instant access and bookmarkable locations. You will tell me that SPAs are just normal web sites that work better, not complex applications. I will cede this point.

However! I submit that SPAs are just SPAs because that's all they could be. They tried to replace fully fledged native apps and failed. That's why React Native exists, starting as a way to do more performant apps for mobiles and now one can write even Windows applications with it.

Single Page Applications are great. I am sure they will become better and better with time until we will forget normal HTML pages exist and that servers can render and so on. But that's going in the wrong direction. Instead of trying to emulate desktop or native apps, SPAs should embrace their webbiness.

Is Javascript rendering bad? No. In fact it's just another type of text interpreted by the browser, just like HTML would be, but we can do better.
Is Javascript URL manipulation bad? No. It's the only way to alter the address location without round trips to the server, but sometimes we need the server. Perhaps selective loading of component resources and code as needed will help.
Is single threaded execution bad? No, but we are not restricted to it.
Is component encapsulation bad? Of course not, as long as we recognize that in the end it will be rendered in a browser that doesn't care about your encapsulation.
The only thing that I am still totally against is CSS in Javascript, although I am sure I haven't seen the best use of it yet.

React is good for SPAs and SPAs are good for React, but both concepts are trying too hard to take things into a very specific direction, one that is less and less about the browser and more about desktop-like components and control of the experience. Do I hate SPAs? No. But as they are now and seeing where they are going, I can't love them either. Let's learn from them, choose the good bits and discard the chaff.  

  Learning from React series:

  • Part 1 - why examining React is useful even if you won't end up using it
  • Part 2 - what Facebook wanted to do with React and how to get a grasp on it
  • Part 3 - what is Reactive Programming all about?
  • Part 4 - is React functional programming?
  • Part 5 (this one) - Typescript, for better and for worse
  • Part 6 - Single Page Applications are not where they wanted to be

  Typescript is a programming language developed by Microsoft. It is a superset of Javascript that allows a lot of type checking and manipulation, hence the name. React and Vue fully support it while Angular requires it. So what is the reason for the adoption of this new language? What are its advantages and disadvantages?

  First of all, what is it? I would start metaphorically, if you can forgive that. Imagine a vast jungle, grown organically since time immemorial, chaotic and wild. Many developers went in, but few have come out unscathed, some never to be seen again. That's Javascript for you. It was released in 1995 as a basic scripting language for browsers, but it was designed as so flexible and complete that it could be used as a programming language in any context with minor modifications. For a very long time tightly coupled with its (very inefficient) browser implementations, it was dismissed from being a proper programming language. But that ended pretty much when V8 was launched, a performant Javascript engine that could be used separately to run the language in whatever situation the developer wanted. With V8, Chrome was launched and soon enough Node.js, which ran Javascript on the server as a proper language.

  The worst and best feature of Javascript is flexibility. You can do pretty much whatever you want in it, as it is a dynamic language unencumbered by such silly things as encapsulation, classes, types and so on. So if you started in a structured way, you could do a lot, if not - like most people unfamiliar with the language - you created a mess that no one could understand, including yourself. So if Javascript is a jungle, Typescript is Duke Nukem coming to cut the trees, wall off vast swathes of forest and only allow a narrow path for life to exist. Only, on that narrow path you get the same chaotic and wild proliferation. A lot fewer software developers traverse the forest and come out with PTSD, but a lot more people go through than before and mistakes can and will be made.

  I guess what I am trying to say is that Typescript sometimes feels like a square peg forced into a round hole. It is not a bad language. In fact, it is amazing in some parts. The type system introduced by Microsoft acts like a kind of system of annotations that inform on what you are actually doing. Tools are aware now of the types of values you use, can optimize code, find errors, warn devs, autocomplete code, help with development, etc. And I am willing to bet that people working on the language are having the time of their lives, because it has to be fun to work on abstract computer science and getting paid, too.

  But what does that mean for the frontend industry? It means that people are getting pushed on that narrow jungle path, for better or for worse. As a small business, you will have to either accept a shitty website created by cheap Javascript and vanilla HTML cavemen or get a lot out of your pocket to hire people who spend time and effort to understand Typescript and some, if not most, of the frontend frameworks that are fashionable at the moment. As a large company you will get tectonic shifts in technology, leaving a large part of your workforce in limbo, while having to spend a lot on hiring and redesigning flows. As an industry, we become dependent on several companies that spend the effort of keeping their frameworks up to date and documented. 

  Let me give you some Typescript questions (that I will not answer) to test your knowledge:

  • can you tell me what all of these types are and how they differ from each other: undefined, null, any, unknown, never, void ?
  • how can you tell if a Typescript object is of a specific form (the equivalent of the .NET 'is' or 'as' functionality)?
  • what is the difference between a union of literal types and an enum?
  • what are and how can you use BigInt, ReadOnlyArray, Partial, NonNullable, Required?
  • what is the difference between a private member of a Typescript class and one starting with #?
  • do you know how to use unions in interpolated strings?
  • what is the difference between interface, type, class, type intersection, class expression and module?

 I could go on and on. On how the possibility of null is now something you have to declare explicitly, for example. I didn't (dare to) ask about type guards and how narrowing works and what conditional types are. And there are so many gotchas for developers coming from other languages, because the language features have been added by people who worked on C#, so they are kind of the same, but actually not. Type meaning and conversion is a large bit of confusing difference between Typescript and C#/Java. For example you can define a class and then cast some data to it, but you don't get what you expect:

class MyClass {
  public name: string='';
  public sayHello() { console.log(`Hello ${this.name}`); }
}

const my:MyClass = { name: 'Siderite' } as MyClass;
console.log(my); // { "name": "Siderite" }
console.log(typeof(my)); // "object"
console.log(my instanceof MyClass) // false
console.log(my.sayHello()); // ERR: my.sayHello is not a function 

There are still web sites dedicated to the inconsistencies of Javascript. Typescript doesn't solve these issues, it mostly hides them. I am sure it's fun to play with types, but is that the optimal solution for the problem at hand, mainly the many ways you can do Javascript wrong? I would argue no. It's fun to work in, but there is a clear dependency between Typescript and Javascript, which forced so many changes in Typescript from Javascript and the other way around, as they have to be kept in sync. All while Javascript needs to remain backwards compatible, too.

"But what about React? Weren't you talking about that, Siderite?"

Yes, I was. I only looked deeper into Typescript because I did this project in React. Before, I had used it with Angular and frankly I didn't feel the friction that I felt now. Angular is designed with Typescript in mind, the development experience is smoother. Angular also uses two directional bindings to propagate changes and that means less Typescript code. The only code you actually need to write is network API code, for which you have out of the box HTTP services, and some limited interface logic. React doesn't do that.

First of all, React has been designed within a kind of declarative/functional mindset, as I explained in previous chapters of this series. It focuses a lot on immutability and functions that are passed around and declaring what your expectations are. Typescript is fundamentally an imperative language. After forcing it through the round hole, the square peg now has to go through a triangular hole, too. The immutability forces one to use a lot of code for changes coming from the UI towards the Typescript logic.

Then, React is a library. It was designed as such and has less levers to force the developer in a direction or another. Even when following a clear development strategy, there are many of which to choose from, all tried and tested and valid, but very different from one another. The jungle was tamed, but now you must consider a multiverse of jungles, each with a different shape.

Finally, React started out in Javascript. Many documentation pages are still just about Javascript. New innovations in the field of React are developed and tested out independently, by various people with various skills and motivations. The learning curve is not steep, but the paths are many.

So in the end, Typescript is an interesting experiment in programming languages, one that will probably surprise me in the near future with ideas that can only be implemented using it. However it is not perfect and its dependency on Javascript is unfortunate, even if its inspiration was not. The purpose of the language was to guide and help developers mired in Javascript confusion, but using it with React goes against that very purpose, as React is still something relatively new and evolving wildly in all directions, so React doesn't help Typescript. Does Typescript help React? I would say yes. However I don't feel that it is enough in its current form. The friction between the two concepts is palpable and I dare any of you to prove me wrong.

It seems I've talked a lot about the problems of React rather than its benefits. I blamed it on things ranging from confusing and obsolete documentation to inconsistent goals of the library and underlying programming language. That's the way I work, focusing on problems so I can find one I can fix. In the next chapter I want to discuss about React in the wild and what are the good things people are saying about it. The most interesting question however, the one that I want to answer with this entire series, is how can we improve our work by adapting lessons learned, either from React to whatever we do or the other way around. What concrete ideas should we adopt from React and which we should condemn to the pit of failed concepts?

  Learning from React series:

  • Part 1 - why examining React is useful even if you won't end up using it
  • Part 2 - what Facebook wanted to do with React and how to get a grasp on it
  • Part 3 - what is Reactive Programming all about?
  • Part 4 (this one) - is React functional programming?
  • Part 5 - Typescript, for better and for worse
  • Part 6 - Single Page Applications are not where they wanted to be

  React was designed just when classes and modules were making their way into Javascript, so it made sense to use them. Developers that are not coming from the Javascript or dynamic languages world are used to the type safety and hierarchical structure that classes provide. And it also made sense from the standpoint of the product. If you want to encapsulate state, logic and presentation why not used existing functioning models like classes, components and so on.

  However, at the same time ideas like functions being first class citizens of programming languages and functional programming were making a comeback, mostly because of big data. That meant that lambdas (arrow functions) were popping up everywhere. If you are a C# developer, you already are familiar with them. Something like Func<int,int> func = (int x)=> x*2; represents a lambda function, which is the same as something written like private int f2(int x) { return x*2; }, yet lambda functions can be declared inside code blocks, can be implicitly cast to Expressions and manipulated and they are brilliant as method parameters. Check out the lambda version in C# compared to the function version in VB:

// C#
var items = allItems.Where(i=>!i.deleted);
// C# function body
var items = allItems.Where(i=>{
                             return !i.deleted
                           });
// VB
Dim items = allItems.Where(Function(i) Not i.deleted)
// VB function body
Dim items = allItems.Where(Function(i) 
			      Return Not i.deleted
			   End Function)

 Similarly, Javascript had only function syntax, even if functions were designed to be first class citizens of the language since its inception. Enter arrow functions in Javascript:

// before
var self = this;
var items = allItems.filter(function(i) {
  return self.validate(i);
});

// after
var items = allItems.filter(i=>this.validate(i));

Note how arrow functions don't have an internal 'this' so you don't need to bind functions or create self variables.

So at this point, React changed and instead of classes, they implemented "functional syntax" in React Hooks. Behind the scenes a component is still generated as a class which React uses and the old syntax is still valid. For example at this time there is no way to create an error boundary component using functional syntax. The result is a very nice simplification of the code:

// React classic (pardon the pun)
export class ShowCount extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }
  componentDidMount() {
    this.setState({
      count: this.props.count
    })
  }

  render() {
    return (
      <div> 
        <h1> Count : {this.state.count} </h1>
      </div>
    );
  }
}

// React Hooks
export function ShowCount(props) {
  const [count, setCount] = useState();

  useEffect(() => {
    setCount(props.count);
  }, [props.count]);

  return (
    <div>
      <h1> Count : {count} </h1>
    </div>
  );
}

// courtesy of https://blog.bitsrc.io/6-reasons-to-use-react-hooks-instead-of-classes-7e3ee745fe04

  But this does not just provide a better syntax, it also changes the way development is done. Inheritance is basically eliminated in favor of composition and people are starting to use the word "functional" in sentences uttered in the real world. And while the overall design of React to use unidirectional binding and immutable variables was there since inception, I do feel like this is just one more step towards a functional programming approach and the reason for so many functional purists popping up lately.

  What is functional programming, though? Wikipedia defines it as "a declarative programming paradigm in which function definitions are trees of expressions that map values to other values, rather than a sequence of imperative statements which update the running state of the program." Sound familiar?

  I will have you know that I have friends that have rebelled and gone to the other side, making applications (including UI) with F# and refusing to submit to the Galactic Imperative. After playing with React I can say that I understand why this approach has appeal. One declares what they need, ignore flow and constrain their efforts inside components that are more or less independent. A program looks and feels like a big function that uses other functions and to which you just provide inputs and out comes UI ready to use. If the same input is provided, the same output results. You can test it to perfection, you can infer what happens with an entire tree of such functions and make optimizations in the transpiler without changing the code. You can even use a diff algorithm on the output tree and just update what changed in the UI.

  But it is time to call bullshit. We've used functions that receive pure data on one side and output user interface on the other side since forever. They are called views. One could even argue that an API is a data provider and the application is the function that uses the data to output UI. You don't ignore flow, you move it up! You will still have to model the interactions between every piece of data you have and all the events that come in. One might even say the unforgivable and assert that React is just another Model-View thingie with the extra constraint that it will forcibly re-render a component when its input state changes.

  That is my main takeaway from React: the idea that forcing re-rendering of components forces the developer to move the state up, closer to where it should be. No one can store stuff in browser variables, in element attributes and data, because all of it will be lost on next render. That is good news, but also very bad news. Let me get you through an example:

  We have data that we need shown in a grid. Every row has an expand/collapse button that will show another grid under it, with details related to that row. The React way of doing things would take us through these steps:

  • create a component that represents the grid and receives an array as input
  • it will contain code that maps the array to a list of row components which receive each row as the input
  • the row component will render a button that will dispatch an expand event for the row when clicked
  • on click the row expanded state will be changed and the data for the row detail grid retrieved

  It sounds great, right? OK, where do you store the state of row expansion? How do we push it to the row component? Let's use a map/dictionary of row id and boolean, why don't we? Does that mean that when you expand/collapse a row only the boolean changes or the entire structure? What will get re-rendered? The row component in question or all the row components?

  What happens when we go to the next page in the grid and then go back? Should we return to the same row expansion states? Where should the scrollbar in the grid be? Should we keep that in the state as well and how do we push it to the grid component? Do row details grids have scroll? Doesn't the size of each component affect the scroll size, so how do we store the scroll position? What is the user resizes the browser or zooms in or out?

  What happens when we resize a grid column? Doesn't that mean that all row components need to be re-rendered? If yes, why? If no, why? What if you resize the column of a detail grid? Should all detail grids have the same resizing applied? How do you control which does what?

  Many grids I've seen are trying to store the expansion, the details, everything in the object sent as a parameter to the row. This seems reasonable until you realize that adding anything to the object changes it, so it should trigger a re-render. And then there is Typescript, which expects an object to keep to its type or else you need to do strange casts from something you know to "unknown", something that could be anything. That's another story, though.

  Suddenly, the encapsulation of components doesn't sound so great anymore. You have to keep count of everything, everywhere, and this data cannot be stored inside the component, but outside. Oh, yes, the component does take care of its own state, but you lose it when you change the input data. In fact, you don't have encapsulation in components, but in pairs of data (what React traditionally calls props) and component. And the props must change otherwise you have a useless component, therefore the data is not really immutable and the façade of functional programming collapses.

  There are ways of controlling when a component should update, but this is not a React tutorial, only a lessons learned blog post. Every complexity of interaction that you have ever had in a previous programming model is still there, only pushed up, where one can only hope it is completely decoupled from UI, to which you add every quirk and complexity coming from React itself. And did we really decouple UI or did we break it into pieces, moving the simplest and less relevant one out and keeping the messy and complex one that gave us headaches in the first place in? It feels to me like React is actually abstracting the browser from you, rather than decoupling it and letting the developer keep control of it.

  After just a month working in this field I cannot tell you that I understood everything and have all the answers, but my impression as of now is that React brings very interesting ideas to the table, yet there is still a lot of work to be done to refine them and maybe turn them into something else.

  Next time I will write about Typescript and how it helps (and hinders) React and maybe even Angular development. See you there!

 Learning from React series:

  • Part 1 - why examining React is useful even if you won't end up using it
  • Part 2 - what Facebook wanted to do with React and how to get a grasp on it
  • Part 3 (this one) - what is Reactive Programming all about?
  • Part 4 - is React functional programming?
  • Part 5 - Typescript, for better and for worse
  • Part 6 - Single Page Applications are not where they wanted to be

The name React is already declaring that it is used in reactive programming, but what is that? Wikipedia is defining it as "a declarative programming paradigm concerned with data streams and the propagation of change". It expands on that to say that it declares the relationship between elements and updates them when either change. You can easily imagine a graph of elements magically updating as any of them changes. However, the implementation details of that magic matter.

  In 2011 Microsoft revealed a free .Net library called Reactive Extensions, or ReactiveX or RX. It was based on a very interesting observation that the observer/observable patterns are the mirror images of iterator/iterable. When the iterator moves through an iterable, the observer reacts to events in the observable; one is imperative, the other reactive. The library was so popular that it was immediately adopted for a bunch of programming languages, including Javascript. It also allowed for operations traditionally used for arrays and collections to work with a similar syntax on observables. This is a great example of reactive programming because instead of deciding when to perform a data access (and having to check if it is possible and everything is in range and so on), the code would just wait for something to happen, for an event that provided data, then act on the data.

  One might argue that Verilog, a hardware description language, is also reactive, as it is based on actions being performed on certain events and it even uses non-blocking assignments, which are like declarations of state change which happen at the same time. Reminds me of the way React is implementing state management.

  Of course, reactive programming is also modern UI and when I say modern, I mean everything in the last twenty years. Code gets executed when elements in the user interface change state: on click, on change, on mouse move, on key press etc. That is why, the developers at Facebook argue, browser based UI programming should be reactive at the core. This is not new, it's something you might even be already very familiar with in other contexts. Code that is triggered by events is also called event-driven programming.

  But at the same time, others also claim their software is reactive. Microservices are now very fashionable. The concept revolves around organizing your product into completely independent modules that only have one external responsibility, which then one wires together via some sort of orchestrator. The biggest advantage of this is obviously separation of concerns, a classic divide and conquer strategy generalized over all software, but also the fact that you can independently test and deploy each microservice. You don't even have to shut down running ones or you can start multiple instances, perhaps with multiple versions and in different locations. This is also distributed programming. The way the communication between microservices is done is usually via some sort of message queue, like Rabbit MQ, but I am working on a really old software, written like 15 years ago, which uses IBM MQ to communicate between different portions of the software - let's call them macroservices :) Well, this is supposed to be reactive programming, too, because the microservices are reacting to the messages arriving on the queue and/or sent from others.

  The observer pattern is old, it's one of the patterns in the original design patterns book Design Patterns: Elements of Reusable Object-Oriented Software, which started the software design pattern craze which rages on even now. Anybody who ever used it extensively in their software can (and many do) claim that they did reactive programming. Then there is something called the actor model (which will probably confuse your Google if you search for it), which is actually a mathematical concept and originated in 1973! Implementations of actors are eerily similar to the microservices concept from above.

  And speaking of events, there is another pattern that is focusing on declaring the flow of changes from a given state, given an event. It's called a state machine. It also boasts separation of concerns because you only care about what happens in any state in case of an event. You can visualize all the possible flows in a state machine, too, as names arrows from any state to another, given that such a transition is defined. The implementation of the state machine engine is irrelevant as long as it enables these state transitions as defined by the developer. 

  Everything above, and probably some other concepts that are named differently but kind of mean the same thing, is reactive programming. Let me give you another example: a method or a software function. Can one say it is reactive? After all, it only executes code when you call it! Couldn't we say that the method reacts to an event that contains the parameters the method needs? What about Javascript, which is designed to be single threaded and where each piece of code is executed based on a queue of operations? Isn't it a reactive programming language using an event bus to determine which actions to perform?

  And that's the rub. The concept of reactivity is subjective and generally irrelevant. The only thing that changes and matters is the implementation of the event transport mechanism and the handling of state.

  In a traditional imperative program we take for granted that the execution of methods will be at the moment of the call and that all methods on that thread will be executed one after the other and that setting a value in memory is atomic and can be read immediately after by any other piece of code and you can even lock that value so it is only read by one entity at a time. Now imagine that you are writing the same program, only we can't make the assumptions above. Calling methods can result in their code getting executed at an arbitrary time or maybe not at all. Whatever you change in a method is only available to that method and there is no way for another method to read the values from another. The result? Your code will take a lot of care to maintain state locally and will start to look more like a state machine, modelling transitions rather than synchronous flows. The order of operations will also be ensured by consuming and emitting the right sort of events. Permanent and/or shared storage will become the responsibility of some of the modules and the idea of "setting data" will become awkward. Keeping these modules in sync will become the greatest hurdle.

  That's all it is! By eliminating assumptions about how your code is executed, the result is something more robust, more generic, more compartmentalized. Is it the golden hammer that will solve all problems? Of course it isn't. We've seen how the concepts at the core of reactive programming have been there since forever. If that was the best way, everybody would already be working like that. The biggest problems of this kind of thinking are resource duplication, as everybody has to keep all the data they use locally, and synchronization, as one cannot assume there exists any source of absolute truth that can be accessed by all at the same time. Debugging the system also becomes a bit complicated.

  In 2014 a bunch of people created something called "The Reactive Manifesto" and anyone can sign it. In it, they define a reactive system as:

  • Responsive - responds quickly
  • Resilient - remains responsive in case of failure
  • Elastic - remains responsive regardless of workload
  • Message Driven - async message passing as the boundary between components

  As you can see, reactive mostly means responsive for them and the concept is more one of organization management than a specific set of programming languages and tools. Note that, in fact, you can create a system that communicates via async message passing between components on the client, on the server, between client and server and so on. There can be multiple types of technology and different stacks. As long as they can react to asynchronous messages, they can be integrated into such a system. 

  This post has reached already a big size and I haven't even touched on functional programming and how it tries to solve... well, everything. I will do that in the next chapter. I have to say that I find the concept of a programming language that eliminates global variable scope and public fields and introduces a delay and a random order of execution of methods or properties from other classes fascinating. Imagine testing and debugging that, then moving the working code to production, where the delay is removed. You will also see that a lot of the ideas above influence how React development is done and perhaps you will understand purists telling everybody how things are not correct until you implement this or that in a certain way. Till next time!

Learning from React series:

  • Part 1 - why examining React is useful even if you won't end up using it
  • Part 2 (this one) - what Facebook wanted to do with React and how to get a grasp on it
  • Part 3 - what is Reactive Programming all about?
  • Part 4 - is React functional programming?
  • Part 5 - Typescript, for better and for worse
  • Part 6 - Single Page Applications are not where they wanted to be

In order to understand React we must consider what were the advantages that Facebook found in the concept when they created the library. There a numerous presentations and articles that they pushed to explain it, but it kind of distills to this:

  • mutation of values complicates flows in complex applications
  • traditional Model-View patterns promote mutation through two directional data binding
  • solution for mutation:
    • use unidirectional data binding and re-render views as the data changes
    • send inputs as events that a higher level entity will interpret
  • solution for slow browser render overhead:
    • code is organized in smaller and smaller components that depend on a few values in the overall data
    • there is an intermediate layer of rendering between React and the actual browser DOM called a Virtual DOM, which only sends to the browser the changes that renders affected

But wait, you will say! How do the values change if they are immutable? The point here is that your components have an immutable internal state. The values that are passed to the components can still change, but on a higher level. They declare a label that have a text and for the label the text never changes. When the text changes in the logic of the application, a new label instance with a new text is rendered. The advantage of this is that the declaration of the render for a component defines the way the component will always render. It's declarative of your intent of how that component should look. They wanted to replace mutation with what they called reconciliation between the previous state and the current state. They almost treated web development like game development or remote access software.

So when you look at a JSX syntax and you see Javascript mixed with HTML and switching back and forth, that is different from the ASPX spaghetti code where server logic was mixed up with UI declarations. JSX is less an XML flavor and more a Javascript flavor. In fact, it is transpiled to Javascript code when executed and the changes to the UI are imperative commands that tell it how to change based on how the render code affected the component. But for the developer it's just a story of how the component should look given some data.

React was released in May 2013 and it went through some transformations on the way. Internally it probably started as an object oriented approach which was cumbersome and fought with the overall design of Javascript. They fixed that by the time of the release by using the JSX syntax, but still with code looking like

var component = React.createClass({ render: function() { return <something/>; } });

And further down the line they came up with React hooks, which move further from the class oriented approach and more towards a functional one with stuff like

const component = (props) => (<something />);

which of course is lighter still. Note that Javascript changed during that time, allowing for more stuff to happen. And now they added Typescript support, so you get something like

const Component = (props:{text:string})=>(<something />);

This evolution of the library is also one of the biggest obstacles against learning how to use it as in your Goggle search you might find solutions and problems from any time in the history of the library. You will find the perfect tool for what you wanted, but all the examples are in Javascript and in Typescript it works differently or the answers refer to previous versions of absolutely everything and you don't know which of them is the one that should apply to your task. Or even worse, some package that you use and it made your life so easy conflicts with the one you just want to use because they were never meant to work together.

As opposed to Angular, which was designed as a framework, to constrain and control what you do, React is a library. And it evolves not only through the efforts of Facebook, but also of a very active community. People would add React to their existing project rather than rewriting it from scratch. This means they will have used any of the various versions of React as well as any of the various versions of all the packages that they use in conjunction with it. And these packages are wild! Imagine a developer coming from the world of WPF or vanilla web design with HTML and CSS as the primary focus and Javascript an after thought or from Angular. They will work with React, but use it in a way they are more familiar with. That means that even if the library has a backing philosophy, there is little it can do to force you to use it in that way.

Let's take just one example: MobX, a package that takes existing data objects and wraps them in proxies that notify of changes. With React you use it as you would a ViewModel in WPF. Instead of sending an event called CLICK from a click event and handling it in some state machine looking code you can just modify the "immutable" property of the data you were sent and behind the scene a setter is executed which lets everybody know that it has changed and so it triggers a re-render which will take the value of the actual property from the behind-the-scene getter. You get your way, React kind of gets its way.

To recap:

  • components live in a tree, rather than a graph, and they all render based on the properties they are passed
  • components declare how they should look like
  • any input from the components is sent up as an event to which the system "reacts"
  • slow browser rendering is replaced with a virtual representation of the UI and updated with specific commands to reflect only the changes from one state to the other
  • React is an evolving beast with many heads and finding your own way of doing things lies at the root of any successful development effort

While exploring development with this library, developers have found various tools and concepts useful to integrate. As we usually do, they started to generalize these attempts and come up with some new principles or get to the root of the underlying flow. I want to spend the next part of the series discussing some of these more general or architectural ideas and try to see what they are worth.

A few years ago I wrote an article about using RealProxy to intercept methods and properties calls in order to log them. It was only for .NET Framework and suggested you inherit all intercepted classes from MarshalByRefObject. This one is a companion piece that shows how interception can be done in a more general way and without the need for MarshalByRefObject.

To do that I am going to give you two versions of the same class, one for .NET Framework and one for .NET Core which can be used like this:

//Initial code:
IInterface obj = new Implementation();

//Interceptor added:
IInterface obj = new Implementation();
var interceptor = new MyInterceptor<IInterface>();
obj = interceptor.Decorate(obj);

//Interceptor class (every method there is optional):
public class MyInterceptor<T> : ClassInterceptor<T>
{
    protected override void OnInvoked(MethodInfo methodInfo, object[] args, object result)
    {
        // do something when the method or property call ended succesfully
    }

    protected override void OnInvoking(MethodInfo methodInfo, object[] args)
    {
        // do something before the method or property call is invoked
    }

    protected override void OnException(MethodInfo methodInfo, object[] args, Exception exception)
    {
        // do something when a method or property call throws an exception
    }
}

This code would be the same for .NET Framework or Core. The difference is in the ClassInterceptor code and the only restriction is that your class has to implement an interface for the methods and properties intercepted.

Here is the .NET Framework code:

public abstract class ClassInterceptor<TInterface> : RealProxy
{
    private object _decorated;

    public ClassInterceptor()
        : base(typeof(TInterface))
    {
    }

    public TInterface Decorate<TImplementation>(TImplementation decorated)
        where TImplementation:TInterface
    {
        _decorated = decorated;
        return (TInterface)GetTransparentProxy();
    }

    public override IMessage Invoke(IMessage msg)
    {
        var methodCall = msg as IMethodCallMessage;
        var methodInfo = methodCall.MethodBase as MethodInfo;
        OnInvoking(methodInfo,methodCall.Args);
        object result;
        try
        {
            result = methodInfo.Invoke(_decorated, methodCall.InArgs);
        } catch(Exception ex)
        {
            OnException(methodInfo, methodCall.Args, ex);
            throw;
        }
        OnInvoked(methodInfo, methodCall.Args, result);
        return new ReturnMessage(result, null, 0, methodCall.LogicalCallContext, methodCall);
    }

    protected virtual void OnException(MethodInfo methodInfo, object[] args, Exception exception) { }
    protected virtual void OnInvoked(MethodInfo methodInfo, object[] args, object result) { }
    protected virtual void OnInvoking(MethodInfo methodInfo, object[] args) { }
}

In it, we use the power of RealProxy to create a transparent proxy. For Core we use DispatchProxy, which is the .NET Core replacement from Microsoft. Here is the code:

public abstract class ClassInterceptor<TInterface> : DispatchProxy
{
    private object _decorated;

    public ClassInterceptor() : base()
    {
    }

    public TInterface Decorate<TImplementation>(TImplementation decorated)
        where TImplementation : TInterface
    {
        var proxy = typeof(DispatchProxy)
                    .GetMethod("Create")
                    .MakeGenericMethod(typeof(TInterface),GetType())
                    .Invoke(null,Array.Empty<object>())
            as ClassInterceptor<TInterface>;

        proxy._decorated = decorated;

        return (TInterface)(object)proxy;
    }

    protected override object Invoke(MethodInfo targetMethod, object[] args)
    {
        OnInvoking(targetMethod,args);
        try
        {
            var result = targetMethod.Invoke(_decorated, args);
            OnInvoked(targetMethod, args,result);
            return result;
        }
        catch (TargetInvocationException exc)
        {
            OnException(targetMethod, args, exc);
            throw exc.InnerException;
        }
    }


    protected virtual void OnException(MethodInfo methodInfo, object[] args, Exception exception) { }
    protected virtual void OnInvoked(MethodInfo methodInfo, object[] args, object result) { }
    protected virtual void OnInvoking(MethodInfo methodInfo, object[] args) { }
}

DispatchProxy is a weird little class. Look how it generates an object which can be cast simultaneously to T or Class<T>!

There are many other things one can do to improve this class:

  • the base class could make the distinction between a method call and a property call. In the latter case the MethodInfo object will have IsSpecialName true and start with set_ or get_
  • for async/await scenarios and not only, the result of a method would be a Task<T> and if you want to log the result you should check for that, await the task, get the result, then log it. So this class could make this functionality available out of the box
  • support for Dependency Injection scenarios could also be added as the perfect place to use interception is when you register an interface-implementation pair. An extension method like container.RegisterSingletonWithLogging could be used instead of container.RegisterSingleton, by registering a factory which replaces the implementation with a logging proxy

I hope this helps!

P.S. Here is an article helping to migrate from RealProxy to DispatchProxy: Migrating RealProxy Usage to DispatchProxy

Definition

So, the task at hand is the subject of a common interview question: Implement an algorithm to get all valid (opened and closed) combinations of n pairs of parentheses. This means that for n=1 there is only one solution: "()". "((" or "))" are not valid, for 2 you will have "(())" and "()()" and so on. The question is trying to test how the interviewee handles recursion and what is commonly called backtracking. But as usual, there's more than one way to skin a cat, although for the life of me I can't see why you would want to do that.

The solutions here will be in C# and the expected result is an enumeration of strings containing open and closed parentheses. The code can be easily translated into other languages, including Javascript (ECMAScript 2015 introduced iterators and generator functions), but that's left to the reader. Let's begin.

Analysis

Before we solve any problem we need to analyse it and see what are the constraints and the expected results. In this case there are several observations that can be made:

  • the resulting strings will be of length n*2 (n pairs)
  • they will contain n '(' characters and n ')' characters
  • they cannot start with a ')' or end in a '('
  • in order to generate such a string, we can start with a smaller string to which we add '(' or ')'
  • we cannot add a ')' if there isn't at least one corresponding unclosed '(' 
  • if we add a '(' we need to have enough characters left to close the parenthesis, so the number of unclosed parentheses cannot exceed the characters left to fill
  • we could count the open and closed parentheses, but we only care about the number of unclosed ones, so instead of "closed" and "open" values, we can only use "open" to represent unclosed parentheses

Let's go for some variables and calculations:

  • n = number of pairs
  • open = number of unclosed parentheses in a string
  • open cannot be negative
  • one cannot add ')' if open = 0
  • one cannot add '(' if open >= n*2 - substring.length

Recursive solution

A simple implementation of these requirements can done with recursion:

public IEnumerable<string> GenerateRecursive(int n, string root = "", int open = 0)
{
    // substring is long enough, return it and exit
    if (root.Length == n * 2)
    {
        yield return root;
        yield break;
    }
    // if we can add '(' to existing substring, continue the process with the result
    if (open < n * 2 - root.Length)
    {
        // if only C# could just 'yield IteratorFunction()' this would look sleeker
        foreach (var s in GenerateRecursive(n, root + "(", open + 1))
        {
            yield return s;
        }
    }
    // if we can add ')' to existing substring, continue the process with the result
    if (open > 0)
    {
        foreach (var s in GenerateRecursive(n, root + ")", open - 1))
        {
            yield return s;
        }
    }
}

However, every time you see recursion you have to ask yourself: could n be large enough to cause a stack overflow? For example this fails for n=3000. The nice thing about this method, though, is that it can be limited to the number of items you want to see. For example var firstTen = GenerateRecursive(1000).Take(10) is very fast, as the generation is depth first and only computes the first ten values and exits.

So, can we replace the recursion with iteration?

Iterative solution

In order to do thing iteratively, we need to store the results of the previous step and use them in the current step. This means breadth first generation, which has its own problems. Let's see some code:

public IEnumerable<string> GenerateIteration(int n)
{
    // using named tuples to store the unclosed parentheses count with the substring
    var results = new List<(string Value,int Open)>() { ("",0) };
    for (int i = 0; i < n*2; i++)
    {
        // each step we compute the list of new strings from the list in the previous step
        var newResults = new List<(string Value, int Open)>();
        foreach (var (Value, Open) in results)
        {
            if (Open < n * 2 - Value.Length)
            {
                newResults.Add((Value + "(", Open + 1));
            }
            if (Open > 0)
            {
                newResults.Add((Value + ")", Open - 1));
            }
        }
        results = newResults;
    }
    return results.Select(r=>r.Value);
}

It's pretty sleek, but if you try something like var firstTen = GenerateRecursive(1000).Take(10) now it will take forever since all combinations of 1000 parentheses need to be computed and stored before taking the first 10! BTW, we can write this much nicer with LINQ, but be careful at the gotcha in the comment:

public IEnumerable<string> GenerateLinq(int n)
{
    // looks much nicer with LINQ
    IEnumerable<(string Value, int Open)> results = new[] { ("", 0) };
    for (var i = 0; i < n * 2; i++)
    {
        results =
            results
                .Where(r => r.Open < n * 2 - r.Value.Length)
                .Select(r => (Value: r.Value + "(", Open: r.Open + 1))
            .Concat(results
                .Where(r => r.Open > 0)
                .Select(r => (Value: r.Value + ")", Open: r.Open - 1))
            );  // but if you do not end this with a .ToList()
                // it will generate a huge expression that then will be evaluated at runtime! Oops!
    }
    return results.Select(r => r.Value);
}

But can't we do better? One is going to stack overflow, the other memory overflow and the last one kind of does both.

Incremental solution

They did say this requires an incremental solution, right? So why don't we take this literally? '(' and ')' are like 0 and 1, as ')' must always follow a '('. If you view a parenthesis string as a binary number, then all possible combinations can be encoded as numbers. This means that we could conceivably write a very fast function that would compute all possible combinations using bit operations, maybe even special processor instructions that count bits and so on. However, this would work only for n<=32 or 64 depending on the processor architecture and we don't want to get into that. But we can still use the concept!

If a string represents a fictional number, then you can start with the smallest one, increment it and check for validity. If you combine the incremental operation with the validity check you don't need to go through 2n operations to get the result. It doesn't use any memory except the current string and it is depth first generation. The best of both worlds! Let's see some code:

public IEnumerable<string> GenerateIncrement(int n)
{
    // the starting point is n open parentheses and n closing ones
    // we use the same array of characters to generate the strings we display
    var arr = (new string('(', n) + new string(')', n)).ToCharArray();
    // iteration will stop when incrementation reaches the "maximum" valid combination
    var success = true;
    while (success)
    {
        yield return new string(arr);
        success = Increment(arr, n);
    }
}

private bool Increment(char[] arr, int n)
{
    // we begin with a valid string, which means there are no unclosed parentheses
    var open = 0;
    // we start from the end of the string
    for (var i = arr.Length - 1; i >= 0; i--)
    {
        // ')' is equivalent to a 1. To "increment" this string we need to go to the previous position
        // incrementing 01 in binary results in 10
        if (arr[i] == ')')
        {
            open++;
            continue;
        }

        // '(' is equivalent to a 0. We will turn it into a ')' to increment it,
        // but only if there are unclosed parentheses to close
        open--;
        if (open == 0) continue;

        // we 'increment' the value
        arr[i] = ')';
        // now we need to reset the rest of the array
        var k = n - (open + i) / 2;
        // as many opening parenthesis as possible
        for (var j = i + 1; j < i + 1 + k; j++)
        {
            arr[j] = '(';
        }
        // the rest are closing parentheses
        for (var j = i + 1 + k; j < n * 2; j++)
        {
            arr[j] = ')';
        }
        return true;
    }
    // if we reached this point it means we got to a maximum
    return false;
}

Now doing GenerateIncrement(1000000).Take(10) took more to display the results than to actually compute them.

More solutions

As this is a classic interview question, there are a billion solutions to it at LeetCode. Yet the purpose of interview questions is to find out how one thinks, not what the solution of the problem actually is. I hope this helps.

Intro

  When talking Dependency Injection, if a class implementing Interface1 needs an implementation of Interface2 in its constructor and the implementation for Interface2 needs an implementation of Interface1 you get a circular dependency error. This could be fixed, though, by providing lazy proxy implementations, which would also fix issues with resources getting allocated too early and other similar issues.  Now, theoretically this is horrible. Yet in practice one meets this situation a lot. This post will attempt to clarify why this happens and how practice may be different from theory.

Problem definition

  Let's start with defining what an interface is. Wikipedia says it's a shared boundary between components. In the context of dependency injection you often hear about the Single Responsibility Principle, which stipulates that a class (and by extension an interface) should only do one thing. Yet even in this case, the implementation for any of the Facade, Bridge, Decorator, Proxy and Adapter software patterns would do only one thing: to proxy, merge or split the functionality of other components, regardless of how many and how complex they are. Going to the other extreme, one could create an interface for every conceivable method, thus eliminating the need for circular dependencies and also loading code that is not yet needed. And then there are the humans writing the code. When you need a service to provide the physical location of the application you would call it ILocationService and when you want to compute the distance between two places you would use the same, because it's about locations, right? Having an ILocationProviderService and an ILocationDistanceCalculator feels like overkill. Imagine trying to determine if a functionality regarding locations is already implemented and going through all the ILocation... interfaces to find out, then having to create a new interface when you write the code for it and spending sleepless nights wondering if you named things right (and if you need to invalidate their cache).

  In other words, depending on context, an interface can be anything, as arbitrarily complex as the components it separates. They could contain methods that are required by other components together with methods that require other components. If you have more such interfaces, you might end up with a circular dependency in the instantiation phase even if the execution flow would not have this problem. Let's take a silly example.

  We have a LocationService and a TimeService. One handles points in space the other moments in time. And let's say we have the entire history of someone's movements. You could get a location based on the time provided (GetLocation) or get the time based on a provided location (GetTime). Now, the input from the user is text, so we need the LocationService and the TimeService to translate that text into actual points in space and moments in time, so GetLocation would use an ITimeService, while GetTime would use an ILocationService. You start the program and you get the circular dependency error. I told you it would be silly. Anyway, you can split any of the services into ITimeParser and ITimeManager or whatever, you can create a new interface called ITextParser, there are a myriad refactoring solutions. But what if you don't have the luxury to refactor and why do you even need to do anything? Surely if you call GetLocation you only need to parse the time, you never call GetTime, and the other way around.

Solution?

  A possible solution is to only actually get the dependency implementation when you use it. Instead of providing the actual implementation for the interface you need, you provide a lazy proxy. Here is an example of a generic (and lazy one liner) LazyProxy implementation:

public class LazyProxy<TInterface>:Lazy<TInterface>
{
    public LazyProxy(IServiceProvider serviceProvider) : base(() => serviceProvider.GetService<TInterface>()) { }
}

  Problem solved, right? LocationService would ask for a LazyProxy<ITimeService> implementation, GetLocation would do _lazyTimeService.Value.ParseTime(input) which would instantiate a TimeService for the first time, which would ask for a LazyProxy<ILocationService> and in GetTime it would use _lazyLocationService.Value.ParseLocation(input) which would get the existing instance of LocationService (if it's registered as Singleton). Imagine either of these services would have needed a lot of other dependencies.

  Now, that's what called a "leaky abstraction". You are hiding the complexity of instantiating and caching a service (and all of its dependencies) until you actually use it. Then you might get an error, when the actual shit hits the actual fan. I do believe that the term "leaky" might have originated from the aforementioned idiom. Yuck, right? It's when the abstraction leaked the complexity that lies beneath.

  There are a number of reasons why you shouldn't do it. Let's get through them.

Criticism

  The most obvious one is that you could do better. The design in the simple and at the same time contrived example above is flawed because each of the services are doing two very separate things: providing a value based on a parameter and interpreting text input. If parsing is a necessary functionality of your application, then why not design an ITextParser interface that both services would use? And if your case is that sometimes you instantiate a class to use one set of functions and sometimes to use another set of functions, maybe you should split that up into two. However, in real life situations you might not have full control over the code, you might not have the resources to refactor the code. Hell, you might be neck deep in spaghetti code! Have you ever worked in one of those house of cards companies where you are not allowed to touch any piece of code for fear it would all crash?

  The next issue is that you would push the detection for a possible bug to a particular point of the execution of your code. You would generate a Heisenbug, a bug that gets reproduced inconsistently. How appropriate this would have been if an IMomentumService were used as well. Developers love Heisenbugs, as the time for their resolution can vary wildly and they would be forced to actually use what they code. Oh, the humanity! Yet, the only problem you would detect early is the cycle in the dependency graph, which is more of a design issue anyway. A bug in the implementation would still be detected when you try to use it. 

  One other issue that this pattern would solve should not be there in the first place: heavy resource use in constructors. Constructors should only construct, obviously, leaving other mechanisms to handle the use of external resources. But here is the snag: if you buy into this requirement for constructors you already use leaky abstractions. And again, you might not be able to change the constructors.

  Consider, though, the way this pattern works. It is based on the fact that no matter when you request the instantiation of a class, you would have a ready implementation of IServiceProvider. The fact that the service locator mechanism exists is already lazy instantiation on the GetService method. In fact, this lazy injection pattern is itself a constructor dependency injection abstraction of the service provider pattern. You could just as well do var timeService = _serviceProvider.GetService<ITimeService>() inside your GetLocation method and it would do the exact same thing. So this is another reason why you should not do it: mixing the metaphors. But hey! If you have read this far, you know that I love mixing those suckers up!

Conclusion

  In conclusion, I cannot recommend this solution if you have others like refactoring available. But in a pinch it might work. Let me know what you think!

  BTW, this issue has been also discussed on Stack Overflow, where there are some interesting answers. 

Update: due to popular demand, I've added Tyrion as a Github repo.

Intro

  Discord is something I have only vaguely heard about and when a friend told me he used it for chat with friends, I installed it, too. I was pleasantly surprised to see it is a very usable and free chat application, which combines feature of IRC, other messenger applications and a bit of Slack. You can create servers and add channels to them, for example, where you can determine the rights of people and so on. What sets Discord apart from anything, perhaps other than Slack, is the level of "integration", the ability to programatically interact with it. So I create a "bot", a program which stays active and responds to user chat messages and can take action. This post is about how to do that.

  Before you implement a bot you obviously need:

  All of this has been done to death and you can follow the links above to learn how to do it. Before we continue, a little something that might not be obvious: you can edit a Discord chat invite so that it never expires, as it is the one on this blog now.

Writing code

One can write a bot in a multitude of programming languages, but I am a .NET dev, so Discord.NET it is. Note that this is an "unofficial" library, so it may not (and it is not) completely in sync with all the options that the Discord API provides. One such feature, for example, is multiple attachments to a message. But I digress.

Since my blog is also written in ASP.NET Core, it made sense to add the bot code to that. Also, in order to make it all clean code, I will use dependency injection as much as possible and use the built-in system for commands, even if it is quite rudimentary.

Step 1 - making dependencies available

We are going to need these dependencies:

  • DiscordSocketClient - the client to connect to Discord
  • CommandService - the service managing commands
  • BotSettings - a class used to hold settings and configuration
  • BotService - the bot itself, which we are going to make implement IHostedService so we can add it as a hosted service in ASP.Net

In order to keep things separated, I will not add all of this in Startup, instead encapsulating them into a Bootstrap class:

public static class Bootstrap
{
    public static IWebHostBuilder UseDiscordBot(this IWebHostBuilder builder)
    {
        return builder.ConfigureServices(services =>
        {
            services
                .AddSingleton<BotSettings>()
                .AddSingleton<DiscordSocketClient>()
                .AddSingleton<CommandService>()
                .AddHostedService<BotService>();
        });
    }
}

This allows me to add the bot simply in CreateWebHostBuilder as: 

WebHost.CreateDefaultBuilder(args)
   .UseStartup<Startup>()
   .UseKestrel(a => a.AddServerHeader = false)
   .UseDiscordBot();

Step 2 - the settings

The BotSettings class will be used not only to hold information, but also communicate it between classes. Each Discord chat bot needs an access token to connect and we can add that as a configuration value in appsettings.config:

{
  ...
  "DiscordBot": {
	"Token":"<the token value>"
  },
  ...
}
public class BotSettings
{
    public BotSettings(IConfiguration config, IHostingEnvironment hostingEnvironment)
    {
        Token = config.GetValue<string>("DiscordBot:Token");
        RootPath = hostingEnvironment.WebRootPath;
        BotEnabled = true;
    }

    public string Token { get; }
    public string RootPath { get; }
    public bool BotEnabled { get; set; }
}

As you can see, no fancy class for getting the config, nor do we use IOptions or anything like that. We only need to get the token value once, let's keep it simple. I've added the RootPath because you might want to use it to access files on the local file system. The other property is a setting for enabling or disabling the functionality of the bot.

Step 3 - the bot skeleton

Here is the skeleton for a bot. It doesn't change much outside the MessageReceived and CommandReceived code.

public class BotService : IHostedService, IDisposable
{
    private readonly DiscordSocketClient _client;
    private readonly CommandService _commandService;
    private readonly IServiceProvider _services;
    private readonly BotSettings _settings;

    public BotService(DiscordSocketClient client,
        CommandService commandService,
        IServiceProvider services,
        BotSettings settings)
    {
        _client = client;
        _commandService = commandService;
        _services = services;
        _settings = settings;
    }

    // The hosted service has started
    public async Task StartAsync(CancellationToken cancellationToken)
    {
        _client.Ready += Ready;
        _client.MessageReceived += MessageReceived;
        _commandService.CommandExecuted += CommandExecuted;
        _client.Log += Log;
        _commandService.Log += Log;
        // look for classes implementing ModuleBase to load commands from
        await _commandService.AddModulesAsync(Assembly.GetEntryAssembly(), _services);
        // log in to Discord, using the provided token
        await _client.LoginAsync(TokenType.Bot, _settings.Token);
        // start bot
        await _client.StartAsync();
    }

    // logging
    private async Task Log(LogMessage arg)
    {
        // do some logging
    }

    // bot has connected and it's ready to work
    private async Task Ready()
    {
        // some random stuff you can do once the bot is online: 

        // set status to online
        await _client.SetStatusAsync(UserStatus.Online);
        // Discord started as a game chat service, so it has the option to show what games you are playing
        // Here the bot will display "Playing dead" while listening
        await _client.SetGameAsync("dead", "https://siderite.dev", ActivityType.Listening);
    }
    private async Task MessageReceived(SocketMessage msg)
    {
        // message retrieved
    }
    private async Task CommandExecuted(Optional<CommandInfo> command, ICommandContext context, IResult result)
    {
        // a command execution was attempted
    }

    // the hosted service is stopping
    public async Task StopAsync(CancellationToken cancellationToken)
    {
        await _client.SetGameAsync(null);
        await _client.SetStatusAsync(UserStatus.Offline);
        await _client.StopAsync();
        _client.Log -= Log;
        _client.Ready -= Ready;
        _client.MessageReceived -= MessageReceived;
        _commandService.Log -= Log;
        _commandService.CommandExecuted -= CommandExecuted;
    }


    public void Dispose()
    {
        _client?.Dispose();
    }
}

Step 4 - adding commands

In order to add commands to the bot, you must do the following:

  • create a class to inherit from ModuleBase
  • add public methods that are decorated with the CommandAttribute
  • don't forget to call commandService.AddModuleAsync like above

Here is an example of an enable/disable command class:

public class BotCommands:ModuleBase
{
    private readonly BotSettings _settings;

    public BotCommands(BotSettings settings)
    {
        _settings = settings;
    }

    [Command("bot")]
    public async Task Bot([Remainder]string rest)
    {
        if (string.Equals(rest, "enable",StringComparison.OrdinalIgnoreCase))
        {
            _settings.BotEnabled = true;
        }
        if (string.Equals(rest, "disable", StringComparison.OrdinalIgnoreCase))
        {
            _settings.BotEnabled = false;
        }
        await this.Context.Channel.SendMessageAsync("Bot is "
            + (_settings.BotEnabled ? "enabled" : "disabled"));
    }
}

When the bot command will be issued, then the state of the bot will be sent as a message to the chat. If the parameter of the command is enable or disable, the state will also be changed accordingly.

Yet, in order for this command to work, we need to add code to the bot MessageReceived method: 

private async Task MessageReceived(SocketMessage msg)
{
    // do not process bot messages or system messages
    if (msg.Author.IsBot || msg.Source != MessageSource.User) return;
    // only process this type of message
    var message = msg as SocketUserMessage;
    if (message == null) return;
    // match the message if it starts with R2D2
    var match = Regex.Match(message.Content, @"^\s*R2D2\s+", RegexOptions.IgnoreCase);
    int? pos = null;
    if (match.Success)
    {
        // this is an R2D2 command, everything after the match is the command text
        pos = match.Length;
    }
    else if (message.Channel is IPrivateChannel)
    {
        // this is a command sent directly to the private channel of the bot, 
        // don't expect to start with R2D2 at all, just execute it
        pos = 0;
    }
    if (pos.HasValue)
    {
        // this is a command, execute it
        var context = new SocketCommandContext(_client, message);
        await _commandService.ExecuteAsync(context, message.Content.Substring(pos.Value), _services);
    }
    else
    {
        // processing of messages that are not commands
        if (_settings.BotEnabled)
        {
            // if the bot is enabled and people are talking about it, show an image and say "beep beep"
            if (message.Content.Contains("R2D2",StringComparison.OrdinalIgnoreCase))
            {
                await message.Channel.SendFileAsync(_settings.RootPath + "/img/R2D2.gif", "Beep beep!", true);
            }
        }
    }
}

This code will forward commands to the command service if message starts with R2D2, else, if bot is enabled, will send replies with the R2D2 picture and saying beep beep to messages that contain R2D2.

Step 5 - handling command results

Command execution may end in one of three states:

  • command is not recognized
  • command has failed
  • command has succeeded

Here is a CommandExecuted event handler that takes these into account:

private async Task CommandExecuted(Optional<CommandInfo> command, ICommandContext context, IResult result)
{
    // if a command isn't found
    if (!command.IsSpecified)
    {
        await context.Message.AddReactionAsync(new Emoji("🤨")); // eyebrow raised emoji
        return;
    }

    // log failure to the console 
    if (!result.IsSuccess)
    {
        await Log(new LogMessage(LogSeverity.Error, nameof(CommandExecuted), $"Error: {result.ErrorReason}"));
        return;
    }
    // react to message
    await context.Message.AddReactionAsync(new Emoji("🤖")); // robot emoji
}

Note that the command info object does not expose a result value, other than success and failure.

Conclusion

This post has shown you how to create a Discord chat bot in .NET and add it to an ASP.Net Core web site as a hosted service. You may see the result by joining this blog's chat and giving commands to Tyr, the chat's bot:

  • play
  • fart
  • use metric or imperial units in messages
  • use Yahoo Messenger emoticons in messages
  • whatever else I will add in it when I get in the mood :)

  When I was looking at Javascript frameworks like Angular and ReactJS I kept running into these weird reducers that were used in state management mostly. It all felt so unnecessarily complicated, so I didn't look too closely into it. Today, reading some random post on dev.to, I found this simple and concise piece of code that explains it:

// simple to unit test this reducer
function maximum(max, num) { return Math.max(max, num); }

// read as: 'reduce to a maximum' 
let numbers = [5, 10, 7, -1, 2, -8, -12];
let max = numbers.reduce(maximum);

Kudos to David for the code sample.

The reducer, in this case, is a function that can be fed to the reduce function, which is known to developers in Javascript and a few other languages, but which for .NET developers it's foreign. In LINQ, we have Aggregate!

// simple to unit test this Aggregator ( :) )
Func<int, int, int> maximum = (max, num) => Math.Max(max, num);

// read as: 'reduce to a maximum' 
var numbers = new[] { 5, 10, 7, -1, 2, -8, -12 };
var max = numbers.Aggregate(maximum);

Of course, in C# Math.Max is already a reducer/Aggregator and can be used directly as a parameter to Aggregate.

I found a lot of situations where people used .reduce instead of a normal loop, which is why I almost never use Aggregate, but there are situations where this kind of syntax is very useful. One would be in functional programming or LINQ expressions that then get translated or optimized to something else before execution, like SQL code. (I don't know if Entity Framework translates Aggregate, though). Another would be where you have a bunch of reducers that can be used interchangeably.

  If you are like me, you want to first establish a nice skeleton app that has everything just right before you start writing your actual code. However, as weird as it may sound, I couldn't find a way to use command line parameters with dependency injection, in the same simple way that one would use a configuration file with IOptions<T> for example. This post shows you how to use CommandLineParser, a nice library that handler everything regarding command line parsing, but in a dependency injection friendly way.

  In order to use command line arguments, we need to obtain them. For any .NET Core application or .NET Framework console application you get it from the parameters of the static Main method from Program. Alternately, you can use Environment.CommandLine, which is actually a string, not an array of strings. But all of these are kind of nudging you towards some ugly code that either has a dependency on the static Environment, either has code early in the application to handle command line arguments, or stores the arguments somehow. What we want is complete separation of modules in our application.

  How can we get the arguments by injection? By creating a new type that encapsulates the simple string array.

// encapsulates the arguments
public class CommandLineArguments
{
    public CommandLineArguments(string[] args)
    {
        this.Args = args;
    }

    public string[] Args { get; }
}

// adds the type to dependency injection
services.AddSingleton<CommandLineArguments>(new CommandLineArguments(args));
// the generic type declaration is superfluous, but the code is easy to read

  With this, we can access the command line arguments anywhere by injecting a CommandLineArguments object and accessing the Args property. But this still implies writing command line parsing code wherever we need that data. We could add some parsing logic in the CommandLineArguments class so that instead of the command line arguments array it would provide us with a strong typed value of the type we want. But then we would put business logic in a command line encapsulation class. Why would it know what type of options we need and why would we need only one type of options? 

  What we would like is something like

public SomeClass(IOptions<MyCommandLineOptions> clOptions) {...}

  Now, we could use this system by writing more complicated that adds a ConfigurationSource and then declaring that certain types are command line options. But I don't want that either for several reasons:

  • writing configuration providers is complex code and at some moment in time one has to ask how much are they willing to write in order to get some damn arguments from the command line
  • declaring the types at the beginning does provide some measure of centralized validation, but on the other hand it's declaring types that we need in business logic somewhere in service configuration, which personally I do not like

  What I propose is adding a new type of IOptions, one that is specific to command line arguments:

// declare the interface for generic command line options
public interface ICommandLineOptions<T> : IOptions<T>
    where T : class, new() { }

// add it to service configuration
services.AddSingleton(typeof(ICommandLineOptions<>), typeof(CommandLineOptions<>));

// put the parsing logic inside the implementation of the interface
public class CommandLineOptions<T> : ICommandLineOptions<T>
    where T : class, new()
{
    private T _value;
    private string[] _args;

    // get the arguments via injection
    public CommandLineOptions(CommandLineArguments arguments)
    {
        _args = arguments.Args;
    }

    public T Value
    {
        get
        {
            if (_value==null)
            {
                // set the value by parsing command line arguments
            }
            return _value;
        }
    }

}

  Now, in order to make it work, we will use CommandLineParser which functions in a very simple way:

  • declare a Parser
  • create a POCO class that has properties decorated with attributes that define what kind of command line parameter they are
  • parse the command line arguments string array into the type of class declared above
  • get the value or handle errors

  Also, to follow the now familiar Microsoft pattern, we will write an extension method to register both arguments and the mechanism for ICommandLineOptions. The end result is:

// extension class to add the system to services
public static class CommandLineExtensions
{
    public static IServiceCollection AddCommandLineOptions(this IServiceCollection services, string[] args)
    {
        return services
            .AddSingleton<CommandLineArguments>(new CommandLineArguments(args))
            .AddSingleton(typeof(ICommandLineOptions<>), typeof(CommandLineOptions<>));
    }
}

public class CommandLineArguments // defined above

public interface ICommandLineOptions<T> // defined above

// full class implementation for command line options
public class CommandLineOptions<T> : ICommandLineOptions<T>
    where T : class, new()
{
    private T _value;
    private string[] _args;

    public CommandLineOptions(CommandLineArguments arguments)
    {
        _args = arguments.Args;
    }

    public T Value
    {
        get
        {
            if (_value==null)
            {
                using (var writer = new StringWriter())
                {
                    var parser = new Parser(configuration =>
                    {
                        configuration.AutoHelp = true;
                        configuration.AutoVersion = false;
                        configuration.CaseSensitive = false;
                        configuration.IgnoreUnknownArguments = true;
                        configuration.HelpWriter = writer;
                    });
                    var result = parser.ParseArguments<T>(_args);
                    result.WithNotParsed(errors => HandleErrors(errors, writer));
                    result.WithParsed(value => _value = value);
                }
            }
            return _value;
        }
    }

    private static void HandleErrors(IEnumerable<Error> errors, TextWriter writer)
    {
        if (errors.Any(e => e.Tag != ErrorType.HelpRequestedError && e.Tag != ErrorType.VersionRequestedError))
        {
            string message = writer.ToString();
            throw new CommandLineParseException(message, errors, typeof(T));
        }
    }
}

// usage when configuring dependency injection
services.AddCommandLineOptions(args);

Enjoy!

Now there are some quirks in the implementation above. One of them is that the parser class generates the usage help by writing it to a TextWriter (default being Console.Error), but since we want this to be encapsulated, we declare our own StringWriter and then store the generated help if any errors. In the case above, I am storing the help text as the exception message, but it's the principle that matters.

Also, with this system one can ask for multiple types of command line options classes, depending on the module, without the need to declare said types at the configuration of dependency injection. The downside is that if you want validation of the command line options at the very beginning, you have to write extra code. In the way implemented above, the application will fail when first asking for a command line option that cannot be mapped on the command line arguments.

As a bonus, here is the way to define an option class that CommandLineParser will parse from the arguments:

// the way we want to use the app is
// FileUtil <command> [-loglevel loglevel] [-quiet] -output <outputFile> file1 file2 .. file10
public class FileUtilOptions
{
    // use Value for parameters with no name
    [Value(0, Required = true, HelpText = "You have to enter a command")]
    public string Command { get; set; }

    // use Option for named parameters
    [Option('l',"loglevel",Required = false, HelpText ="Log level can be None, Normal, Verbose")]
    public string LogLevel { get; set; }

    // use bool for named parameters with no value
    [Option('q', "quiet", Default = false, Required = false, HelpText = "Quiet mode produces no console output")]
    public bool Quiet { get; set; }

    // Required for required values
    [Option('o', "output", Required = true, HelpText = "Output file is required")]
    public string OutputFile { get; set; }

    // use Min/Max for enumerables
    [Value(1, Min = 1, Max = 10, HelpText = "At least one file name and at most 10")]
    public IEnumerable<string> Files { get; set; }
}

Note that the short style of a parameter needs to be used with a dash, the long one with two dashes:

  • -o outputFile.txt - correct (value outputFile.txt)
  • --output outputFile.txt - correct (value outputFile.txt)
  • -output outputFile.txt - incorrect (value utput and outputFile.txt is considered an unnamed argument)

Intro

  As I was working on LInQer I was hooked on the multiple optimizations that I was finding. Do you want to compute the average of an iterable? You would need the total count and the sum of the items, which you can get in a single function that you can reuse to get the sum or the count. But what if the iterable is an integer range between 1 and 10? Then you can compute the sum and you already know the count. Inspired by that work and by other concepts like interval types or Maybe/Nullable types, I've decided to write this post, which I do not know if it will lead to any usable code.

What is an iterable/enumerable?

  In Javascript they call it an Iterable, in .NET you have IEnumerable. They mean the same thing: sources of values. With new concepts like async/await you can use Observables as Enumerables as well, although they are theoretically diametrically opposing patterns. In both languages they are implemented as having a method that returns an iterator/enumerator, an object that can move to the next value, give you the next value and maybe reset itself. You can define any stream of values like that, having one or more values or, indeed, none. From now own I will discuss in terms of .NET nomenclature, but I see no reason why it wouldn't apply to any other language that implements this feature.

  For example an array is defined as an IEnumerable<T> in .NET. Its enumerator will return false if trying to move to the next value and the array is empty, or true if there is at least a value and the current value will return the first value in the array. Move next again and it will return true or false depending on whether there is a next value. But there is no need for the values to exist to have an Enumerable. One could write an object that would return all the positive integer numbers. It's length would be infinite and the values would only be generated when requested. There is no differentiation between an Enumerable and a generator in .NET, but there is in Javascript. For this reason whenever I will use the term generator, I will mean an object that generates values rather than produce them from a source of existing ones.

The NULL controversy

  A very popular InfoQ post describes the introduction of the NULL concept in programming languages a the billion dollar mistake. I am not so sure about that, but I can concede they make good points. The alternative to using a special value to describe the absence of a value is use an "option" object that either has Some value or it has None. You would check the existence of a value by calling a method to tell you if it has a value and you would get the value from the current value property. Doesn't it sound familiar? It's a more specific case of an Enumerator! Another popular solution to remove NULLs from code is to never return values from your methods, but arrays. An empty array would represent no value. An array is an Enumerable!

And that last idea opens up an interesting possibility: instead of one or none, you can have multiple values. What then? What would a multiplication mean? What about a decision block?

The LInQer experience

  If you know me, you are probably fed up with me plugging LInQer as the greatest thing since fire was invented. But that's because it is! And while implementing .NET LInQ as a Javascript library I've played with some very interesting concepts.

  For example, while implementing the Last operator on enumerables, I had two different implementations depending on whether one could know the length in advance and one could use indexed access to the values. An array of one billion values has no problem giving you the last item in it because of two things: you know where the array ends and you can access any item at any position without having to go through other values. You just take the value at index one billion minus one. If you would have a generator, though, the only way to get the last value would be to enumerate again and again and again and only when moving to the next value would fail you would have the last value as the last one. And of course, this would be bad if there are no bounds to the generator.

  But there is more. What about very common statistical values like the sum? This, of course, applies to numbers. The Enumerable need not produce numbers, so in other contexts it means nothing. Then there are concepts like statistical distribution. One can make some assumptions if they know the distribution of values. A constant yet infinite generator of numbers will always have the same average value. It would return the same value, regardless of index.

  I spent a lot of time doing sorting that only needs a part of the enumerable, or partial sorting. I've implemented a Quicksort algorithm that works faster than the default sort when there are enough values and that can ignore the parts of the array that I don't need. Also, there are specific algorithm to return the last or first N items. All of this depends on functions that determine the order of items. Randomness is also interesting, as it needs to take into consideration the change of probabilities as the list of items increases with each request. Sampling was fun, too!

  Then there were operators like Distinct or Group which needed to use functions to determine sameness.

  With all this work, I've never intended to make this more than what LInQ is in .NET: a way to dynamically filter and map and enumerate sequences of items without having to go through them all or to create intermediate but unnecessary arrays. What I am talking about now is taking things further and deeper.

Continuous intervals

  What if the Enumerable abstraction is not enough? For example one could define the interval of real numbers between 0 and 1. You can never enumerate the next value, but there are definite boundaries, a clear distribution of values, a very obvious average. What about series and limits? If a generator generates values that depend on previous values, like a geometric progression or a Fibonacci series, you can sometimes compute the minimum or maximum value of the items in it, or of their sums.  

Tools

  So we have more concepts in our bag now:

  • move next (function)
  • current value
  • item length (could be infinite or just unknown)
  • indexed access (or not)
  • boundaries (min, max, limits)
  • distribution (probabilities)
  • order
  • discreteness

  How could we use these?

Concrete cases

  There is one famous probabilities problem: what are the chances you will get a particular value by throwing a number of dice. And it is interesting because there is a marked difference between using one die or more. Using at least two dice and plotting the values you get after multiple throws you get what is called a Normal distribution, a Gauss curve, and that's because there are more combinations of values that sum up to 6 than there are for 2.

  How can we declare a value that belongs to an interval? One solution is to add all kinds of metadata or validations. But what if we just declare an iterable with one value that has a random value between 1 and 6? And what if we add it with another one? What would that mean?

  Here is a demo example. It's silly and it looks too much like the Calculator demos you see for unit testing and I really hate those, but I do want to just demo this. What else can we do with this idea? I will continue to think about it.

class Program
    {
        static void Main(string[] args)
        {
            var die1 = new RandomGenerator(1, 6);
            var die2 = new RandomGenerator(1, 6);
            // just get the value
            var value1 = die1.First() + die2.First();
            // compose the two dice using Linq, then get value
            var value2 = die1.Zip(die2).Select(z => z.First + z.Second).First();
            // compose the two dice using operator overload, then get value
            var value3 = (die1 + die2).First();
            var min = (die1 + die2).Min();
        }

        /// <summary>
        /// Implemented Min alone for demo purposes
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public interface IGenerator<T> : IEnumerable<T>
        {
            int Min();
        }

        /// <summary>
        /// Generates integer values from minValue to maxValue inclusively
        /// </summary>
        public class RandomGenerator : IGenerator<int>
        {
            private readonly Random _rnd;
            private readonly int _minValue;
            private readonly int _maxValue;

            public RandomGenerator(int minValue, int maxValue)
            {
                _rnd = new Random();
                this._minValue = minValue;
                this._maxValue = maxValue;
            }

            public static IGenerator<int> operator +(RandomGenerator gen1, IGenerator<int> gen2)
            {
                return new AdditionGenerator(gen1, gen2);
            }

            public IEnumerator<int> GetEnumerator()
            {
                while (true)
                {
                    yield return _rnd.Next(_minValue, _maxValue + 1);
                }
            }

            IEnumerator IEnumerable.GetEnumerator()
            {
                return ((IEnumerable<int>)this).GetEnumerator();
            }

            public int Min()
            {
                return _minValue;
            }
        }
        
        /// <summary>
        /// Combines two generators through addition
        /// </summary>
        internal class AdditionGenerator : IGenerator<int>
        {
            private IGenerator<int> _gen1;
            private IGenerator<int> _gen2;

            public AdditionGenerator(Program.RandomGenerator gen1, Program.IGenerator<int> gen2)
            {
                this._gen1 = gen1;
                this._gen2 = gen2;
            }

            public IEnumerator<int> GetEnumerator()
            {
                var en1 = _gen1.GetEnumerator();
                var en2 = _gen2.GetEnumerator();
                while (true)
                {
                    var hasValue = en1.MoveNext();
                    if (hasValue != en2.MoveNext())
                    {
                        throw new InvalidOperationException("One generator stopped providing values before the other");
                    }
                    if (!hasValue)
                    {
                        yield break;
                    }
                    yield return en1.Current + en2.Current;
                }

            }

            IEnumerator IEnumerable.GetEnumerator()
            {
                return ((IEnumerable<int>)this).GetEnumerator();
            }

            public int Min()
            {
                return _gen1.Min() + _gen2.Min();
            }
        }
    }

Conclusion (so far)

I am going to think about this some more. It has a lot of potential as type abstraction, but to be honest, I deal very little in numerical values and math and statistics, so I don't see what I personally could do with this. I suspect, though, that other people might find it very useful or at least interesting. And yes, I am aware of mathematical concepts like interval arithmetic and I am sure there are a ton of existing libraries that already do something like that and much more, but I am looking at this more from the standpoint of computer science and quasi-primitive types than from a mathematical or numerical perspective. If you have any suggestions or ideas or requests, let me know!

  You can consider this an interview question, although to be fair if someone did ask me this for an interview I would say they are assholes. What is the difference between the pre-increment operator and the post-increment operator in C#?

  They look the same in C and C# and Javascript and Java and all the languages that share the curly bracket syntax with C, but in fact they are slightly different. Slight enough to make someone an asshole for asking the question as if it were relevant, but important enough for you to read about it. One of the most common interpretations of the syntax is that x++ is incrementing the value after the operation, while ++x is incrementing it before the operation. That is wrong.

  In fact, for C++ the return values are different between pre and post operators. I am not a C++ dev, so I give you this reference link: "Pre operators increment or decrement the value of the object and return a reference to the result. Post operators create a copy of the object, increment or decrement the value of the object and return the copy from before the increment or decrement." So one returns an object, the other returns a reference to an object. It is also possible that the assignment be done after the value was produced in C or C++. In C# the assignment must be done before any value is returned.

  In C#, to paraphrase Eric Lippert, "Both pre and post operators determine the value of the variable, what value will be assigned back to storage and assign the new value to storage. The postfix operator produces the original value, and the prefix operator produces the assigned value." So it's (kindda) like this piece of code:

int Increment(ref int x, bool post) {
  var originalX = x;
  var newX = x+1;
  x = newX;
  return post ? originalX : newX;
}

  So why the hell does it matter? I mean, it's a rather meaningless difference between the programming languages and the before/after mnemonic is making the code pretty clear, doesn't it? OK. Let's try some code and let me see how fast you come up with the answer. Remember, this is supposed to be simple, so if you are thinking too much about it, it doesn't matter you get the correct answer. Ready?

  1. Any difference between x++ and ++x if the resulting value is not used?
  2. var a=1; var b=++a; What's the value of b?
  3. var a=1; var b=a++; var c=++a; What's the value of c?
  4. var i = 0; for (i=0; i<5; ++i) Console.Write(i+" "); Console.WriteLine(i); What is printed at the console?
  5. var i = 0; for (i=0; i<5; i++) Console.Write(i+" "); Console.WriteLine(i); What is printed at the console?
  6. var a=1; a=a++; What's the value of a?

And all of this was about the increment operator as normally used for integer values. There is a big part about operator overloading in there, but I believe less relevant in the context of differences between pre and post increment/decrement operators.

There is one important part to discuss, though, and that is best code practices. When to use post and when to use pre. And they are really easy: separate statements from expressions! Statements execute code with side effects, they should return nothing. Expressions return values without side effects. If you never use the value of an increment or decrement and instead use it as a statement with side-effects, there is no difference between ++a and a++. In fact one doesn't need the preincrement/predecrement operators at all! In this context, the answers for the questions above is 1. No 2,3,6: You are using it wrong! 4,5: the same thing, since without getting the value we have scenario 1.

Just for reference, though, here are the answers:

  1. No
  2. 2
  3. 3 (b is 1)
  4. 0 1 2 3 4 5
  5. 0 1 2 3 4 5
  6. 1

Hope that makes you think.

Intro

  This is part of a series that I plan to build on as time goes on: technical interview questions, dissected and laid bare for both interviewers and interviewees. You can also check out the previous one: Interview question: all items in table A but not in B.

  This question is a little bit more complex and abstract at the same time. The post is written more for interviewers this time, because as candidates go, you need to read the links in it if you didn't know the concepts in it. This also is not a question with a single correct answer. It comes after asking about Dependency Injection as a whole and the candidate answering correctly.

  I expect senior developers to be able to go through this successfully, it is not a test for junior developers, although depending on their previous experience juniors might be able to go through it and seniors be force to reason through it.

The test

Bonus introduction question: why use DI at all? Expected answers would be separation of concerns and testability. 

  The question has two steps.

Step 1: given the following code in a legacy application, improve it to use Dependency Injection:

public SomeClass {
  public List<Item> GetItems(int days, string filter) {
    var service = new ItemService();
    return service.GetItems()
      .Where(i => i.Time >= DateTime.Now.AddDays(-days));
  }
}

Bonus questions:

  • has the candidate worked with LINQ before?
  • what does the code do?

Now, this question is about programming knowledge as it is for attention. There are three irregularities that can attract that attention:

  • the most obvious: the service is being instantiated by calling the constructor
    • the interviewer expects at the very least for the candidate to notice it and suggest moving the instantiation of the service in the constructor of the SomeClass class and inject it instead of using new
    • there is the possibility of passing the service as a parameter, as well, but suggest that the signature of the method should remain the same to get around it. Anyway, one can discuss the idea of moving all dependencies to the constructor and/or the calling methods and get insight in the way the candidate is thinking.
  • the unexplained string filter in the signature of the method
    • the interviewer can either tell the candidate that it will become relevant later, because it will, or that this is a method that implements an interface, to which a more snarky candidate might reply that SomeClass implements nothing (bonus for attention)
  • the use of DateTime.Now
    • it is a static property that gives a different output every time so it should be taken into account for Dependency Injection or at least for unit testing

By now you have filtered out the majority of failing candidates and you are left with someone who used or at least understands DI, can read and understand code, has used or at least understood basic LINQ and you have also gauged their level of attention to detail.

If the candidate only talked about the service and they decided to create an interface for ItemService and then add it as a parameter for the constructor of SomeClass, ask them to write a unit test for the method, explain to them that testability is one of the goals of DI if you didn't cover this already

  • bonus: see if they do unit testing or at least understand the concept
  • if they do attempt to write the unit test, ask them what would happen if you would run the test in different days

The expected result of this part is that the candidate understands the need of abstracting DateTime.Now. It is interesting to note how they intend to abstract it, since they do not have access to the code and it is a static method/property to abstract.

Whether the candidate figured it out by themselves or it was explained to them, the expected answer is that DateTime.Now is abstracted by creating an IDateTimeService interface that is implemented as a wrapper over DateTime.

At this point the code should look like this:

public SomeClass {
  private IItemService _itemService;
  private IDateTimeService _dateTimeService;

  public SomeClass(IItemService itemService, IDateTimeService dateTimeService) {
    _itemService = itemService;
    _dateTimeService = dateTimeService;
  }

  public List<Item> GetItems(int days, string filter) {
    return _itemService.GetItems()
      .Where(i => i.Time >= _dateTimeService.Now.AddDays(-days));
  }
}

Also, the candidate should be asked to write a unit test, just to see they know how, for bonus points. Note if the candidate understands isolation for unit testing or does something that would work but be silly like generate the test data based on current date or duplicate the code logic in the test instead of working with static data.

Step 2: tell the candidate that the legacy code they need to fix looks a bit different:

public SomeClass {
  public List<Item> GetItems(int days, string filter) {
    var service = new ItemService(filter);
    return service.GetItems()
      .Where(i => i.Time >= DateTime.Now.AddDays(-days));
  }
}

The ItemService now receives the filter as the parameter. Ask them what to do in this case.

The expected answer is a factory injected instead of the service, which will then be used to instantiate an IItemService with a parameter. Bonus discussion about software patterns can be inserted here.

There are other valid answers here, like using the DI container itself as a factory for the service, which might provoke interesting discussions in itself, like weighing constructor injection versus service provider in dependency injection and whether hybrid solutions might be better.

Bonus question: what if you cannot control the code of ItemService in step 1 and it does not implement an interface or a base class?

  • warning, this might give a hint for the second part of the interview, so use it at the end 
  • correct answer 1: use the class as the type of the parameter and let the dependency container decide how to instantiate it
  • correct answer 2: use a wrapper over the class that implements the interface and proxies to the instance methods.

Conclusion

For me this test told me a lot more about the candidate than just their dependency injection knowledge. We got to talking, I became aware of how their minds worked and I was both pleasantly surprised when they came with alternate solutions that kind of worked and a bit irked that they went that far and didn't see the superior option. Most of the time this made me think about the differences between what I would answer and what they did and this resulted in interesting discussions that enriched not only their experience, but also mine.

Dependency injection, separation of concerns and unit testing are important concepts for any modern developer. I hope this helps devs evolve and interviewers find the best candidates... at least until all of them get to read my blog.

  This is something that appeared in C# 5, so a long time ago, with .NET 4.5, but I only found out about it recently. Remember when you wanted to know the name of a property when doing INotifyPropertyChanged? Or when you wanted to log the name of the method that was calling? Or you wanted to know which line in which source file is responsible for calling a certain piece of code? All of this can be done with the Caller Information feature.

  And it is easy enough to use, just decorate a method parameter with an explicit default value with any of these three attributes:

The parameter value, if not set when calling the method, will be filled in with the member name or file name or line number. It's something that the compiler does, so no overhead from reflection. Even better, it works on the caller of the method, not the interior of the method. Imagine you had to write a piece of code to do the same. How would you reference the name of the method calling the method you are in?

Example from Microsoft's site:

public void DoProcessing()
{
    TraceMessage("Something happened.");
}

public void TraceMessage(string message,
        [System.Runtime.CompilerServices.CallerMemberName] string memberName = "",
        [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "",
        [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
{
    System.Diagnostics.Trace.WriteLine("message: " + message);
    System.Diagnostics.Trace.WriteLine("member name: " + memberName);
    System.Diagnostics.Trace.WriteLine("source file path: " + sourceFilePath);
    System.Diagnostics.Trace.WriteLine("source line number: " + sourceLineNumber);
}

// Sample Output:
//  message: Something happened.
//  member name: DoProcessing
//  source file path: c:\Visual Studio Projects\CallerInfoCS\CallerInfoCS\Form1.cs
//  source line number: 31