Wednesday, December 23, 2015

Discovering a Trove of Java Primitives Collection Handling

While reading the blog post 5 Tips for Reducing Your Java Garbage Collection Overhead, I was reminded of the existence of a small Java collection library called Trove that "provides high speed regular and primitive collections for Java." I am especially interested in the ability to apply Trove to allow for collections of primitives rather than requiring elements in collections to be full-fledged reference objects. I look at Trove in greater detail in this post.

The JDK's standard collections respect generics and require object references for their elements and do not allow for storing of primitives in the collections. Even code that appears to be placing primitives in the standard JDK collections is actually placing object references in the collection via autoboxing. The advantage of this generics approach is the ability to have the same classes and methods work on objects of many different types. The cost is the need to store full reference objects even when leaner primitives could be stored.

The Trove library has an LPGL license and is relatively small (well under 10 MB) as shown in the next screen snapshot of the Downloads page:

The small download contains more than just the necessary library in JAR format. It also contains documentation and source. The library JAR itself (trove-3.1a1.jar in this case) is around 2.5 MB in size.

One of the reasons that Trove is easy to use is that it largely mimics the JDK collections' interfaces in its own collections' APIs. The next code listing demonstrates how adding values to a List implementation is essentially the same API calls whether using a JDK 7 List (ArrayList in this case) or the Trove-provided TDoubleArrayList.

Adding Elements to JDK's ArrayList and Trove's TDoubleArrayList

/**
 * Demonstrate standard JDK {@code ArrayList<Double>}
 * with some JDK 8 functionality.
 */
public void demonstrateJdkArrayListForDoubles()
{
   final ArrayList<Double> doubles = new ArrayList<>();
   doubles.add(15.5);
   doubles.add(24.4);
   doubles.add(36.3);
   doubles.add(67.6);
   doubles.add(10.0);
   out.println("JDK ArrayList<Double>:");
   out.println("\tDoubles List: " + doubles);
   out.println("\tMaximum double: " + doubles.stream().max(Double::compare));
   out.println("\tMinimum double: " + doubles.stream().min(Double::compare));
   out.println("\tSum of doubles: " + doubles.stream().mapToDouble(Double::doubleValue).sum());
}

/**
 * Demonstrate use of TDoubleArrayList and show how
 * similar using it is to using {@code ArrayList<Double>}.
 */
public void demonstrateTroveArrayListForDoubles()
{
   // Demonstrate adding elements to TDoubleArrayList is
   // exactly like adding elements to ArrayList<Double>.
   final TDoubleArrayList doubles = new TDoubleArrayList();
   doubles.add(15.5);
   doubles.add(24.4);
   doubles.add(36.3);
   doubles.add(67.6);
   doubles.add(10.0);
   out.println("Trove TDoubleArrayList:");  // TDoubleArrayList overrides toString()
   out.println("\tDoubles List: " + doubles);
   out.println("\tMaximum double: " + doubles.max());
   out.println("\tMinimum double: " + doubles.min());
   out.println("\tSum of doubles: " + doubles.sum());
}

The above code listing also demonstrates how easy it is with the Trove implementation of an array list to access the maximum, minimum, and sum of the collection of doubles. One of the advantage of these collections written to a specific primitive data type (double in this case) is that methods that apply specifically to that data type can be provided in the implementation. While it might not make a lot of sense for a collection of String or a collection of an arbitrary object return maximum, minimum, and sums, the meaning of these methods is obvious for a collection devoted to doubles such as TDoubleArrayList. The above listing does indicate how the same can be accomplished with JDK 8 using streams.

One subtle difference that may not be obvious (due to autoboxing) when looking at the code listing above is that the JDK implementation ArrayList stores reference Double objects while the Trove TDoubleArrayList implementation stores primitive doubles. Trove supplies implementations of lists, sets, and maps for various numeric types such as bytes, characters, shorts, integers, longs, floats, and doubles.

One of the interesting data structures/collections provided by Trove is the TDoubleArrayStack. Backed by the just-demonstrated TDoubleArrayList, the TDoubleArrayStack does not expose add methods in its API for adding elements. Rather, its methods reflect semantics one would expect in a last-in-first-out (LIFO) stack implementation: push(double) to add, pop() to access and remove the mostly recently added entry, and peek() to see the most recently added entry without removing it. Application of this stack implementation is shown in the next code listing. There are stack implementations for other numeric data types as well.

Trove's TDoubleArrayStack

/**
 * Demonstrate Trove's Double Array Stack.
 *
 * Trove's TDoubleArrayStack allows access to its
 * contents via push, pop, and peek.
 */
public void demonstrateTroveDoubleArrayStack()
{
   final TDoubleArrayStack stack = new TDoubleArrayStack();
   stack.push(15.5);
   stack.push(17.3);
   stack.push(16.6);
   stack.push(2.2);
   out.println("Trove Array Stack of Doubles");
   out.println("\tPeek: " + stack.peek() + "; After Size: " + stack.size());
   out.println("\tPop:  " + stack.pop() + "; After Size: " + stack.size());
   out.println("\tPeek: " + stack.peek() + "; After Size: " + stack.size());
}

Although not shown here, Trove also supports first-in-first-out (FIFO) queue structures for Java's primitive types in its gnu.trove.queue package. Classes in this package provide methods adhering to queue semantics: offer, poll, and peek.

The java.util.Collections class provides much useful functionality when working with JDK collections. Trove provides a subset of java.util.Collections's functionality for working with Trove-based collections in its own class called gnu.trove.TCollections. Specifically, at the time of this writing, the TCollections class provides support for synchronized and unmodified Trove collections. The next code listing demonstrates using TCollections and also demonstrates using a Trove collection oriented toward a data type other than double (int in this case) and to a different data structure type (linked list).

TCollections and TIntLinkedList Demonstrated

/**
 * Demonstrate one of Trove's "equivalent"s of the
 * java.util.Collections class.
 */
public void demonstrateTroveCollectionsClass()
{
   final TIntLinkedList integers = new TIntLinkedList();
   integers.add(5);
   integers.add(7);
   integers.add(3);
   integers.add(1);
   final TIntList unmodifiableIntegers = TCollections.unmodifiableList(integers);
   try
   {
      unmodifiableIntegers.add(15);
   }
   catch (Exception ex)
   {
      out.println("\tException caught: " + ex);
   }
}

