From JavaScript to ELM – Step 2: Types, Cases & HelloWorld

Learning elm improved my coding skills and deepened my understanding of functional programming. This is a post in a step-by-step series that will explain how to develop a simple game using elm from the point of view of a JavaScript programmer. If you haven’t read previous posts, it is recommended, here is the list:

1. Intro
2. Basics

Lets dive in.

Every variable in Elm has a certain type. We have seen that 5, 3.14, "hello", False, etc.. are all of different simple familiar types, Int, Float, String, Bool… Let’s dive into some more complicated types

Data structure types

Here are some types of lists.

Notice that empty lists have the type of List a. In this example a could be any type. It could be List Int, List String or any other type. This is due to lack of information about the content of the list.

Types of records:

Tuples’ types are simply notated

Types of functions
In elm there is a special way to write types of functions.

The type annotation for the function add is

Int -> Int -> Int

In english, this means “given an Int, and another Int, produces an Int”. One can ask why isn’t it written like that Int, Int -> Int

But there is a good reason for it. Remember that in elm every function is curried? Well, there is a different way to approach this type annotation:

Int -> (Int -> Int)

In English “given an Int produces a function that when given an Int, produces Int”

Lets observe this while we annotate our functions with types

Can you see the sense? Each Int information you supply to the “system” cuts the chain in one step, until you reach to a variable of Int. add can be described as a function that sums two integers, or a function that builds another function that adds a constant to a variable. The type annotation Int -> Int -> Int keeps all possibilities open.

Note, it is very recommended, yet not mandatory, to annotate your functions with types.

Now suppose we use records of x and y integer members to represent coordinates in a game. A creator function for this structure looks like this:

Note that a & b could be named x & y as well, I just wanted to avoid confusion.

The function above accepts two numbers and produces a coordinate. It is easy to see how the code gets verbose pretty quick with record’s type annotations. What would happen if instead of a coordinate I were to produce a record with 12 fields?

Type alias
You can name complex data types in order to simplify things.
Instead of writing { x = Int, y = Int } every time a function accepts a coordinate as a parameter or produces a one as a return value you can simply write:

Note, All type names must be capitalized.

This makes the word Coordinate exactly the same as
{ x = Int, y = Int }. In the sense that you could rewrite newCoordinate to look like:

But actually, after the type alias expression there is no need for newCoordinate as well. This is because every type alias is already a constructor. say what?!

If you want to create new coordinate you can simply write

Union Types & Cases
They allow you create more complex type structures, at first they look like enums but there is more to them, welcome union types.

The statement above says that a type of CheckerPiece can be of three optional values, White, Black or None. And so, White, Black and None are all values of the type CheckerPiece.

Now lets see how to use them, say we want to write a predicate function to check if a certian piece has a color as oppose to None.

The code above states that if a piece value is None then it has no color, otherwise it is. This could also be written like that:

But this will not compile:

It will display the Error of

Elm took care of a possibility we didn’t think of. In JavaScript our predicate function would return undefined and who knows if things are under control or not? Imagine that this predicate has over 100 places were it is being called in the code, can one be sure that all of them are handling undefined?

Let’s dive to some more complex Union Types. A checker piece has a coordinate as well, doesn’t it?

One way to implement this would be

And you could create coordinated pieces like that

But wait a minute, I don’t want None to have a location, it is silly. Thus CoordinatedPiece is a bad solution for the problem. If I want Just white and black to have a location this is how it is done.

Assuming Coordinate is already defined as a type alias for { x = Int, y = Int }, I can now create a white checker piece only by delivering a coordinate as well.

Note that p & n are of the same type.

A cool thing that helps to understand what is going on is by understanding the type of White itself. It is actually a function of type
Coordinate -> CheckerPiece

Meaning, only when given a Coordinate then it is fully a CheckerPiece.

Now let us imagine that I want to implement a function that returns a pieces location.

The function accepts a default location as a way to answer in case the pieces value is None. In the future I’ll display a better way to deal with values that may or may not be. Note that I can deconstruct the union type to its pieces inside a case expression. By declaring a variable named “location” it automatically has the value of the first argument White function accepted, if the piece is a actually white. Same goes to black’s case, and to emphasize it I gave it a rather odd name.

Cooldown time

It took me a little while to grasp these concepts. What are the differences between union types and type aliases? What can or can’t be done with case expressions. It helps to read the article more then once, also it is recommended to start play with things.

So, for starters, this is an “Hello World” example in Elm

