Showing posts with label Book Review. Show all posts
Showing posts with label Book Review. Show all posts

Wednesday, October 10, 2018

Book Review: Java by Comparison

I accepted the invitation to review Java by Comparison: Become a Java Craftsman in 70 Examples (2018, The Pragmatic Bookshelf) because the premise of this book interested me. The book Software Craftsmanship: The New Imperative had a significant effect on me when I was a much less experienced software developer and I looked forward to reviewing Java by Comparison because of its connection with the concept of software craftsmanship and its examples being provided in the Java programming language. I was provided with the electronic version of the book and I chose the PDF format for my review.

Java by Comparison is written by Simon Harrer, Jörg Lenhard, and Linus Dietz and has over 160 pages of substantive content (not counting prefaces, forewords, table of contents, etc.). Java by Comparison features nine chapters and the 70 cases covered span the first eight of those nine chapters.

Java by Comparison uses the same format for eight of its nine chapters. Each of these eight chapters are divided into several items each and at least two code samples are presented for each item. The first code sample for each item is typically functionally correct code, but the second code sample for each item illustrates how that particular item's principle can be applied to improve that code. There are three samples of these items ("extracts") available on the book's web site to see what I'm attempting to explain here.

Java by Comparison covers specific principles that fall into the areas of clean code, stylistic considerations, readability considerations, comments, naming, exception handling, unit testing, object-oriented design, and using Java's functional capabilities that were largely introduced to the language with JDK 8. Simple code examples are used in each item to contrast minimally sufficient code with improved code.

The ninth and final chapter is different from the first eight chapters. That chapter has fewer code samples and more descriptive text of general practices experienced Java developers tend to adopt in areas such as static code analysis, build automation, continuous integration, logging, and working with concurrency. This chapter is mostly higher-level and provides a taste of these topics for the newer Java developer.

I consider the following to be strengths of Java by Comparison:

  • Content
    • Java by Comparison collects information useful to newer Java developers in a single location.
    • As Java by Comparison covers various topics, it also introduces useful side notes of value to newer Java developers. Here are some examples of this:
      • There is a side note about "Multiple Returns vs. Single Return per Method" in the section on avoiding unnecessary comparisons.
      • There is a side note about "Never Use Floating-Point Arithmetic for Money" in the section on using appropriate tolerance values in unit testing.
    • Java by Comparison uses several different parts of the JDK API to illustrate its points.
    • Most of the lessons discussed in Java by Comparison are ones that I've had to learn the hard way and I found myself agreeing with most of the recommendations (and I've even blogged on some of them).
  • Format
    • The format comparing working code with superior code is effective in illustrating the principle discussed in each item.
    • The authors find a nice balance of small, simple code examples and just enough text to cover the point.
  • Finish
    • Java by Comparison is polished and has very few grammatical errors or typos. This seems to be an increasingly rare characteristic of technical books.
    • Code listings have color-coded syntax and shaded background in the PDF version of the book.
    • PDF version provides links between pages that reference each other.
    • Links to online resources work from PDF.
    • An accessible errata is available.
  • Tone
    • The text in Java by Comparison is easy to read, highly approachable, succinct, and well suited for those newer to Java.
    • Java by Comparison makes recommendations, but is not overly prescriptive and on several occasions highlights that sometimes "best" is context-sensitive and can only be determined after trying different approaches.
    • Although written by three different authors, the writing of Java by Comparison is consistent and uniform.
  • References
    • Java by Comparison provides frequent references to books and online resources for additional details regarding the concepts it covers.
    • Java by Comparison's "Bibliography" lists several of the most influential books and posts in Java and software development.

Intended Audience

I would have liked to have had access to Java by Comparison when I was still relatively new to Java. I remember reading the first edition of Effective Java and learning some from it, but Java by Comparison would have been more appropriate for my level of comfort with Java at that time.

The "Acknowledgements" section of Java by Comparison provides insight into the intended audience. The authors started building "a collection of common issues" that students in their "Advanced Java Programming" class encountered. The "Who Should Read This Book" section of the book addresses the audience more directly, "This book is for people who are learning to program in Java at a beginner or intermediate level. It's also a classroom resource for teachers who coach new developers in their journey to become programmers." The authors add, "You should read this book after you’ve learned the basic Java syntax - after you're able to write small programs with conditions and loops and you know the basics of object-oriented programming." The authors even provide a FizzBuzz-based assessment for potential readers to determine if they have the minimum recommended Java ability to make this book useful to them.