When one wishes to iterate over a Trove-based collection, one can access it via a traditional iterator as shown in the next code listing. Although the collection and associated iterator work on long values in this example, Trove provides similar collections and iterators for Java's other primitive data types.

Using Trove Iterator to Iterate Trove Collection

/**
 * Demonstrate "traditional" iteration of a
 * Trove collection.
 */
public void demonstrateIterationWithIterator()
{
   final TLongHashSet longs = new TLongHashSet();
   longs.add(15);
   longs.add(6);
   longs.add(12);
   longs.add(13);
   longs.add(2);
   TLongIterator longIterator = longs.iterator();
   while (longIterator.hasNext())
   {
      final long longValue = longIterator.next();
      out.println(longValue);
   }
}

An alternate approach for iterating a Trove collection is to use a Procedure. This is demonstrated in the following two code listings. The first listing demonstrates a custom long-oriented Procedure and the second listing demonstrates applying that custom Procedure to iteration on a TLongLinkedList via its forEach method.

Using Trove Procedure to Iterate Trove Collection

/**
 * Demonstrate iteration of a Trove collection
 * using a Procedure.
 */
public void demonstrateIterationWithProcedure()
{
   final TLongLinkedList longs = new TLongLinkedList();
   longs.add(15);
   longs.add(6);
   longs.add(12);
   longs.add(13);
   longs.add(2);
   longs.forEach(new StandardOutputLongProcedure());
}

Procedure Implementation Used in Previous Iteration Example


package dustin.examples.trove;

import static java.lang.System.out;

import gnu.trove.procedure.TLongProcedure;

/**
 * Simple implementation of TLongProcedure that
 * iterates over Trove collection of {@code long}
 * values and writes those values to standard
 * output with one value per line.
 */
public class StandardOutputLongProcedure implements TLongProcedure
{
   @Override
   public boolean execute(long longValue)
   {
      out.println(longValue);
      return true;
   }
}

It's worth noting that Trove collections tend to provide forEachDescending methods as well to provide iteration in reverse order.

Additional Observations Related to GNU Trove

  • GNU Trove is a library providing "high speed regular and primitive collections for Java" and should not be confused with Trove that is a "Database as a Service for OpenStack."
  • The Trove collections and data structures all have names prefixed with "T" (for Trove). In fact, all the classes and interfaces in Trove start with "T" except HashingStrategy, IdentityHashingStrategy, and Version.
  • Trove collections generally provide a constructor accepting an array of their underlying data type and provide toArray() methods to provide their data elements in form of array of primitives.
  • Trove collections generally provide explicitly overridden toString() implementations that allow for the individual data elements to be easily written similar to JDK collections and differently than Java arrays (which require Arrays.toString() methods).
  • Additional Trove details can be found in the Overview, the FAQ, and the message forums. Other resources include Enhance Collection Performance with this Treasure Trove, Java HashMap Performance, High Performance Libraries in Java, and TROVE – High Performance Collections for Java.
  • Trove's Java packages are organized generally by data structure type with all primitive type specific implementations for a given data structure type in the same package. For example, packages are named like gnu.trove.list, gnu.trove.set, and so on.
  • Because each Trove collection is specific to a particular primitive data type, each collection does not require a generic parameter and has none of the issues related to generics (such as erasure). This approach also allows each collection to support methods specific to the data type that is stored in that collection. For example, collections of numeric types can provide sum methods while collections specific to character types can provide grep methods.

Conclusion

In many common uses, the JDK-provided collections will perform sufficiently well and storing the object references may not be an issue. However, there are cases where the ability to use Trove collections and particularly to store primitives rather than object references may provide necessary advantage. The advantage of storing primitives rather than their equivalent object references in collections becomes more obvious as the collection gets larger.

Friday, December 18, 2015

Packt Publishing and Udemy 2015-Ending Sales

As has become an annual tradition, Packt Publishing has all of its e-books and e-videos on sale for $5 (USD) each, presumably for a limited time.

Packt-affiliated Udemy.com is hosting a similar promotion and offering their online courses for $15 each (which can be a significant savings over the list price of each). As the image below shows, this sale on Udemy courses ends at 11:59 pm (PST) on Christmas Eve (December 24, 2015).

I recently viewed the Udemy video course Learning JavaScript Data Structures and Algorithms and my review is available on their site. I have reviewed several Packt e-books and a few Packt videos in the past and many of those reviews are listed next.

E-books

Videos

Monday, December 14, 2015

Book Review: Learning Underscore.js

The purpose of Alex Pop's Learning Underscore.js (Packt Publishing, October 2015) is to "explore the Underscore.js library using a test-driven development approach." There are seven chapters in this book on Underscore.js covering just under 200 substantive pages.

Preface

The Preface of Learning Underscore.js discusses JavaScript's recent surge in popularity and the role of Underscore.js in that rising popularity. The author states, "For a JavaScript developer, Underscore is the JavaScript-based library that can be used to create code that runs everywhere or as a foundation for adopting a functional programming style."

The "What this book covers" section of the Preface provides brief summaries of each of the book's seven chapters. The "Who this book is for" section states that the book is for "developers with fundamental JavaScript knowledge who want to use modern JavaScript libraries to advance their programming skills." You can find the full content of these two sections of the Preface in the author's blog post Announcing my upcoming book "Learning Underscore.js".

The Preface also has a section "What you need for this book" that a Node.js installation and text editor or IDE supporting JavaScript are the necessary tools for working with the book's examples.

Chapter 1: Getting Started with Underscore.js

The initial chapter of Learning Underscore.js "introduces you to Underscore and explains the main problems addressed by this library together with a quick introduction to functional programming." The chapter also opens by stating it is assumed that the reader knows "JavaScript programming fundamentals and how to create basic web pages using HTML, CSS, and jQuery." The chapter states that it is Underscore 1.8.3 covered in this book and that Underscore "provides an extensive set of functions that simplify and enhance handling of JavaScript objects, arrays, and functions ... by providing missing functional programming features to JavaScript."

Chapter 1 explains Underscore's original rise to prominence based on its "support for some of the functionality introduced by ECMAScript 5" that "made it a useful library for web applications targeting older browsers ... and for developers that wanted to write code that was based on ES5 without worrying about browser support." The section goes onto explain that this is not Underscore's primary use anymore and that a library such as es5-shim is better suited for that. The chapter uses this discussion to point out, "All of this book's examples assume that they are executed against a JavaScript version that is ES5 compliant."