The important thing to understand is that elm starts from a function called main. And that text is a function that accepts string and turn it into displayed HTML.

The site runelm.io is a really cool place to start playing with elm code. I wrote few lines to show how to use the examples from the article and display them in the DOM as text, this is a good place to start and play with types and function declerations, check it out.

Questions?
Feel free to write in the comments.

You are a conditioned mechanism. Only a meditator goes beyond conditioning. Why? Because every conditioning works through thoughts.

Osho

ripple

Liked the article?

Subscribe

From JavaScript to ELM – Step 1: Basics

Learning elm improved my coding skills and deepened my understanding of functional programming. In the last post I reviewed some of elm’s advantages regarding promising no run time errors and vast speed, if you haven’t read it, it is recommended.

This is the first post of a step-by-step series that will explain how to develop a simple game using elm from the point of view of a JavaScript programmer. Check out this game I implemented recently (play with a,w,s & d)

Lets dive in.

Comments

A trick: Next code is not commented, but if you remove the first } it will all be commented

Declerations

Elm is a static typed language, meaning, every variable has a type. This type cannot be altered later on.

Manipulations

Lists, Tuples & Records

Note, Record meant to store data, like structs in c language. Even though you can push a function into a record, in many cases this would not make sense because this function cannot alter the state of the record, it is immutable.

Conditions

Note that every expression in elm returns a value, thus, every if statement must contain else statement as well, otherwise it may not have a value. In addition the evaluated value of an if statement can be assigned to a variable, for instance:

Case conditions

You could also write condition with a cases

Note the special symbol ‘_’ that represents every other possible case. Case expressions are far more powerful and interesting but we will dive into it in the future.

Functions (fun)

Declaration looks like this:

First of all, it might look weird, I agree. But! once you get used to it you start to see that it is much more clear, less verbose, and more English-like then having ( , ) all over your code.
a & b are parameters of a function named add, the returned value is a + b. Why there is no return keyword in elm? Yet again, because every expression in elm returns a value so there is no need to state it.

Invoking the function would be done like this:

Every function in elm are curried (if you are not familiar with the concept you can read my weird post about it). This means that if I choose to send just one parameter to add I will get a function that expects the second parameter.

Example:

In JavaScript terms add could be defined

But if you send only a, then add behaves as if it was defined like this:

Of Course it is possible to write add in JavaScript in such a way that it responds both as a function that accepts 2 parameters, or a function that accepts only one parameter at a time, curried. Libraries like Lodash and Ramda expose a function named “curry” which will gladly transform any function you give it to a curried function like that.

Function operators

There are some cool function operators that might be foreign to a JavaScript developer. For example instead of toString 13 one can write 13 |> toString this can be useful to simplify syntax in some cases. For example

There is also an operator for composing functions. But I’ll talk about it in the future.

Lambda
Nameless functions are written like that:

With two parameters lambdas are written:

Loops
Elm has no loops. The reason is that loops are by nature imperative and elm wants to keep the language purely declarative. Think of it, for loops depend on the change of value of an iterating index, and while loops depend on the change of value of a condition. So how could one loop in an environment where all is immutable?

List functions.

If this idea is odd to you, feel invited to read my post on the topic of how to never use loops again.

So if one wants to produce the numbers from 1 to 10, it would be done like that:

List.range stands for the function range in external List package. List package is obviously a core package, meaning no one have to actually import it. range produces the numbers you wish, later on you can “iterate” them, or more accurately, apply any other list function such as map or filter

Here is a mapping example:

Questions?
Feel free to write in the comments.

Continue next to From JavaScript to ELM – Step 2: Types, Cases & HelloWorld

Finale

Special thanks to this dude who opened a pull request to the plugin I use to highlight code. It helped me to highlight elm snippets gracefully.

A journey of a thousand miles begins with a single step.

Lao

ripple

Liked the article?

Subscribe

elm promises no run-time errors!

For the past several weeks I’ve learned the great language of Elm and I would like to share why I think it is so promising and capable of influencing the future of web development.

Elm is a functional front-end programming language, that compiles into JavaScript and promises big things, 2 of which are:

  • Great performance
  • No run-time errors

It is still pretty new, but has been used in big production apps, and kept it’s promises. For instance NoRedInk has 36k lines of Elm, as it is reported in elm’s official page.

Great Performance
Like reactJS, Elm uses a virtual DOM in order to optimize page loading. Here are some statistics regarding the speed of Elm.

It seems to beat the greatest web technologies. You can read and review the methodology if you feel skeptic, here.

