Using array destructuring and recursion to make your JavaScript algorithms shine

JavaScript if far from being the best-designed language in the world. I personally often feel myself like in the mine field when coding in it. But it evolves and gets better and better. I can increasingly better express the ideas in JavaScript and I feel it becomes truly powerful and pretty pleasant language to use. Here, I want to share how today one can calculate the sum of the array of numbers. The example is contrived but this example is always used in the schools to teach programming and usually, students are taught to create an accumulator variable and then iterate and accumulate the sum in that variable. How procedural is this! Now, look at what you can do with JavaScript today:

No variables, no loops, pure simplicity. It might be not very efficient code, but very simple and functional one.

Another example. I have found a quicksort implementation in JavaScript on the web (you can skip it, it is just for illustration):

It is totally procedural and very difficult to understand. Now, here is my alternative implementation, using recursion and latest JavaScript features:

So clear, so simple and again no loops or variables. Love it. Again, performance is not great here, but I am biased towards code simplicity and optimizing only when absolutely necessary.

Facebooktwittergoogle_pluslinkedinmailFacebooktwittergoogle_pluslinkedinmail

Updating an immutable object in TypeScript

Recently I could not figure out how to types-safely update immutable object in TypeScript. The problem is that in JavaScript the object spread feature is used for this task, like so:

But if you have accidentally missspelled the property you want to update, object spread will add a new propery instead of updating old one:

So I asked StackOverflow for help and got an excellent answer to use a helper function:

Now if I want to update my point but make a mistake – I get a compiler error:

All is great now, but someone on StackOverflow asked to explain each line of this update function. It is not simple indeed and uses latest TypeScript features. The author did not respond, so I will try to explain it here.

The most complex line is first one:

function update<T, K extends keyof T>(obj: T, updateSpec: Pick<T, K>): T {

This line incorporates two pretty complex typescript features: generics and indexed type query. I highly recommend clicking links provided in the previous sentence and reading articles provided by TypeScript official documentation, which is great. But here is my shallow explanation.

A generic type is the type which is not known when the function is defined but only becomes know when the function is used somewhere in the code (all is at development time, not runtime). For example in the given update function the type T is not known, when function is defined, but at this point o1 = update(o1, {y:1}); the type T becomes of type Point. So, for now, we know that in this particular call, function update will take a Point and will also return a Point.

Indexed type query gives you an ability to query at compile-time the names of the properties of some type. For example, type PointProperties = keyof Point; // "x" | "y". That is from the variable of type Point we can query the property named x or y or both. So the expression K extends keyof T means in our case that generic type K must be something compatible with "x" | "y":

Ok, now we know exactly the type constraints of update function, but what is Pick<T, K>? It is the type, added to TypeScript standard library in version 2.1 and is mapped type:

You can think of it as a type which consists of a subset of properties of type T, described by K. So when we have a point defined this way: interface Point { x: number, y: number }, the type Pick<Point,"x"> is basically {x:number} and Pick<Point,"x" | "y"> is { x: number, y: number }

Hence to conclude, the first line of the function just tells its name and that it takes as the first parameter the value of unconstrained type T, returned value is of the same type. And the second argument must be some type, which contains any subset of properties, defined in T. So, if you want to update the Point, the only eligible values for the second parameter of update are: { y: 1 }, { x: 1 }, {}, { y:1, x:1 } (note: number 1 is arbitrary here, any number will do; if compiler option --strictNullChecks is not on, then values undefined and null are also eligible).

All other lines are not nearly as interesting :-). Second line: const result = {} as T just creates creates an empty object and tells TypeScript to treat it as the value of type T. Third line Object.keys(obj).forEach(key => result[key] = obj[key]) is pure JavaScript which copies all properties from input object obj to the result object. Fourth line Object.keys(updateSpec).forEach((key: K) => result[key] = updateSpec[key]) does the same for updateSpec, this actually replaces old values of obj with new ones from updateSpec. And finally the function returns: return result;.

Facebooktwittergoogle_pluslinkedinmailFacebooktwittergoogle_pluslinkedinmail

Angular 1.x has no dependencies and therefore it’s OK to include it with Webpack’s noParse option. So wrong.

Angular 1.x has no dependencies and therefore it’s OK to include it with Webpack’s option noParse. This idea I have learnt in the great online screencast (Russian) devoted to Webpack. The option noParse instructs Webpack not to analyze the source code of the included program and not to inject any dependencies to it. This can boost the performance when dealing with big libraries which have no dependencies and export global variables to communicate with other parts of the system. And indeed, Angular is huge, it works without any dependencies and exports global variable.

So I optimized my Webpack process with not parsing Angular and later lost 1.5 working days trying to understand why my system did not work. I had included two other modules jstree, which is a jQuery plugin and the Angular wrapper over jstree, ng-js-tree. Of course, JQuery was also involved and things just exploded:

The thing is, Angular HAS dependency! It is tricky, though. This dependency is JQuery, but if you don’t provide jQuery it will use it’s internal lighter version of JQuery named JQLite and will silently continue working. Here is the Angular’s source code proving that.

So here is what happened under Webpack’s control: 1) JQuery was initialized; 2) jstree was initialized and attached to the JQuery; 3) Angular was initialized, but since it was checking for window.jQuery and it was undefined, Angular was initialized with its internal beast JQLite. window.jQuery was undefined because Webpack does not allow globals, it manages global variables like jQuery on its own and passes them to modules which mention those variables in their source code. But that source code must be parsed first, and I had noParse for Angular :-). 4) ng-js-tree was initialized but with the DOM element wrapped by JQLite, not by real JQuery to which jstree was attached. 5) the miserable crash happened when ng-js-tree tried to access DOM element, provided to it, assuming that was JQuery DOM element while it was JQLite DOM element.

Hence, be careful when you optimize your Webpack with a noParse option for some module. Even if that module works just fine without any dependencies, there might be some complex interdependencies which will make you cry like in my case it was with Angular, JQuery, jstree, and ng-sj-tree.

Facebooktwittergoogle_pluslinkedinmailFacebooktwittergoogle_pluslinkedinmail