The first chapter features a section called "Getting started with Underscore by example" that uses examples to introduce Underscore's features, capabilities, and advantages over straight ECMAScript 5 (JavaScript). The first examples contrast implementing "find" capability with forEach calls versus using Underscore's find. The Underscore global object and its default name reference (_) are introduced in the context of these first two examples.

Other examples in Chapter 1 illustrate Underscore's support for functions countBy, pairs, each, map, and reduce. Because these last few Underscore functions are functional in nature, it's a natural fit or this section of the first chapter to provide brief background on "functional programming style."

The section of Chapter 1 called "Useful patterns and practices for JavaScript applications targeting ECMAScript 5" introduces "some JavaScript patterns and practices" that are "essential when writing ES5 code, but you don't need them when writing ES6 code using classes and modules." Topics in this section include dealing with JavaScript's hoisting and the "difficult problem" of global scope with immediately-invoked function expression and revealing module pattern. The chapter also introduces JavaScript's strict mode.

The final major section of the first chapter, "Setting up a development workflow for exploring Underscore," introduces several key components of a "development workflow that is popular with JavaScript developers." These include discussion of installing Node.js with Node Package Manager (npm) on Windows, Linux, and Mac OS X. This section also describes managing dependencies with Bower, choosing a JavaScript editor (such as WebStorm, Cloud9, Node.js Tools or Visual Studio, Sublime Text, and Atom), and testing with Jasmine.

Chapter 2: Using Underscore.js with Collections

The second chapter of Learning Underscore.js revisits the "key Underscore functions" each, map, and reduce introduced in the first chapter. Concepts such as "JavaScript reflection like techniques" and duck typing are discussed in this context.

Chapter 2 delves into searching with Underscore and introduces Underscore functions some, findWhere, and contains in addition to revisiting find. Similarly, the second chapter's dive into sorting looks at Underscore functions filter, where, reject, partition, and every.

The first chapter had introduced an example of an aggregate function (reduce) and of a transformation function (map). The second chapter defines the difference between these two types of functions, delves more deeply into how to apply both of these types of functions, and introduces new Underscore functions of each type. The newly introduced aggregation functions are max, min and the newly introduced transformation functions are sortBy, groupBy, and indexBy.

Chapter 3: Using Underscore.js with Arrays, Objects, and Functions

Chapter 3 of Learning Underscore.js begins by looking at some array-specific functions provided by Underscore: first, rest, last, initial, union, intersection, difference, and zip. It also looks more briefly at several other "array-related functions."

The third chapter's section "Objects" opens with the sentence, "Underscore has a series of dedicated functions targeting objects, which extends the features provided for collections." Functions covered (code listings and explanations) in this section include keys, allKeys, values, invert, pairs, contains, pick, omit, extend, clone, has, property, propertyOf, matcher, isEqual, and isMatch. This section also looks at "assertion functions" for "object validation," "determining object types," for String objects, and for Number objects.

Chapter 3's section "Functions" opens with the sentence, "Underscore has a series of functions that specifically target objects of the type Function: it has functions that target other functions." The section discusses bind, bindAll, partial, memoize, wrap, negate, compose, delay, throttle and debounce, once, after, and before. The third chapter ends with a list o miscellaneous utility functions each with very brief descriptions.

Chapter 4: Programming Paradigms with Underscore.js

The first three chapters of Learning Underscore.js provided an "overview of most of the Underscore features" and the fourth chapter looks at using Underscore in object-oriented and functional paradigms. The chapter states, "JavaScript is a dynamic multi-paradigm programming language that can be used with an imperative, object-oriented, or functional programming style." The chapter provides an overview of the object-oriented paradigm as it pertains to ECMAScript 5 and ECMAScript 6 versions of JavaScript before looking at "Using Underscore with the object-oriented programming paradigm." The stated objective of this section is to demonstrate that "the Underscore object-related functions [can help] us build a class implementation that should feel familiar to developers coming from a class-based OOP language."

Chapter 4 also looks at "the functional programming paradigm," looks at what it takes to migrate from an object-oriented paradigm to a functional-oriented paradigm in JavaScript, and then looks at "functional programming with Underscore.js." The chapter explains that Underscore provides "built-in support" for the "method-chaining concept" with the chain, map, and tap functions.

Chapter 5: Using Underscore.js in the Browser, on the Server, and with the Database

Learning Underscore.js's fifth chapter looks at using Underscore in the contexts of browser (Underscore templates), server (Node.js), and database (MongoDB and PostgreSQL).

The fifth chapter's discussion of using Underscore in the browser looks at using Bootstrap as a "frontend design framework" and the looks at how applying Underscore templates enables creation of "a better solution." Chapter 5's look at JavaScript on the server provides more information on using Node.js before describing how to "[convert] JavaScript code to Node.js modules."

The "Using Underscore with MongoDB" section of the fifth chapter introduces that "popular document database" and provides a high-level overview of MongoDB conceptually and compares and contrasts this NoSQL implementation with relational databases. The section looks at how MongoDB makes use of JavaScript and describes how to install MongoDB on Windows, Ubuntu Linux. and Mac OS X. This section also explains how to configure and run MongoDB and then provides an example of using the MongoDB JavaScript API and the MongoDB JavaScript shell. There are several pages explaining and demonstrating application of the "MongoDB Node.js driver."

Chapter 5 also has a section called "Using Underscore with PostgreSQL" that introduces PostgreSQL's support for "JavaScript as a procedural language through the PL/v8 project." This section describes how to install and configure PostgreSQL, how to install PostgreSQL on the same three operating systems as shown earlier for MongoDB, and "using psql with basic database commands." The section also looks at PostgreSQL data types before delving into details regarding PostgreSQL's jsonb type.

Being a fan of the PostgreSQL database, I particularly enjoyed this section on using JavaScript with PostgreSQL and especially liked the section on "using PostgreSQL with plv8." This section first shows use of JavaScript to write PostgreSQL stored functions and then shows how to use Underscore with those implementations.

Chapter 6: Related Underscore.js Libraries and ECMAScript Standards