No run-time errors
Elm uses something that is called type inference to insure no exception invokes to the user. In simple terms, elm will check every condition in your code and make sure that all the possibilities are fully covered. Imagine that JavaScript could tell you that you forgot to check if a variable is undefined, it is not so far from what elm does.

Pure Functional
I personally feel that slowly programmers start to realize that OOP is not so good as once we used to think. This is due to encapsulation, which is one of OOP’s core principles. Encapsulation is the binding of data and functions together as one structure we call Object. Very briefly it is bad due to unexpected state changes. When a programmer in OOP writes a method that alters the object’s state, he has to keep in mind that there may be other methods that alter the state as well, methods he didn’t know exists in many cases…

Elm deals with this issue with various ways. First of all there are no objects. There are Data Types and there are Functions and they are fully separated. Second, every variable in Elm is immutable , meaning it cannot be changed after declaration. This prevents the unexpected side-effects that can alter the variable without a programmer’s awareness. Moreover it causes one to carefully think before he gives a name to a variable. I find it also empowering the = operator. For example if we say in elm that
a = b + c
it means that without doubt, no matter what happens in the program, a will always be equal to b + c. One cannot say that on JavaScript because a line after c could be assigned to some other value, and thus it breaks the equation.

One powerful syntax
As a web developer one must learn the syntax of HTML, CSS and JavaScript. But also, one must know the weaknesses of each language. For instance, HTML has no conditions or loops, solutions to this have been suggested since PHP days when one could open a PHP block inside an HTML content. This damages the code readability because one needs to read both languages mixed together in order to understand what is going on. In Angular, for example, Google tried to solve this issue by embracing the HTML’s syntax and so one can use the <ng-if> directive, but I don’t find it as a good solution because when a heavy angular logic is being implemented in directives it gets messy pretty quick. Elm’s approach is quite neat, Elm provides a one unified syntax that covers JavaScript aspects as well as HTML and CSS all together.

Continue next to From JavaScript to ELM – Step 1: Basics

Future content in the blog
In the next posts I’m going to cover aspects of elm coding from the point of view of an average JavaScript developer. My goal is to bring you to the level of simple game development. like this one that I implemented (use w,a,s & d).

The only way to make sense out of change is to plunge into it, move with it, and join the dance.

Alan Watts

ripple

Liked the article?

Subscribe

Currying Functions for Animals (and a singing robot)

Currying is a Functional Programming technique that can improve your code readability, reduce it’s length, diminish bugs but most importantly, known for causing you to fall in love with your code often.

Why Currying?

Suppose we have this data structure:

And suppose we must use selectAnimal() if we want to peek from the data structure, this can be reasonable if the structure is not exposed to us, or it is much more complex or large…

How can we take care of every animal in the zoo?
A procedural way to code it would be:

But this code has many disadvantages and duplicated segments that are not reused. Imagine what would happen if the list of animals was much longer. Of course we could loop over each type, but still the word zoo, for instance would appear several times. One could argue that zoo could have been a global variable for the function selectAnimal() but I disagree because I’d rather keep selectAnimal() a Pure Function for many reasons.

Notice the “salmon reptile” bug that is hiding like a needle inside a haystack in the code above.

Currying could help us solving these issues.

What is a Currying Function?

A Currying Function is converting a function with multiple arguments to a series of functions each accepts 1 argument, where each wraps the other. For example
(x, y, z) => z + y + z curried, would have been written like this:
x => y => z => x + y + z.
When you call it and send x, you get a function that accepts y, when y is sent, you get a function that accepts z, when z is sent then the answer returns.

How to Curry?

Lets use some Wrapper Functions on selectAnimal() and create a Currying Function:

or simply:

The entity above can be used in several ways:

Lets use this Currying Function to refactor the care taking code into something nice and less verbose.

Notice that the “salmon reptile” bug is less likely to happen in this code.

If we wanted to increase the reusabillity (degree of code reuse), a functional way to do so would be to create a high-order function like:

A high-order function is simply a function that either accepts a function as a parameter, or return a function or both.

The function takeCareMulti() is designed to take care of multiple animals, it accepts a typeSelector function, a typeCare function, and a list of animal names. Needless to say, It takes care on each animal.

Usage:

Notice the improvement from where we started. It is almost as if a robot is singing it. One could easily wrap each function to output its action and it would look like:

Summary

Use currying functions to increase code readability, reusabillity and your affection for the code. It might also decrease the length of your code and the chance to make a mistake.

where was that tiger all along?

namer