I agree with the authors' recommendations regarding who will benefit most from Java by Comparison. However, I would add that even more experienced Java developers might benefit greatly from reading Java by Comparison if they have not spent much time reading things such as Effective Java, Clean Code, Holub on Patterns, or other books or online media regarding writing Java more effectively.

My Recommendation

Many developers new to Java who have started feeling comfortable with its syntax and basic APIs often ask what is the next best book from them to read. Java by Comparison now gives me an easy answer to that question. I will recommend this book to developers new to Java as an appropriate book for them to read before moving onto Clean Code and Effective Java.

Java by Comparison is also recommended for more experienced Java developers who have concentrated mostly on getting the job done in the past and would like to do a better job at writing code that is more than sufficient and is easier for the next developer who has to work with it.

Java by Comparison applies a novel approach to presenting ideas for beginning and intermediate Java developers to learn techniques they can practice to become better Java developers and to write better code that will benefit others and themselves.

Additional References

There are three sample "excerpts" available to give a prospective reader an opportunity to determine if he or she likes the format and style of writing. There are listed below. I have also included links to others' reviews of Java by Comparison because we all have different tastes and experiences and it might be helpful for prospective readers of Java by Comparison to read what others have said about the book.

Monday, January 25, 2016

Book Review: JavaScript Concurrency

Adam Boduch's book JavaScript Concurrency has been published by Packt Publishing (December 2015). The subtitle of the book is, "Build better software with concurrent JavaScript programming, and unlock a more efficient and forward thinking approach to web development." JavaScript Concurrency consists of ten chapters spanning over 260 substantive pages. The author has described this book in his blog post of the same title.

Preface

The Preface of JavaScript Concurrency provides a single sentence summary of each of the book's ten chapters (find longer chapter descriptions in the author's blog post). The Preface states that the "requirements for this book" are a modern web browser, Node.js, and a code editor.

JavaScript Concurrency's Preface states that "all aspects of concurrent, asynchronous, and parallel programming are covered from first principles" and advertises that the book is "written for any JavaScript developer who wants to learn how to write more efficient, powerful, and maintainable applications that utilize the latest developments in the JavaScript language."

Chapter 1: Why JavaScript Concurrency?

The first sentence of the first chapter of JavaScript Concurrency opens with, "JavaScript is not a language associated with concurrency," but then points out that "this has changed a lot over the past few years, especially with new language features in ES 2015. The chapter introduces concepts of synchronous and asynchronous JavaScript. There is coverage of asynchronous versus parallel that uses simple juggler examples to illustrate the differences.

JavaScript Concurrency's initial chapter introduces the "JavaScript concurrency principles" of "parallelize," "synchronize," and "conserve." The chapter describes the "parallelize principle" as "taking advantage of modern CPU capabilities to compute results in less time" and explains that JavaScript parallelism is achieved in web browsers with Web Workers and in Node.js by spawning processes.

Chapter 1 describes the "synchronize principle" as "about the mechanisms used to coordinate concurrent actions and the abstractions of those mechanisms" and introduces callback functions and Promises. The chapter describes the "conserve principle" as "about saving on compute and memory resources" and introduces "lazy evaluation."

Chapter 2: The JavaScript Execution Model

JavaScript Concurrency's second chapter introduces the JavaScript execution model and related terminology: tasks, execution environment, interpreter, task queue, and event loop. The section "Creating tasks using timers" introduces and demonstrates use of setTimeout() and setInterval() "to schedule JavaScript code to run at a later time."

The second chapter of JavaScript Concurrency looks at basic ways of "responding to DOM events" and "responding to network events" using JavaScript callbacks. As part of this discussion, discussion and demonstrative code listings are provided related to use of debounce and for coordinating multiple requests. The chapter concludes with discussion of some of the challenges of using JavaScript callbacks as an introduction to the motivation for promises.

Chapter 3: Synchronizing with Promises

The third chapter of JavaScript Concurrency opens with a brief history of promises in JavaScript and defines key terms associated with promises: Promise, State, Executor, Resolver, Rejector, and Thenable. The objective of this chapter is to cover how the ES6 implementation of promises in JavaScript helps address JavaScript's so-called "callback hell."

Chapter 3 provides explanations of each of the terms related to JavaScript promises that were briefly introduced at the beginning of the chapter. The chapter uses multiple code listings and descriptive text to explain different approaches to using promises and I liked the id it presents of extending the promise prototype with an always() function that should be run for a given promise whether it resolves or rejects.