The focus of Chapter 6 of Learning Underscore.js is on libraries that are "alternative and complementary" to Underscore.js and on Underscore.js's "relationship with JavaScript standards and how to write the ECMAScript 2015 (ES6) code." The chapter explains that the alternative and complementary libraries can be desirable because Underscore itself is relatively small.

Underscore-contrib is introduced in this sixth chapter. The chapter explains the relationship of Underscore to Underscore-contrib and provides "an overview of Underscore-contrib functionality." It covers select functions from the sub-libraries provided by Underscore-contrib, discusses installing Underscore-contrib, and provides a couple of examples of applying Underscore-contrib.

The lodash library is also introduced in Chapter 6 as a JavaScript library originally forked from Underscore that focuses "on better performance, improved consistency across browsers, and enhanced code readability." This section outlines how lodash varied originally from Underscore and eventually became incompatible with Underscore. The section also provides an "overview of lodash functionality" that compares and contrasts some of Lodash's functions with similar ones in Underscore.

It surprised me a bit that a book about Underscore and with "Underscore" in the title mentioned ways in which lodash might be considered superior to Underscore. There is even a section in Chapter 6 on "migrating a project from Underscore to lodash", a reference to a Wiki page on migrating from Underscore to lodash, and a reference to another Packt Publishing title Lo-Dash Essentials.

Chapter 6 of Learning Underscore.js talks about Underscore's relationship to ECMAScript/JavaScript standards. The section begins with background details: "Up until Underscore 1.6, there was a strong correlation between the library and some of the native JavaScript functions available in ES5. Starting with Underscore 1.7, this link was broken and the library introduced implementations that performed better than the native JavaScript equivalents." The section goes onto look at ECMAScript 5.1 (ES5) functions that are similar to Underscore functions and lists some of the advantages of the Underscore versions of these functions.

The section "ECMAScript 2015 (ES6)" describes advantages offered by ES6 and describes features of ES6. This section references the ECMAScript 6 Compatibility Table and explains how transpilers can be used to "convert code from ... upcoming ECMAScript specifications ... into code that is compatible with older specifications." Babel is introduced as a transpiler for converting ES6 code to ES5 code and examples of using Babel from a web browser, from the command-line, and in conjunction with Node.js are provided. Several examples are provided of using Babel to use ES6 functionality.

Chapter 7: Underscore.js Build Automation and Code Reusability

The final chapter of Learning Underscore.js begins by looking at installing Gulp and using Gulp for deployments. The chapter also includes a section "Reusing code based on Underscore between client and server" that covers use of CommonJS, Browserify, Jasmine, and Gulp to enable using code on client and server. The final section of the chapter and of the book illustrates using babelify to add "ECMAScript 2015 (ES6) support to Browserify."

General Observations

  • Learning Underscore.js introduces Underscore.js and provides relatively extensive coverage of this JavaScript library. It goes a bit beyond Underscore by covering lodash and by covering other JavaScript-oriented libraries and tools that allow for working with new ECMAScript features.
  • I liked that Learning Underscore.js liberally referenced online materials for more details on many of the topics it introduced. Some of these articles and resources are excellent and I was glad to have them pointed out.
  • I liked the book's coverage of running JavaScript in different contexts such as browser, server, and database. The book helped show that it's possible to do this, but also demonstrated that doing so is still not trivial and does require additional effort to achieve a full degree of cross-platform compatibility.
  • Learning Underscore.js includes numerous code listings. Even in the PDF copy of the book that Packt Publishing provided for my review, the code listings are black font on white background with no color syntax and no line numbers. However, each chapter references where the code can be downloaded to be used in the reader's favorite IDE or editor. These references include Cloud9 links.

Conclusion

Learning Underscore.js provides a thorough introduction to Underscore.js that includes explanation of why it's popular among JavaScript developers and some of the functionality it makes available above and beyond current JavaScript implementations. The book points out different approaches that can be used to start taking greater advantage of ES6 features today.

Monday, December 7, 2015

Book Review: Learning JavaScript Data Structures and Algorithms

The Packt Publishing book Learning JavaScript Data Structures and Algorithms by Loiane Groner has the subtitle "Understand and implement classic data structures and algorithms using JavaScript." Learning JavaScript Data Structures and Algorithms has just under 200 substantive pages spanning ten chapters in the main book. There is also an additional Chapter 11 and an Appendix referenced in the Preface that can be downloaded as separate PDFs.

Preface

The Preface of Learning JavaScript Data Structures and Algorithms briefly describes the importance of data structures and algorithms in software development and provides brief descriptions of each of the book's eleven chapters and of the appendix. In the "What you need for this book" section, the Preface describes three development environments that the reader can choose from to use for examples in the book.

The "Who this book is for" section may be the most important of the Preface I include it here to provide a good idea of who Learning JavaScript Data Structures and Algorithms is best suited for.

This book is intended for students of Computer Science, people who are just starting their career in technology, and those who want to learn about data structures and algorithms with JavaScript. Some knowledge of programming logic is the only thing you need to know to start having fun with algorithms and JavaScript!
This book is written for beginners who want to learn about data structures and algorithms, and also for those who are already familiar with data structures and algorithms but who want to learn how to use them with JavaScript.

Chapter 1: JavaScript – A Quick Overview

The initial chapter of Learning JavaScript Data Structures and Algorithms asserts, "JavaScript is a must-have on your résumé if you are or going to become a web developer." The chapter explains why the author chose JavaScript as the language "to learn about data structures and algorithms."

Chapter 1 of Learning JavaScript Data Structures and Algorithms has a section "Setting up the environment" that describes using a browser such as Chrome or Firefox (with FireBug) as the simplest environment and demonstrates via screen snapshots use of either browser and its associated development tools. This section also describes installing XAMPP and node.js.

Chapter 1's section on "JavaScript basics" begins by describing and demonstrating the two ways (directly embedded and included in referenced file) to include JavaScript in HTML. The chapter then discusses and demonstrates variables and variable scope, types, operators, approaches to writing output, true and false in JavaScript (truthy and falsy), the equals operators, conditional statements, loops, functions, and objects.

The section "Debugging and tools" briefly references JavaScript debugging and recommends the Google Chrome Debugging JavaScript page. This section also recommends choosing an editor from three it lists and briefly describes: Aptana, JetBrains's WebStorm, and Sublime.