Out beyond ideas of wrongdoing
and rightdoing there is a field.
I’ll meet you there.

Rumi

ripple

Liked the article?

Subscribe

What is a Promise and how it works?

blog-promise1

First of all, I promise to implement a promise in this article.

What is a Promise?

The Promise object is used for asynchronous computations. A Promise represents a value which may be available now, or in the future, or never.

MDN

Example!

In the example above, the function given to the promise ctor is executed async. Also it is determined to have 2 parameters. These are callbacks in case of success or fail. Promises should supply a success value when resolved or failure reason when rejected.

Don’t be intimidate by the arrow functions if you aren’t familiar with them
(parameter) => {/*action*/}
is equivalent to
function(parameter) {/*action*/}

Using the code above would be done by chaining the functions then and catch like that:

The function passed to then() will be invoked with an answer if the promise is or will be resolved. The function passed to catch() will be invoked with a reason if the promise will eventually reject. This way you can relate any async post-action to your code.

How promises work?

Well first, you have to keep’em 🙂

Let’s implement a very simple promise so we could have a better understanding on the basis of what is going on inside. Code followed with deep explanation:

First thing to notice is that when created a new instance of edge64Promise then given parameter action is immediately executed async. This is done by:

action is invoked with two private functions that edge64Promise delivers, resolve() and reject(). I’ll examine one of them, since both are really similar:

resolve() will be executed by the promise’ user when a promise resolves, hence it has an answer parameter. This answer is stored because it is not clear whether or not, at this point the then() is executed. If it isn’t, we are not really sure what to do with the answer and we must wait until then() is invoked. However, if then() is already invoked, then that.resolveCallback would be defined, and so we can call it.

Notice the use of that instead of this, I use it as a conversion in any class function/method in order to prevent context confusions which can happen a lot in JavaScript

At the moment when then() is invoked, we aren’t sure that the promise is resolved with an answer. If it is, we have two parts of the whole, the callback function and the answer to send to it, otherwise, we must store the callback function in case the promise will resolve.

We return that in order to allow chaining the catch() afterwards.

Note: I’ve explained the most plain and simple way of using promise. For instance, Notice that in my implementation you can’t chain .then() twice, and this option is important for other coding techniques which I will might post about in the future.

Summary

Promise will help you control an async code.

The trick in implementing a class like Promise is to realize that resolve() and then() relay on each other. resolve() misses the callback function and then() misses the actual answer. Same goes to reject and catch() but with reason, instead of answer.

How to never use loops again with map, filter and reduce?

Here is a piece of code, it’s purpose is to manage employees’ salary bonuses due to holidays.

Was it ugly? Was it difficult to follow? Were there too many variables? And isn’t it too much verbose? The main problem with this code is that it is not straight to the point.

Lets refactor it so it could lose some sense of repetitiveness.

Replacing loops with map filter & reduce

Here is an alternative nice code:

I successfully eliminated any usage of loops. Notice how short it is. Notice that we got rid of variables such as extra, newEmps and others. The code is less verbose, it is straight to the point.

Now let’s dive deep on how each of the function refactored, so we could have some better understanding on map, filter & reduce.

Filter

Filter loops over a list and checks each item with a predicate function. If the function returns true, the item remains, otherwise it is filtered. An example:

Boys are persons who are children and males.

If you are not familiar with arrow functions whey are kinda nice, a synonym statement would have looked like this:

Map

Map loops over a list and apply a function on each item. All of the results are collected into a new list that returns. An example:

Men are grown boys.

Notice that hopefully grow is a pure function and thus, boys and men are two different lists.

Reduce

Reduce loops over a list and returns a single value out of it. Depending on an iteratee function sent, reduce sums, multiplies or does any other operation. Example:

In the example above, if population consists of 4 people, then iteratee function would have been called 4 times. In other words, if we called the ireratee function countSavings, for the sake of example, then the above reduce function produces the same value as this code:

Bonus Section – How to avoid looping over functions?

If some of the things are still unclear at this point, it is a good idea to read again the salary example refactored and examine it a little further.

Lets go back to our salary example above. Say that salary calculation task was way more complex, in fact it is. If in order to calculate it, we would need a vast amount of functions, how would we do it?

Assuming emp has an array of salary transactions, something like:

Then surely we had to loop over this functions and

Don’t be so sure. There is also a way to eliminate this loop away. Read carefully and twice:

