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