I really like Learning JavaScript Data Structure and Algorithms's introduction to JavaScript. The chapter presents JavaScript basics in a clear, concise manner. The author does a nice job of mixing commonly accepted "best practices" of JavaScript development in with the topics as they are introduced. For example, I really like the table that summarizes how true and false work in JavaScript.

Chapter 2: Arrays

Chapter 2 of Learning JavaScript Data Structures and Algorithms introduces the simplest of JavaScript's data structures - arrays. The chapter provides simple code listings and associated explanations that cover creating and initializing arrays, adding elements to and removing elements from arrays, multidimensional arrays, calling methods on arrays, joining arrays, iterating over an array, sorting (including custom sorting) an array, searching with indexOf and lastIndexOf, and writing out the contents of an array as a String with toString() and join(). The second chapter concludes with a short section that lists and briefly describes additional resources on JavaScript arrays.

Chapter 3: Stacks

The third chapter of Learning JavaScript Data Structures and Algorithms introduces the concept of a LIFO stack and how to implement a stack in JavaScript as a custom Stack class. The discussion that introduces the newly written Stack class is followed by discussion on using that class. This chapter is surprisingly short given all the details it introduces (including conversions between different numeric bases) and it concludes with references to the classical "balanced parentheses and the Hanoi tower examples" that can be downloaded with the book's source code (not included in the book itself).

Chapter 4: Queues

FIFO Queues are the subject of Learning JavaScript Data Structures and Algorithms's fourth chapter. As was done in the previous chapter, Chapter 4 begins with discussion and code listings for creating a Queue class and moves onto how to apply this Queue class. The chapter concludes with descriptions of applying a priority queue and Hot Potato queue.

Chapter 5: Linked Lists

Chapter 5 of Learning JavaScript Data Structures and Algorithms introduces linked lists and compares and contrasts linked lists with arrays. As was done in the previous two chapters, the fifth chapter describes and illustrates how to implement its data structure (LinkedList) and then demonstrates using it.

Doubly linked lists are also covered in Chapter 5. The chapter discusses and illustrates adapting LinkedList to be a DoublyLinkedList. This discussion includes several simple graphics and text explaining the complexities of the book-keeping for managing a custom-developer doubly-linked list.

The fifth chapter also introduces the concepts of a circular linked list and a doubly circular linked list. Although the chapter doesn't actually cover the implementation of these data structures, it references the source code that is available for download for those implementations.

Chapter 6: Sets

The data structures covered in Chapters 2 through 5 of Learning JavaScript Data Structures and Algorithms are sequential structures, but the sixth chapter introduces Sets and describes a "Set" as "a collection of items that are unordered and consists of unique elements". The author points out that ECMAScript 6 is expected to provide a built-in Set and then demonstrates implementation of a Set "based on the Set implementation of ECMAScript 6." I found it interesting that a JavaScript Object was chosen to back the custom Set, but the author explains an advantage of this approach: "objects in JavaScript do not allow you to have two different properties on the same key, which guarantees unique elements in our set."

Chapter 6 explains and illustrates with code samples the implementation of a Set with methods matching or similar to those anticipated for the ECMAScript 6 Set. The chapter demonstrates use of the custom Set class. The coverage includes introduction with graphics of different set operations and how to implement them using the Set class.

Chapter 7: Dictionaries and Hashes

Chapter 7 of Learning JavaScript Data Structures and Algorithms introduces two structures that are based on key/value pairs and on the concept of unique entries: dictionaries (maps) and hashes. The chapter states that ECMAScript 6 includes a built-in Map implementation and then proceeds to illustrate how an Object-based Dictionary implementation can be written in JavaScript. As is the pattern in the other chapters on JavaScript data structures, this section also demonstrates use of the custom Dictionary class.

The seventh chapter also illustrates with text and code listings how to implement a HashTable and how to use it. This includes significant discussion on techniques for hash collision resolution.

Chapter 8: Trees

Learning JavaScript Data Structures and Algorithms's eighth chapter begins with an introduction to concepts and terminology associated with trees. The chapter illustrates creation of a BinarySearchTree class and how to traverse it, search it, and perform other basic operations on it. The chapter only briefly introduces the Adelson-Velskii and Landis' (AVL) tree, but states that an implementation of it can be downloaded from the source code associated with the book.

Chapter 9: Graphs

The ninth chapter of Learning JavaScript Data Structures and Algorithms introduces the last major data structure covered in this book: graphs. The chapter starts by introducing graph concepts and terminology and then describes directed and undirected graphs. The chapter explains two common implementations of graphs (adjacency matrix and incidence matrix) before illustrating development of a Graph class. The coverage of graph traversals is significant and detailed.

Chapter 10: Sorting and Searching Algorithms

The last chapter that is included in the PDF version of Learning JavaScript Data Structures and Algorithms that I was provided for my review is focused on common sorting and searching algorithms implemented in JavaScript. The covered sorting algorithms include bubble sort, selection sort, insertion sort, merge sort, and quick sort. I was surprised to learn from reading this book that each browser is free to implement Array.prototype.sort with its own choice of one of these or another sorting implementation.

The second part of the tenth chapter covers searching algorithms implemented in JavaScript and specifically covers sequential search and binary search. Big O notation is important in any discussion of algorithms and their performance and that is covered in more detail in the supplementary chapter and appendix.

Chapter 11: More About Algorithms

This eleventh chapter of Learning JavaScript Data Structures and Algorithms was referenced as a separate download (PDF) in the Preface. This chapter looks in more detail at recursion (introduced in Chapter 8) and Big O notation (introduced in Chapter 10) and discusses dynamic programming and greedy algorithms.

Chapter 11's coverage of recursion describes the situation in recursive code that can lead to stack overflow errors and describes the browser-specific limitations on call stack size. The recursion coverage also introduces ECMAScript 6's support for tail call optimization and revisits a classical recursive example with the Fibonacci sequence.

"Dynamic Programming" (DP) is described in Chapter 11 as "an optimization technique used to solve complex problems by breaking them in to smaller sub-problems." The chapter introduces the three main steps used to solve a DP problem and briefly describes some famous problems solved with DP. Code and text explanations cover implementing a solution for the minimum coin change problem.

The "Greedy Algorithms" section of the eleventh chapter states that a greedy algorithm "makes the locally optimal choice (the best solution at the time) at each stage with the hope of finding a global optimum (global best solution)." It then approaches the same minimum code change problem solved with dynamic programming approach with the greedy algorithm implementation and compares and contrasts the two approaches.

