Destructuring CoffeeScript one sip at a time

motif

TL;DR? Don’t worry, (: You can see the code running here.
Destructuring CoffeeScript

Introduction

Destructuring in Coffeescript is an elegant feature that makes the language feel closer to pure functional languages such as Haskell. Let’s see an example of that.

Show me the code

We will start by creating two types of tree objects:

Leaf, as the name suggest, will be the tree nodes that contain values. On the other hand, Nodes will be the objects that will glue together the tree.

Let’s see some structures in order to see how the tree will look like:

Now that we know how some of the trees will look like, we can start thinking how we can iterate them. We can use the constructor property to distinguish whether we have a Node or a Leaf.

Let’s write a function that will sum all the Leaf nodes of a given tree.

A couple of things to notice from the previous example:

  • switchwhen are versatile and can receive functions as the content to match.
  • In CoffeeScript everything is an expression (as much as possible). That means that the last evaluated statement of a function will be the return value. In the Leaf branch it returns value and in the Node branch the return value is the result of nodes.reduce f, 0
  • Last but not least, by doing {value} = tree and {nodes} = tree we are destructuring the objects. This feature simplifies code and improves readability.

From the last code snippet, we can generalize some parts and get a functional way (fold function) to transverse the data structure:

The arguments of the function are:

  • fLeaf:Function to reduce to each of the Leaf ndoes
  • fNode: Function to reduce to each of the Nodes
  • valueNode: Initial value

We can express sumTree using reduceTree on the following way:

id = (x) -> x
fNode = (x, y) -> x + y
sumTree = (tree) -> reduceTree id, fNode, 0, 
 
# returns 9
sumTree new Node(new Leaf(4), new Leaf(5))

Conclusion

Coffeescript syntax sugar allows some algorithms to be codified in an elegant fashion, specially when they involve destructuring. In the RAML Grammar project, where we describe RAML Grammar for providing suggestions and autocomplete to the API Designer, we use extensively trees and easily transverse them thanks to the language nature.


We'd love to hear your opinion on this post