Lets examine the expression above, beginning with (arg, func) => func(arg):
This function accepts two parameters, first is an argument, second is a function. The return value is that which the function (2nd parameter) will return when given the arugment (1st parameter). So for instance, if we call this weird entity kindDavid just for the sake of example, then:
kingDavid(3,x=>x+4) is 7
and
kingDavid(13.5,x=> x==13.5) is true
and more importantly
kingDavid(emp, calculateSalary) is calculateSalary(emp)

Because calculateSalary is a function returning a new emp object it can work perfectly with reduce. First iteration will apply: (emp, emp.transactions[0]) which will return emp.transactions[0](emp). This is actually a new emp with calculated salary. It is now to be sent as a first argument in (result, emp.transactions[1]), which will return emp.transactions[1](result), and so on… Until all the transaction functions applied on a single emp.

The below code emphasizes it:

Want to know more?

Hit

npm install lodash --save

Then

const _ = require('lodash');

And play with it. Full documentation is here.

Summary

If you don’t like your code too straight to the point, use loops.

Subscribe

How to write Wrapper Functions? (aka Decorators)

Wrapping a function, also known Decorating, is parallel to inheriting from an object in the OOP world. It is a way of taking a prototype idea and extend it in a way that encourages code reuse. Moreover, it is a powerful creative tool that open doors to new ways of coding and thinking.

Say we developed a Server that logs many messages like

But it is only after we coded that we realized we forgot to log the actual time of the message. First thing that comes to mind is that the code needs to get refactored, and any appearance of console.log should be replaced with some other function that logs the time as well. This is probably the right thing to do by the way, but for the sake of curiosity wouldn’t it be nice if we could just alter console.log?

Altering console.log

Meet wrapper:

Wrapper is a function that accepts a function as a parameter and returns a function when its done. This makes it a Higher-Order Function, which is the title any function that gets or returns a function earns. The way to use wrapper in our Server is:

console.log = wrapper(console.log);

What just happened here? Lets begin from the right side of the expression, we just sent console.log as a parameter to some wrapper. Wrapper received the function, and in return, it gave back a new function. One that first prints the date, and then invokes the parameter function. The returned function eventually is set back to be console.log itself.

Note the use of console.info in the wrapper. If we used console.log to log the date, it wouldn’t work because by the time it invokes console.log is referring the wrapper, but if the wrapper is within in itself.. it means.. – – – > INFINITY !

Note that the parameter func is accessible inside the new function that is being created, and also available in the time of invoking the inner function (which turns to be console.log). This is due to Closures. In a sentence, any function, at the moment of creation, takes a snapshot of its scope which will remain available at the moment of running. This is called Closure since the scope lives just because it has a reference which is the very function that this scope actually belonged to in first place.

What a closure 🙂

Read that sentence again.

This concept also gives the opportunity for this freak to actually work:

If you are wondering how to use it, this is the way:

But you can also go straight forward:

Last Note
Wrapping a function doesn’t necessarily have to do with mutating existing functions. We could also use wrapping as a function inheritance technique.

This might actually be a more common way, but I just wanted to show off.

For more info see Decorators.

How to write Pure Functions

A pure function is a function where the return value is only determined by its input values, without observable side effects. This is how functions in math work: Math.cos(x) will, for the same value of x , always return the same result

– Wikipedia

Pure Functions fulfill the KISS principle (Keep It Simple & Stupid), Using them in coding can reduce dramatically the complexity of your code. Basically all one has to do is avoiding 2 main mistakes.

1. Not Ecologic

When a function carry side effects, it may become challenging to predict the outcome of invoking it. In many cases, other team member may use our function, not knowing the side effect that will take place. This can cause much confusion. Iv’e seen functions that carry so many side effects that it was extremely challenging to understand how to maintain them.


// Bad example:
function getNewDog() {

   // Create Dog
   var newDog = DogFactory.createDog("woof!");

   // Add it to Golbal list [not ecologic!]
   owner.dogs.push(newDog);

   // Return the dog
   return newDog;
}

In the example above, the owners’ list is altered because this is the programmer intention. But the function name doesn’t reveal it’s hidden affects. A pure way to write this function would be:


// Good example:
function getNewDog() {

   // Create Dog, and return it
   return DogFactory.createDog("woof!");
}

// Add to list
owner.dogs.push(getNewDog());

2. Not Independent

When the value is not determined only by the parameter, a function might be unpredictable of value. It also might cause Error if it runs in foreign scopes. And on top of that, it limits the function to be too specific to task.


// Bad example:
function getHealthyDog() {

   // For each dog of Global owner [Not Independent]
   for(var dog of owner.dogs) {

     // If the dog is healthy
     if(dog.healthy) {

       // Return it
       return dog;
     }
   }
}