JavaScript Concurrency's third chapter reinforces that promises "are born into a pending state, and they die in either a resolved or rejected state" and then goes onto describe consequence of this. There is more in-depth coverage of use of JavaScript promises in different contexts that includes discussion and example code illustrating Promise.all() for handling multiple promises, Promise.race() for specifying that first resolved promise wins, and Promise.resolve(), and Promise.reject() for dealing with a JavaScript function that has "the potential to be both synchronous and asynchronous."

Chapter 4: Lazy Evaluation with Generators

Chapter 4 of JavaScript Concurrency opens with the sentence, "Lazy evaluation is a programming technique, which is used when we don't want to compute values until the very last second." The early portion of this chapter also explains, "The Generator is a new primitive type introduced to JavaScript as a part of the ES6 specification of the language" that helps "implement lazy evaluation techniques in [JavaScript] code." The chapter looks at the JavaScript Generator in more detail, including coverage of generator function syntax (function*), use of yield and next, and use of for .. of for iterating over a sequence of generators..

JavaScript Concurrency's fourth chapter describes with text and illustrates with code how to use generators to work with infinite and alternating/circular sequences. The chapter similarly describes and illustrates deferring between generators and interweaving generators. There are also sections in this chapter regarding passing data to generators, reusing general generators, and implementing "lightweight map/reduce." The "Coroutines" section of Chapter 4 "looks at some techniques for implementing coroutines in JavaScript using generators" and provides examples of implementing and using JavaScript coroutines based on generators.

Chapter 5: Working with Workers

The fifth chapter of JavaScript Concurrency begins with the sentence, "Web workers enable true parallelism within a web browser," and states, "In this chapter, we'll walk through the conceptual ideas of web workers, and how they relate to the concurrency principles that we're trying to achieve in our applications." The chapter introduces web workers as "at their core, ... nothing more than operating system-level threads."

Chapter 5 covers three types of web workers: dedicated (default), sub-workers, and shared workers. There is also coverage of worker environments and how these differ from the main thread's environment.

JavaScript Concurrency's fifth chapter explains and demonstrates the worker importScripts() function to import the lodash library. The chapter also covers communication between workers and related message serialization. I like that the chapter includes discussion of trade-offs and disadvantages associated with use of shared workers and sub-workers. The chapter concludes with coverage of error and exception handling in web workers.

Chapter 6: Practical Parallelism

Chapter 6 of JavaScript Concurrency introduces functional programming and related concepts such as immutability and referential transparency. A section in this chapter asks, "Do we need to go parallel?" That section briefly discusses how to decide whether to apply parallelism or not. This is complemented by a section that briefly discusses how to determine how many cores are available and use that information to decide how much parallelism is appropriate. The chapter also introduces "candidate problems" that can be addressed with parallelism such as mapping and reducing, searching collections, and "keeping the DOM responsive."

Chapter 7: Abstracting Concurrency

The seventh chapter begins by looking "at the approaches that we might use to insulate the rest of our application from tricky concurrency bits." The chapter explains how promises can be used to encapsulate the complexities of concurrent code. The explanations and code examples demonstrate "creating helper functions that wrap the worker communications" to return promises and "extending the web worker interface" postMessage() method. The chapter's section on "lazy workers" looks at "using generators in web workers."

Several of the code listings in Chapter 7 are at least partially taken from http://adambom.github.io/parallel.js/ (and this is designated as code comments in those listings). After referencing these multiple code listings based on that library, the author formally introduces Parallel.js and explains that this library's purpose is "to make interacting with web workers as seamless as possible." The chapter discusses how to use Parallel.js to provide one's own functions to workers provided by Parallel.js rather than implementing one's own workers. The chapter demonstrates using Parallel.js to spawn workers and for mapping and reducing. I like that this section includes discussion of parallel slowdown and how to address that.

Chapter 7 concludes with coverage of worker pools. There are several pages devoted to explanation and demonstrative code listings related to implementing a worker "pool abstraction [that] look[s] and behave[s] like a plain dedicated worker."

Chapter 8: Evented IO with NodeJS

The purpose of Chapter 8 is to "explain how Node handles concurrency and how we need to program our NodeJS code to take full advantage of this environment." The chapter introduces evented IO, the Node.js Event Loop, and why these work well in web environments. The author introduces Dan Kegel's concept of the C10K problem and discusses how Node helps address this. The areas of specific focus are network IO and file system IO with descriptive text explanations and associated code samples.