The supplementary Chapter 11 provides more in-depth discussion of Big O notation that includes a nice, simple table of the various notations and their corresponding names before describing each notation in more detail. There's a nice color chart comparing the complexities of the different levels of Big O notation and I like that the source code for generating that chart in JavaScript can be downloaded with the source associated with the book.

Chapter 11 concludes with a listing and brief description of online sites that allow developers to "[have] fun with algorithms".

Appendix: Big-O Cheat Sheet

Like Chapter 11, the Appendix is not included in the main book (at least in the PDF version I reviewed), but is instead available as a separate download (PDF) of two pages. This appendix begins with a table summarizing "the big-O notation for the insert, delete, and search operations of the data structures" covered in Learning JavaScript Data Structures and Algorithms. Similar tables exist for graph operations, sorting algorithms, and search algorithms.

General Observations

  • Learning JavaScript Data Structures and Algorithms provides an excellent introduction to data structures and to implementing and using common data structures in JavaScript. As such, it is a book that should appeal and be of use to a developer with minimal or no JavaScript experience or even someone who is not necessarily interested in JavaScript, but is interested in learning about data structures.
    • JavaScript turns out to be a pretty good language to teach and learn data structures. It's an added bonus that many of the generated data structures can be used in JavaScript code without being redundant with built-in language data structures. One of the drawbacks of teaching data structures with Java, for example, is that it's hard for the learner to see the benefit when he or she knows Java already has a rich collection of data structures.
    • Although the book is, at its title suggests, on JavaScript data structures, much of the content is largely applicable to many modern programming languages. There is clear, concise coverage of common data structures, issues to consider when implementing and using them, and the relative costs of operations (Big O notation) associated with these structures.
  • There are several screen snapshots included in Learning JavaScript Data Structures and Algorithms that are clear resolution and in color. Some of these are annotated to make them even easier to understand quickly.
  • The are several simple graphics included in Learning JavaScript Data Structures and Algorithms that are black symbols on white background. Although very simple, they communicate the information and concepts well. Indeed, their simplicity likely increases their communicative value even if they are not the most aesthetically pleasing. Given their simple nature, they probably appear very clearly even in a printed book with black text and white pages.
  • Code listings in Learning JavaScript Data Structures and Algorithms are black font on white background (no color syntax) without line numbers in the PDF version. For greater code readability, I recommend downloading the source code for this book from the Packt site and opening the code in your favorite text editor (such as Sublime) or IDE.
    • It is a common characteristic of Packt books to not include line numbers in code listings. However, Learning JavaScript Data Structures and Algorithms does place markers such as {1} after comment slashes (//) on certain lines that are later described in conjunction with that line number marking. This functions similarly to having line numbers on the source code in terms of making it easier to see clearly what lines of code are being referenced specifically in the discussion text.
    • It is recommended to download the code associated with the book not only to read it in your favorite editor, but because many included supplementary examples were mentioned but not shown in the book.
  • Several of the Packt Publishing books I've read and/or reviewed have significant editing issues such as numerous typos and misspellings. I was impressed, however, with the polish of Learning JavaScript Data Structures and Algorithms. It not only avoids typos and misspellings, but features easy-to-read prose and reads very quickly.

Conclusion

I have reviewed numerous Packt Publishing books, but feel comfortable stating that Learning JavaScript Data Structures and Algorithms is one of the best Packt Publishing titles I've read (probably in the top five). Learning JavaScript Data Structures and Algorithms is both an excellent introduction to JavaScript and to writing and using common data structures and algorithms in JavaScript. Perhaps what surprised me most about this book is that it would be a good introduction to data structures for anyone interested in learning about data structures regardless of their preferred programming language.

Thursday, December 3, 2015

Book Review: Learning TypeScript

Packt Publishing recently published Remo H. Jansen's Learning TypeScript with the subtitle, "Exploit the features of TypeScript to develop and maintain captivating web applications with ease." The book features well over 300 pages that constitute ten chapters and a preface.

Preface

The Preface of Learning TypeScript begins with an introduction to the current state of JavaScript and an explanation of why Microsoft developed TypeScript. The Preface provides short descriptions of what each of its ten chapters entails and states that Learning TypeScript "teach[es] TypeScript's core features" and "also explores the power of some tools, design principles, best practices and ... demonstrates how to apply them in a real-life application."

The "What you need for this book" section of the Preface states that TypeScript 1.5 is used for the book's examples and that the Atom text editor is used in the book (though any text editor should be fine).

The "Who this book is for" section of the Preface explains that Learning TypeScript is for an "intermediate-level JavaScript developer aiming to learn TypeScript to build beautiful web applications" who has "no prior knowledge of TypeScript," but does have "a basic understanding of jQuery."

Chapter 1: Introducing TypeScript

The first sentence of the initial chapter of Learning TypeScript states in that single sentence the intent of the book: "This book focuses on TypeScript's object-oriented nature and how it can help you to write better code." The chapter then opens with a discussion of the TypeScript architecture and TypeScript design goals. The discussed design goals include static typing, compatibility with JavaScript, code structuring mechanisms, avoidance of runtime overhead for "emitted" JavaScript code, and ability to execute on multiple platforms.

In the discussion of the TypeScript architecture, the book includes a copy of the diagram available in the Microsoft TypeScript Architectural Overview Wiki page and then provides a brief explanation for each layer in that architecture diagram.

Learning TypeScript advises the reader to use the TypeScript Playground as an easy way to play with and try out TypeScript code. A screen snapshot and explanatory text describe how a developer can type in TypeScript code on the left and see the corresponding JavaScript code on the right. This section of the first chapter also describes using the TypeScript compiler built into VisualStudio or downloaded separately via node.js's npm.

Chapter 1 of Learning TypeScript moves from its discussion of accessing the TypeScript compiler to introducing TypeScript types. This section introduces TypeScript's optional static type notation along with the variable declaration keywords var, let, and const. Union types, type guards, and type aliases are also introduced in this introductory chapter.

A good explanation of ambient declarations is presented and is followed by tables listing arithmetic operators, comparison operators, logical operators, bitwise operators, and assignment operators in TypeScript. The section on flow-control statements (if, if/else, switch, while, do/while, for, and for...in) briefly describes each and illustrates each with small code listings.

Chapter 1's survey of basic TypeScript language features wraps up with introductions to TypeScript's functions, classes, interfaces, and namespaces. The chapter concludes with an example that applies many of these language features.

Chapter 2: Automating Your Development Workflow

The second chapter of Learning TypeScript covers "some tools to automate our development workflow ... to reduce the amount of time that we usually spend on simple and repetitive tasks." The chapter begins by delineating tools to install for the development environment. These tools include Node.js, the Atom text editor and atom-typescript package, git and github, node package manager npm, Bower, DefinitelyTyped, Gulp, gulp-tslint, CommonJS, Karma, BrowserSync, and Travis CI.

Over ten years ago, Ruby on Rails introduced me to the power and convenience of scaffolding. "Scaffolding" is defined in Learning TypeScript as a tool "used to autogenerate the project structure, build scripts, and much more." The chapter states that "the most popular scaffolding tool these days is Yeoman" and then demonstrates applying Yeoman to generate a beginning source directory structure.

Chapter 3: Working with Functions

Chapter 3 of Learning TypeScript is dedicated to functions because "functions are the fundamental building block of any application in TypeScript." The chapter begins with some introductory information on TypeScript functions, how to declare them, and how to overload them. During its introduction to functions, Chapter 3 also explains the use of template strings (back tick characters) and placeholders (${}). The chapter also highlights some of the differences between TypeScript functions and JavaScript functions. For example, it explains, "Unlike JavaScript, the TypeScript compiler will throw an error if we attempt to invoke a function without providing the exact number and type of parameters that its signature declares" (unless, as the chapter explains, you indicate one or more parameters are optional using ? syntax, a default value, or rest parameters).

Chapter 3 also explains that TypeScript scope, like JavaScript scope, is function-based. Indeed, the author points out that "a TypeScript application is a JavaScript application at runtime" and that JavaScript’s variable hoisting is in force in TypeScript. Examples are provided of using let and const in TypeScript to explicitly specify different block scopes than the default function scope.

Immediately invoked function expression (IIFE) is introduced in the third chapter as a pattern "to avoid variable hoisting from within blocks" and "to prevent us from polluting the global scope." Chapter 3 also introduces generic function in TypeScript. The chapter looks at tag templates as well and notes that this is a feature anticipated for TypeScript 1.6.

The final major section of Chapter 3 is "Asynchronous programming in TypeScript." This section covers callback functions, higher-order functions, and arrow functions (fat arrow functions). The section also provides an example of "callback hell" related to loading a Handlebars template and then discusses use of Promises (and provides an example based on Q's implementation of Promise) to dress these callback issues.

The section of Learning TypeScript's third chapter on asynchronous programming looks at anticipated asynchronous functions in TypeScript and refers the reader to the TypeScript Roadmap for details on when this feature will be available (looks like TypeScript 2.0 at time of this writing). The chapter also covers generator functions (expected in TypeScript 1.6).

4. Object-Oriented Programming with TypeScript

Learning TypeScript's fifth chapter begins with a review of the SOLID principles of object-oriented programming and then begins to describe "how to write TypeScript code that adheres to these principles so that our applications are easy to maintain and extend over time." The chapter revisits classes, constructors, and interfaces in the context of the SOLID principles. It also introduces the object-oriented concepts of association, aggregation, composition, inheritance, mixins, generic classes, and generic constraints.

Chapter 4 of Learning TypeScript introduces TypeScript modules and contrasts them with namespaces. This section describes, compares, and contrasts TypeScript's "available module definition syntaxes": ES6 module (TypeScript 1.5), external modules (pre-TypeScript 1.6), AMD and require.js modules, CommonJS modules, UMD modules, and SystemJS modules.

The fourth chapter concludes with a discussion on circular dependencies and illustrates use of Atom's generation of a dependency tree graph to help identify circular dependencies.

Chapter 5: Runtime

Chapter 5 of Learning TypeScript opens with the reminder that "TypeScript runtime is the JavaScript runtime" and adds, "TypeScript is only used at design time; the TypeScript code is then compiled into JavaScript and finally executed. The JavaScript runtime is in charge of the execution. Is important to understand that we never execute TypeScript code and we always execute JavaScript code." For someone familiar with the JavaScript runtime who is reading Learning TypeScript to, well, learn TypeScript, this chapter may not be necessary.

The fifth chapter points out the importance of being aware of the environment to which a TypeScript (or JavaScript) application is being deployed as different variables and objects are available or not available in different types of environments. The chapter introduces JavaScript runtime concepts of heap, queue, stack, and frames and displays a simple color graphic of these concepts seemingly adapted from the image on the Concurrency model and Event Loop page of the Mozilla Developer Network. There is also brief discussion of how the JavaScript event loop works.

Chapter 5 discusses one of the nuances of JavaScript that I have found to be most challenging: its behavior depends on the context in which this is used and whether it's in strict mode or non-strict mode. There is brief discussion of using this in the global context and more extensive discussion of using this in the function context with emphasis on invoking the call, apply, and bind methods on the Function.prototype object.

Learning TypeScript's fifth chapter concludes with fairly detailed introductions to JavaScript Prototypes and JavaScript closures.

Chapter 6: Application Performance

Learning TypeScript's sixth chapter begins with summary of several types of resources that might have limited availability. The chapter then briefly describes several performance metrics before covering different types of performance analysis. It introduces the Resource Timing API, presents an image similar to that on the W3C Resource Timing specification page and very much like the image on the performance-bookmarklet project page, and demonstrates using the Performance-Bookmarklet browser extension.

The sixth chapter's discussion on "network performance and user experience" makes some interesting points based on a 2009 Akamai study and shows an interesting image that can also be seen in the NewRelic article Velocity Roundup: Real-Users, Performance and What Matters to You. The chapter also introduces and demonstrates using Google's PageSpeed Insights and YSlow to measure page loading times and offer suggestions for faster user experience.

Chapter 6's section on "GPU performance analysis" applies stats.js in an example demonstrating measuring of frames per second and the section on "CPU performance analysis" demonstrates using the Chrome Developer Tools Profiler. Google Chrome Developer tools are also used in this chapter's demonstration of tracking down JavaScript memory leaks.

Another section of Chapter 6 describes the JavaScript garbage collector and provides recommendations for achieving the best performance related to garbage collection. The "Performance optimization automation" section discusses automating performance monitoring and performance testing.

The concluding section of Chapter 6 covers exception handling in TypeScript and introduces the Error class, a pre-TypeScript 1.6 approach to extend the Error class for a custom error, and use of try, catch, and finally. Like Chapter 5, Chapter 6 is, for the most part, not specific to TypeScript but rather applies to JavaScript in general and also applies to TypeScript.

Chapter 7: Application Testing

The focus of Learning TypeScript's seventh chapter is "how to write unit tests for TypeScript applications." This chapter begins with a review of key terms related to unit testing such as assertion, spec, test case, test suite, test doubles (spy, dummy, stub, and mock) and test coverage.

The examples in Chapter 7 make use of a wide variety of tools and these are each briefly described in the chapter (including how to install, typically via npm install). The covered tools include Gulp for running tasks used by tests, Karma for executing tests, Istanbul for test coverage, Mocha for the test framework, Chai and Karma-Chai for test assertions, and Sinon for test doubles (test isolation) support, tsd to manage third-party tool dependencies, PhantomJS and karma-phantomjs-launcher for browser testing without starting a browser, and Selenium and Nightwatch.js for end-to-end testing.

Chapter 7's discussion of "testing planning and methodologies" briefly describes test-driven development (TDD) and behavior-driven development (BDD). There are also brief descriptions of different types of tests ranging from unit tests to end-to-end tests. The chapter concludes with explanations and discussion illustrating application of the tools to test TypeScript applications.

Chapter 8: Decorators

Chapter 7 of Learning TypeScript covers annotations and decorators. The chapter begins by explaining that decorators are planned for ECMAScript 7, but are available now in TypeScript 1.5. There is explanation regarding annotations (originated with AtScript, which is now part of TypeScript) and decorators and their subtle differences.

The seventh chapter of Learning TypeScript explains and illustrates decorators (including how to implement them) for classes, properties, methods, and parameters. The section on decorators also explains why and how a decorator factory is used and how to use a decorator with arguments.

Chapter 7 concludes with an introduction to the Reflection Metadata API. The ability to use Reflect.getMetadata is planned for ES7, but is available already in TypeScript 1.5.

Chapter 9: Application Architecture

Chapter 9 of Learning TypeScript contains discussion on application archictecture considerations for TypeScript applications. It covers the increasingly ubiquitous Single-Page Application architecture and discusses application of Ajax with Handlebars.js and jQuery.

Chapter 9's section on "MV* architecture" introduces "the Model-View-Controller (MVC) design pattern and some of its derivative versions, such as Model-View-ViewModel (MVVM) and Model-View-Presenter (MVP)." There are some useful diagrams in this section illustrating these concepts and versions of these diagrams are available in the presentations Working with AngularJS and About Flux.

After its introductory coverage of single-page applications and so-called MV* architectures, the ninth chapter looks at how to go about selecting a framework to use with single-page applications rather than writing one from scratch. This section provides a useful graphic that depicts different potentially desired characteristics of such a framework with one or more frameworks that meets satisfies those desires. I also appreciated this section's reference to TodoMVC for "helping you select an MV* framework."

Learning TypeScript's ninth chapter concludes with a sizable section on developing a custom MV* framework. There are several code listings and associated explanation associated with this example that the author warns is for learning purposes rather than for production use.

Chapter 10: Putting Everything Together

Learning TypeScript's final chapter "[puts] into practice the majority of the concepts ... covered in the previous chapters" via an example demonstrating development of a "a small single-page web application using the SPA framework" that was introduced in Chapter 9. The chapter contains several code listings and explanations of each part of the application. The chapter briefly covers unit testing of the application and preparing the application for a production release.

General Observations

  • The book that is the subject of this review, Learning TypeScript, should not be confused with Bryan Rayner's presentation Learning TypeScript: Or, An Appeal to Embrace Typed Languages.
  • Some chapters of Learning TypeScript are TypeScript-specific and others are more ECMAScript/JavaScript-general. Because TypeScript is a superset of JavaScript and an implementation of ECMAScript, this is a sensible approach for a book with a title that includes "TypeScript".
    • Developers with no TypeScript or JavaScript experience can use Learning TypeScript as a completely self-contained book to introduce themselves to TypeScript and the JavaScript ecosystem works in.
    • Developers who already have TypeScript experience may still find the book useful because of the details provided related to ECMAScript in general (particularly newer and future features).
    • Even developers who are not interested in TypeScript in particular, but who are interested in modern and future ECMAScript features, may find several of the chapters to be useful.
      • For example, while the chapter of Learning TypeScript on object-oriented concepts will not bring many new concepts to the attention of Java, C++, and C# developers, it could be very useful for a JavaScript developer with minimal class-based object-oriented experience who wants to learn more about where ECMAScript's class support is heading.
      • TypeScript already implements several proposed new ECMAScript features, so learning about TypeScript can often translate to better understanding JavaScript's future.
      • TypeScript has been adopted by Angular 2, making understanding of it important to many web developers who might not otherwise be interested in TypeScript.
  • There are numerous code listings in Learning TypeScript. Most are short and do a good job of illustrating the concepts. Even in the PDF version I reviewed, they are black font on white background with no color syntax and no line numbers. I encourage anyone following along with the code examples to download the source code and open it in their favorite IDE or text editor.
  • It's a minor pet peeve of mine, but I'll point it out here for completeness. Several of the examples in Learning TypeScript use the "legacy" example keywords "foo" and "bar." I was starting to think books were getting away from this, but this is a modern book that still uses those generic names. I've never liked these terms for multiple reasons, but perhaps my strongest reason to dislike them is that they have zero contextual meaning. I'd rather see contrived but still more realistic variable names in examples.
  • The TypeScript Language Specification (1.5 as of this writing), the TypeScript Tutorial, and the TypeScript Handbook are additional very useful resources.

Conclusion

Learning TypeScript provides a solid introduction to TypeScript. It goes beyond that, however, and, via discussion of TypeScript, examines modern ECMAScript and where ECMAScript is going in the near future. The reader of Learning TypeScript not only learns about TypeScript, but learns about recent and soon-to-be-added features for JavaScript. Learning TypeScript contains TypeScript-specific details as well as JavaScript/ECMAScript-general details. This demonstrates how TypeScript can be used in conjunction with other JavaScript tools and frameworks.