Elm is a great little language for writing front end web applications, i.e. apps that run in the browser. There are already several great resources available for learning Elm, like the Elm Guide, Road to Elm and many other resources collected in the great compilation Awesome Elm. Yet many of these resources focus on explaining either the language itself or how to create web applications with it. In this little ebook I want to attempt both at the same time - to teach Elm, the language, and how to build a web applications with it. I am writing it as a gentle introduction for people who have never worked with a functional programming language before. If you will, it is a bit like an extended preface to the Elm Guide that takes some time to discuss the various concepts of the language while building a simple example web app.
I intend to revisit this text in the future and add an additional introduction for those who have no prior programming experience, because I recon that Elm is a great way to get started with programming. Yet, for now, the book starts with a reader in mind who knows a bit of programming, some html, css and at least a superficial understanding of how Javascript is used to modify the DOM of the browser. If you don't, I do hope that you might still follow along - but you will probably need to take some detours and look up some concepts. If you don't understand some remarks in a sentence, try to read on - I drop some terms from other languages every once in a while to build mental bridges where appropriate, but if these don't make sense to you it should not hinder understanding of the concepts in Elm itself.
I explicitly do not expect the reader to have any experience with functional programming languages like Haskell or OCaml. If you do, you are already an expert in another functional programming language in the ML family, this series will be pretty verbose for you and may want to look for a more succinct introduction :).
If you have some experience with Elm already, you may be tempted to skip the first few chapters. I would advise to still at least skim them by jumping from header to header, as a solid understanding of how functions and types work in Elm is key to avoid confusion later.
We all have limited time available and even though learning is often rewarding in itself, the reality is that there are so many interesting things and we have to pick and choose which road to go down. If you are still evaluating if you want to learn Elm, here are some points in Elm's favour and why I think learning and using it is a worthwhile endeavor:
Elm is a well designed, modern language. It compiles to Javascript and is designed to be used to build web applications from the ground up. It has a great type system that is both easy to use and makes many errors impossible (more about this later, but basically Elm does not use null or undefined - the dreaded "undefined is not a function" or NullPointerException from other languages simply can't happen in Elm)
Elm is small. It is small in that the language itself can be picked up by someone familiar with the concepts in a very short time. Other languages with a similar syntax and philosophy as Elm, like Haskell or PureScript, are able to express more powerful abstractions - but this comes at the cost of additional learning time to master them.
Elm is young. Unlike languages like Javascript or C++ or Haskell that have evolved for two decades or more, the first public Elm version was released only in 2012. Elm thus has not collected as much cruft as some older languages and was able to learn from some of their mistakes.
The elm compiler is like a friendly programmer sitting next to, helping you along (as @clarkware put it once on twitter). It is hard to explain this to someone who has only worked in dynamically typed languages like Javascript or Python - let me just say that Elm's great type system means that the compiler will help you catch many errors before you will ever run your program.
Elm's type system is quite a bit more powerful than e.g. Java's or C#'s type systems because it implements Algebraic Data Types), yet writing down types is almost always optional, because Elm can always figure out the type of every value. This, combined with a compiler that was built from the ground up with the goal to provide good error messages means that the compiler has a really deep understanding of the data flow through your program and can help you find inconsistencies. When you change something, the compiler will tell you all the places you need to change until the entire data flow is correct again.
In my experience, this allows you to develop complex projects at a higher speed and with much bigger confidence. Requirements will always change, and when they do, you are well equipped to deal with them.
The Elm Architecture, the way elm web applications are structured, leads you to a great design that is conceptually simple, because all data is immutable, collected in a single place and changed atomically in the update function. Views are pure (idempotent) functions that turn your data into something that is visible on the screen - with the same data leading to the same outcome, always, perfectly reproducibly. User actions, timed events and the results of XHRs (Api requests over HTTP) are all modeled as messages that are sent to your application and trigger a new cycle through the update function. This approach means that there is always a single source of truth - the problem of inconsistent state between several components is almost eliminated.
Elm is a great introduction to functional programming. Learning Elm will make it easier to learn other, more complex functional languages like Haskell, Purescript or OCaml. In my opinion as someone who has used many programming languages over the years, this family of languages represent the best general purpose tools for writing correct, maintainable code. That said, even if you end up working mostly with other languages, the concepts you learn in Elm will equip you with new ways to think about programming problems and make you a better programmer.
Ok, this may be weird - why would I suggest you learn something else instead? The thing is, Elm has a particular focus, and you have to decide if the benefits of learning Elm are worth it. I like Elm and so I root for it, but ultimately you have to decide. In this section, I want to point you to some other languages that may be more relevant for you, depending on what you want to do.
Elm is not a general purpose language. If the above sounds interesting (a great type system, immutable data, ...), but you want to write native applications for desktops or smart phones, or if you want to write backend code for the server, you are more or less out of luck right now with Elm as it specifically compiles to Javascript and even there is mostly designed to be used in the browser right now (support for node applications is still hacky).
If you want to create desktop applications, you may want to see if you can write in Elm and use Electron, but you may be better of learning something else. A great purely functional programming language is Haskell, although it's learning curve is quite a bit steeper. It compiles to native code and can be used for a wide variety of applications. If Javascript as a compile target suits you fine, but you need to write server side code, Purescript is probably a better match for you. If you are starting with programming and want a language that is relatively easy to learn and quite general, Python may be a good choice (it is dynamically typed though and makes it a lot easier to make mistakes)
Elm's type system does not allow a great deal of abstraction. Abstraction is always a trade-off and I think that Elm struck a very nice balance, but there are cases where some more powerful abstractions might be nice for complex applications. If you like abstractions in general and/or already know that you can't live without higher kinded polymorphism and type classes, you may want to go straight to PureScript (if you want to target the browser or Node), Haskell (if you want a general purpose language) or Idris (if you want dependent types and be at the cutting edge of type systems in programing languages)
Elm is not widely used yet. This is a bit of a chicken and egg problem, because it will only get better if more people use it, but this can be a real concern. There are not a lot of companies who are looking for Elm programmers, but there are bazillions looking for Javascript devs. The ones who do look for Elm people are probably great though ;).
Elm does not cover everything you can do in the browser yet. While a lot of the major functionality of modern browsers can be accessed in Elm, some things are not yet possible (e.g. manipulating binary files through the ArrayBuffer interface and similar). While there is a mechanism to send messages to native Javascript from Elm and the other way round, and thus handle such challenges with native Javascript code, an application that uses a lot of cutting edge features may have too much code in Javascript to make it worthwhile.
When you learn something new, there are always points where you get stuck. Such situations can often be resolved quickly by asking someone with a deeper understanding. For Elm, there are two great resources where a lot of nice people from the Elm community hang out to answer questions: One, best suited for smaller questions, is the Elm Slack. The other, ideal for longer questions, is the Elm google group. Don't hesitate to ask for help, we all started out not knowing any of this stuff in the beginning :)