Chapter 9: Advanced NodeJS Concurrency

Chapter 9 begins by introducing the co library as a library relying on generators and promises "to implement coroutines." The introduction to co introduces the "co() function to create a coroutine," demonstrates how co's awaiting values support is similar to proposed ES7 syntax, demonstrates resolving promises with co, and explains using "the wrap() utility to make a plain coroutine function into a reusable function."

JavaScript Concurrency's ninth chapter includes a section that explains how to fork new Node child processes to avoid issues with the blocked IO event loop. There is also a section on applying "a pool of general-purpose processes." The "Server Clusters" section discusses "scaling our Node application to several machines" and covers examples of this in the context of proxying, microservices, and load balancing.

Chapter 10: Building a Concurrent Application

The final chapter of JavaScript Concurrency uses a "simple chat application" to demonstrate concepts covered in the earlier chapters for building a concurrent application in JavaScript. The chapter begins by revisiting why it's easier to design applications to be concurrent from the beginning than to retrofit an application that was not designed to be concurrent.

The sample chat application built in Chapter 10 is based on Node.js and uses a few libraries such as commander and formidable. Although several simplifying assumptions are made to keep the example simpler, there is still a lot of code to list and describe. The chapter concludes with a section on other features that could be added to the sample chat application and with a paragraph that closes out the entire book.

General Observations

  • JavaScript Concurrency covers several modern (ES6/ES7) topics. This is very useful as many JavaScript books don't yet cover these modern abilities. However, the one drawback is that some of the covered material is not finalized and is subject to change. This is a trade-off that every book written about "cutting edge" topics faces.
  • Several JavaScript libraries with concurrent-orientation are introduced and demonstrated in JavaScript Concurrency. The most attention is paid to Parallel.js, co, formidable, and commander, probably in that order.
  • JavaScript Concurrency not only introduces syntax of new JavaScript concurrency features, but it also includes discussion on motivations for using the different constructs and trade-offs and design decisions that should be considered when selecting a JavaScript concurrent construct.
  • JavaScript Concurrency is best suited for an intermediate or advanced JavaScript developer who has little or no experience with promises, generators, workers, coroutines, and other ES6/ES7 concurrency concepts. A potential reader of this book should probably understand the material covered in Concurrency Model and Event Loop before reading this book. I wouldn't recommend this book to someone trying to learn JavaScript with no previous experience with the language, but would recommend it to someone with basic familiarity and some experience with JavaScript.
  • JavaScript Concurrency covers JavaScript concurrency both in web browser environments and on the server with Node.js.
  • There are numerous code listings in JavaScript Concurrency. These code listings are black text on white background with no color syntax and no line numbers. The code is available for download, which is probably preferable so that the code can be viewed in a favorite editor or IDE with color syntax and line numbers. The code listings are heavily commented (more so and at a lower level than I'd want in production code) and this is desirable in a book that is introducing and explaining concepts. It's nice to be able to read the code and associated comments to gain understanding and switch less between the code and associated text discussion for that understanding.
  • JavaScript Concurrency contains numerous simple diagrams to illustrate concepts. These diagrams consist of simple shapes such as boxes and arrows. In some cases, these simple diagrams make a concept easier to understand and in some cases the diagrams add very little value perhaps because they are overly simplistic.
  • There are some typos in JavaScript Concurrency that generally did not preclude me from understanding the points being made. I list a sample of them here so that readers of this post can decide if these are significant to their understanding, mildly distracting, or not an issue at all.
    • Page 100 has text introducing a code snippet that states, "Next, we'll use the loadScripts() function to bring the lodash library into our library...", but fortunately the actual code listing correctly demonstrates importScripts() rather than loadScripts().
    • Page 149, "Our application is likely filled with operations these, where concurrency simply doesn't make sense."
    • Page 233, "it will be a very simply chat application"
  • Because preferences can be subjective and opinionated, I like to include references to other reviews of the same books in many of my book reviews. Other reviews of JavaScript Concurrency are available:

Conclusion

JavaScript Concurrency sticks to what its two-words title describes: JavaScript concurrency. It is in many ways a "modern JavaScript" book that added clarity to my understanding of what JavaScript now supports or soon will support in many different browsers and on the server with Node.js.

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.