Pattern Matching is for sure one of the most powerful features in Scala
(kindly borrowed from Haskell). Nonetheless, developers approaching the
language for the first time might sometimes wonder where it is actually useful
in real life. In this post, I describe one particular real life scenario in
which Pattern Matching shines: validation of structured input.

For the purpose of the argument, suppose we have an application that deals with
bank accounts, expressed as
IBAN codes
(International Bank Account Numbers). IBAN can have different formats depending
on the country, but they all follow certain rules:

They begin with a country code followed by two digits used for the checksum
calculation

They must only contain digits and the 26 latin alphabetic characters from A
to Z

It is possible to validate them by calculating a checksum

Imagine that our system needs to accept an IBAN from user input, validate it,
and decompose it into its part so that we can use it. One naive way would be to
create a wrapper class with different methods that takes care of validation and
access to the various components of the IBAN code:

This imperative style is quite brittle. Whenever we accept an IBAN we want to
validate and decompose it before use, so this solution would lead to a big
amount of repetition and the risk of forgetting to handle invalid codes:

1234567891011121314151617

// Assume userInput is a user provided string,// like "GB82123876b87876b" or "invalidIBAN"valiban=newIBAN(userInput)if(iban.isValid){valaccount=iban.accountvalcountry=iban.countryif(country=="DE")// ...German IBAN, do somethingif(country=="IT")// ...Italian IBAN, do something elseelse// ...IBAN from other country}else{// Handle invalid IBAN. What if we forget?}

We can improve a lot on this by creating a custom extractor, enabling pattern
matching on valid IBAN strings (explaining custom extractors is not in the
scope of this post, but if needed you can read this awesome article):

1234567891011121314151617181920212223242526

objectIBAN{defunapply(code:String):Option[(String, String)]={// Match a Regex for format// validation and decomposingvalIBANPattern="""([A-Z]{2})(\d{2})([A-Z0-9]{12,27})""".rcodematch{caseIBANPattern(country,check,account)=>if(checksumIsValid(country,check,account))// The `check` part is only used for checksum// validation, no need to return itSome((country,account))elseNonecase_=>None}}privatedefchecksumIsValid(country:String,check:String,account:String):Boolean={// Perform checksum validation here...}}

This extractor makes it possible to match a string and, in case it is a valid
IBAN, extract its components. Pattern matching in this situation makes handling
of valid and invalid IBAN very explicit:

The code that handles validation and decomposition stays in one single place,
only responsible of these two operation that always go together. We also
removed the need of a wrapping class, so we only work with plain strings. Freed
from validation/decomposition concerns, the rest of the application code also
becomes very legible, with a clear and symmetric way to handle the case of
invalid input.

JavaScript’s prototypal inheritance paradigm is easy to understand, but can
lead to nasty surprises when it comes to non-primitive properties. While the
issue I discuss here is purely a JavaScript one, the fact that the awesome
CoffeeScript syntax make it so easy to implement classes and extend them leads
developers to run more frequently into this kind of situations.

The Issue with Non-Primitive Properties

The issue can occur whenever we have a CoffeeScript class (or JavaScript
constructor) with a property which is not of a primitive type (basically
anything which is not number, string, boolean, null nor undefined).
For example, let’s have a class with an Array property:

12

classPersonneeds: ["eat","drink","breath"]

Now let’s create two instances, and let’s modify this non-primitive property on
one of them:

Changing one instance led to unwanted changes to other instances too! This
issue occurs because the needs property is stored in the shared
[[Prototype]].

Note that if we overwritten the property on one instance everything would have
been fine, since the overwritten value would live on that particular instance
only. But if we only modify the property, it stays in the [[Prototype]] and
the changes are shared among instances. This is why this issue can only occur
with non-primitive properties: primitives are immutable.

A common feature in many UIs is a widget that can be hidden or shown by clicking on some handle. Some examples are “accordions” or collapsible/expandable sections and navigation menus. Usually the interactivity is achieved with some JavaScript code that toggles the display property of some elements when a handle is clicked.

HTML5 adds two new tags that can theoretically be used to achieve the same effect without any JavaScript code: the details and the summary tags. Here is an excerpt from the HTML5 spec:

The details element represents a disclosure widget from which the user can obtain additional information or controls. […]

The first summary element child of the element, if any, represents the summary or legend of the details. If there is no child summary element, the user agent should provide its own legend (e.g. “Details”).

The rest of the element’s contents represents the additional information or controls.

The open content attribute is a boolean attribute. If present, it indicates that both the summary and the additional information is to be shown to the user. If the attribute is absent, only the summary is to be shown.

In other words, details is a block-level tag with a boolean open attribute that controls its visibility, and it usually have a nested summary tag that is always visible and represent the “handle” that toggles the open attribute, and thus the visibility, on and off.

Cool, isn’t it? Well, unfortunately support is currently quite poor, as at the moment only WebKit seems to properly implement it. The big question is: can we easily polyfill it and start using it in the real world?

Two-way data binding refers to the ability to bind changes to an object’s properties to changes in the UI, and viceversa. In other words, if we have a user object with a name property, whenever we assign a new value to user.name the UI should show the new name. In the same way, if the UI includes an input field for the user’s name, entering a value should cause the name property of the user object to be changed accordingly.

Many popular client-side JavaScript frameworks like Ember.js, Angular.js or KnockoutJS advertise two-way data binding among their top features. This doesn’t mean that it is too hard to implement it from scratch, nor that adopting one of those frameworks is the only option when this kind of functionality is needed. The underlying idea is in fact quite basic, and can be condensed into a 3-point action plan:

We need a way to specify which UI elements are bound to which properties

jQuery is so easy to use that sometimes we end up relying on it even for tasks that could be easily achieved using the native browser APIs. While there is nothing wrong with using jQuery, going native makes our code more portable, future proof and often more performant.

DOM selection is an example of something often performed with jQuery, but straightforward enough to achieve without any external library.

The Selectors API

The HTML5 Selectors API has been around for quite some time now, and it is supported in all modern browsers and in IE down to version 8. Its implementation is based on the querySelector family of methods, that includes four members:

document.querySelector( selector ) takes a CSS selector string and returns the first DOM element that matches the selector, or null if no match is found.

element.querySelector( selector ) does the same, but searching only among the descendants of element.

document.querySelectorAll( selector ) takes a CSS selector string and returns a non-live NodeList of all the DOM elements matching the selector. If no element matches the selector, an empty list is returned.

element.querySelectorAll( selector ) does the same as its counterpart defined on document, but again searching only among the descendants of element.