Over a million developers have joined DZone.

On the Importance of the Standard Library

DZone's Guide to

On the Importance of the Standard Library

· Web Dev Zone ·
Free Resource

Jumpstart your Angular applications with Indigo.Design, a unified platform for visual design, UX prototyping, code generation, and app development.

A standard library is often seen as a convenience, but it is much more; it raises the level of abstraction and enables rich composition, which helps manage complexity when building large applications. In this article I will show how a standard library achieves that using Dart as an example.

If It Looks Like a List It Will Be a List

Let’s start with something very simple. Let’s look at the list collection type, which we all know and love. Since List comes with the Dart standard library, everything is built using it. When I say everything, I really mean everything. For instance, adding a class to an HTML element is done not via some obscure DOM API, but using standard list operations.

element.classes.add("my-class") //element.classes is List<String>

By the same token, you do not use append or prepend to add an element to the DOM, because in Dart you merely add an element to a list of DOM nodes.

var button = new ButtonElement()..text="OK";
element.nodes.add(button); //element.nodes is List<Node>

These two examples show the Dart standard library playing the role of an anti-corruption layer. It hides all the weirdness of the DOM API and gives you a consistent view of the underlying platform.

Standard Library is an Anti-Corruption Layer

There are libraries in the JavaScript ecosystem doing the same thing (e.g., jQuery), but Dart goes far beyond that. It is not just a thin layer on top of the DOM. The Dart standard library provides building blocks that substantially raise the level of abstraction. One of them is Stream.

Reactive Programming with Streams

Streams have been added to the Dart platform to help deal with the asynchronous nature of Dart programs. They provide a unified interface to anything that can send out a series of events. An example of a stream would be all of the keyup events on some input element. When a user presses a key, an event is pushed to the stream, and everyone listening will be notified.


Now, it gets interesting. If you look at these two pictures of a stream and a list, you will notice that they look exactly the same.

Streams and Lists

Think about it. Lists and streams are both just sequences of values. The only difference is that lists are pull-based sequences and streams are pushed-based sequences. In other words, when working with a list you are pulling values from it until you reach the end of it. A stream, on the other hand, pushes values to you until there is nothing left.

Since streams are very much like regular collections, the standard library defines familiar collection operations (e.g., map, filter and reduce) on them. Using these we can express complex reactive computations in a declarative way.

var inputs =
  map((event) => event.target.value).
  where((text) => text.length > 2).
  transform(new Throttle(500)).


Here I am taking a stream of all keyups and mapping it into a stream of values. Then, I am doing some filtering. After that, I am ignoring fast typing to make requests only when the user pauses for more than half a second. Next, I am querying Wikipedia. Finally, I am filtering out invalid responses to print only valid results. This has all been done with just a few lines of code.

Streams are a very powerful tool for expressing reactive computations, but that is not what I want to emphasize here. I want to emphasize the importance of the standard library. Since the standard library provides streams, everything that is essentially a sequence of some sort is represented as a stream (not just keyboard and mouse events). A web socket object has a stream of messages. A Backbone-like library gives you a stream of changes for a particular model.

inputElement.onKeyUp //Stream<KeyboardEvent>
webSocket.onMessage //Stream<MessageEvent>
mvcModel.onChange //Stream<ChangeEvent>

They all have the same interface, which allows us to use the same decorators and combinators. So the throttle transformation can be written once and used everywhere.

Standard Library => Object Composability

What's more, the standard library enables composability of other libraries. When working on your library you don't choose what async primitives to support. At the very least you will support the standard ones, which means that the stream you return from your library will be the one you expect in your library. It makes libraries more composable.

Standard Library => Library Composability

Raising the Level of Abstraction

The fact that something like Stream is provided by the standard library makes a big difference, because it can be used at the API boundary of other libraries. Thus, most Dart libraries work with streams.

In JavaScript, on the other hand, even if you build a library on top of Bacon.js you can't make Bacon.js a part of your library’s API because if you return a Bacon.js stream the majority of other libraries will not know what to do with it, which forces you to use callbacks. That is why everyone saying that JavaScript is flexible enough to implement anything is missing the point. Sure, you can implement streams in JavaScript, but to really raise the level of abstraction you have to make them ubiquitous.

Wrapping Up

The standard library acts as an anti-corruption layer hiding the inconsistencies of the underlying platform. It also makes abstractions ubiquitous, which raises the level of abstraction.

The absence of a standard library, in my view, is the weakest part of JavaScript, which is much harder to ignore than, for instance, some obscure language features. Dart, on the other hand, comes with one and this fact alone makes Dart a viable alternative.

Read More About Dart

Read more about Dart at engineering.nulogy.com.

Take a look at an Indigo.Design sample application to learn more about how apps are created with design to code software.


Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}