The function above is dependent on owner. If the owner changes, the value of the function changes. If the owner is undefined the function throws error. A Pure way to write it would be:


// Good example:
function getHealthy(list) {

   // For each item in list
   for(var item of list) {

     // If the item is healthy
     if(item.healthy) {

       // Return it
       return item;
     }
   }
}

getHealthy(owner.dogs);

Note that by making the function purer, we enlarged it’s purpose and made it abstract. Now it doesn’t yield a healthy dog, but any object that could be identified as healthy.

Pure functions are easy to learn and adopt. They will make your life easier.

Implementing Language Processing

Intro

When writing crawlers, often I found myself trying to figure out what time was a post written when the String that inserted into the Database was “2 days ago at 16:20”. Thus I implemented its-a-date,  a Natural Language Date Description Processor, or simply – when given a Date description, it returns a Date object.

In the process of figuring out how to approach the implementation of a Date Description Parser, I realized that I have to use the Interpreter Design Pattern, in other words, I had to write a Programming Language. Mostly I learned how to do so from this guy. But this article is a shorter and much simpler version of how to implement a Programming Language as a solution for my problem.

First of all, what is the connection between Date Description and a Programming Language? Well, it seems that date descriptions tend to have pretty accurate syntax. Here are some examples.

3 months after 11/01/1990

Type: Relative
Value: +3 Months

Type: Absolute
(Point of Reference)
Day: 11, Month: 1,
Year: 1990

 

An other example would be:

 

2 days ago at 16:20

Type: Relative
Value: -2 Days

Point of Reference: Now (Default)
Type: Absolute
Hour: 16, Minute: 20

 

2 Different Affect Types: The Relative & The Absolute

It seems that date descriptions can contain two affect types, Relative & Absolute. First one, the Absolute, determines different time parts (e.g ‘Today’ – sets the date, or ‘4th’ sets the day of the month). Relatives indicate a movement in timeline according to a point of reference. Default point of reference would be This Very Moment, but if an Absolute part has been set, usually it turns to be the point of reference. For example ‘in 2 minutes’ refers to 2 minutes from now, but ‘2 minutes after midnight’ refers to the hour 00:00.

Note that the scope of an affect type, relative or absolute, is a specific time part. For instance if we take a look at ‘Yesterday, 2 minutes after midnight’  we can see that ‘Yesterday’ is a relative refers to Now, but ‘2 minutes after’ is a relative refers to the Absolute ‘midnight’. 

Some regulations must be applied. We can easily see that 2 Absolutes of the same time part are not allowed (e.g. ‘midnight at 2 pm’, two absolute hour affects). On the other hand there is no problem of chaining relatives of the same time part (e.g. ‘2 minutes before 2 minutes before now’, although it’s somewhat silly).

 

Tokens

After discussing the grammar, or the fundamental rules of Date Descriptions, it is time to talk about tokens. Tokens are the tiniest part of a syntax, it’s a Symbol, Word or a Phrase that has a determined action and a specific role in the language. In JavaScript, for instance, some of the tokens are: {, if, new, ) & case

In the program, tokens will carry the logic of the Affect Types discussed above. Every token must have a predefined meaning that the interpreter can resolve. Lets review some of its-a-date tokens:

 

febsnip

 

The regex determines whether or not a token is invoked. The Affects is an array of consequences this token is going to carry, in this example, the month time part will be absolutely 2. this may also be the point of reference in case of a description like ‘3 months after February’.

 
 

agotoken

Notice that here we got a token of some other kind. It doesn’t have an Affects array, instead it has an affectGenerator function. The purpose of this function is to return an array of affects, given the values from the regex capturing groups. Notice that not only the value of the relative affect is determined by the matches, also the time type. When the description is “5 days ago”, the day part is altered, but if the description is “5 minutes ago”, the minutes are altered.

 
 

hourtoken

In this token example, we can see the affect generator that we recognize, but the special case here is that a single token have 2 affects. One over the hour, and the second over the minutes.

 

Interpreter

It is time to leave you with the riddle of how to implement the code that translates these tokens, and others, into a date object. If you are eager to fully understand how it actually works, I feel it is best understood when debugging. I welcome you to download the small project from Github, or just hit:
npm install its-a-date --save
and then…

 

itsadate

 

If you feel like contributing to the project, pull requests will make me happy. Implementing tokens for further more foreign languages can be a good practice of this article’s ideas, and as well very appreciated.