 So yeah, hello everybody and thank you for joining me here. I will be talking to you about Elm today. This is going to be an introductory talk about the language and I'll also be sharing about our experience in using a language like this to build a real world application. And yeah, I'm not actually going to go serve tea or something. That just stands for the Elm architecture. So a bit about myself, my name is Ritesh. A couple of months back I joined big binary as a senior software engineer and we wanted to build a product that would provide contextual help documents to the users and we call this product is help. So this is still like in the very early stages and let me give you a quick overview of what is help is and what we wanted to achieve with it. So for the sake of an example, let's assume that you have a web app to upload and edit videos or something. And you wanted to provide some helpful documentation to your users. Guides, so to speak. So what you could do is you could sign up on ASEL create your documentation by following a few simple steps. I won't go into the details and once you have your documentation ready then you can get a JavaScript code snippet which you can then insert in your app or website. This is much like, you know, how you would integrate Google Analytics or intercom or something like that. So once you've done that a small button or a help icon would render in your website. The user can then click on this icon and this would open up this widget which would, you know, provide the help documents for your user. Now one important feature of this product ASEL is that it provides these help documents based on a certain context rather than the user just having to search through, you know, a repository of things. So it takes into consideration things like the current location or the URL of the user that's, you know, that the user is right now in and suggests some articles to the user based on these parameters. So yeah, I mean that's just, that's the gist of the application. The gist of ASEL and these are all mock screens so you don't have to worry about this. Now we knew that the front end would involve a fair bit of work and there were two parts to it. One was developing the widget side code which would reside in the, you know, the client website and the other is developing the admin side where, you know, the users would sign in and create your documentation and stuff. So yeah, the front end, right? I mean there are a number of frameworks and libraries out there that you could have adopted and these are just amongst the, you know, the popular ones. I'm not even sure if people use MobX but yeah, that's that. And these days it's quite difficult to pick one, right? Most of the frameworks have evolved over the years and they've come a long way and you really have to look at certain other aspects to pick the right one for you. That being said, we do quite a bit of work with React within big binary and we like React and its ecosystem a lot but this is all still, you know, JavaScript and we knew that if we relied on JavaScript and any of its framework and tooling, it would still bring in issues that inherently exist within the JavaScript world and as the code base grows, it's only a matter of time that these issues, you know, start cropping up. So if you've dabbled with front-end development then for sure you must have faced issues like, for example, with null or, you know, undefined is not a function and JavaScript is inherently impure and mutable. Now, this is not just me being pro-FP here and, you know, bashing JavaScript but it's a known fact that this leads to unpredictable behavior and bugs. Now, there are measures again that we can take to curb these problems. TypeScript and Flow, for example, gives us static type checking, right? And it's great. But again, there are times where we need JavaScript's dynamism to work for us or rather as front-end developers, we tend to fall back on JavaScript's dynamic nature to, you know, for shortcuts. So both these systems, they give us the any type which essentially allows us to escape the whole type checking altogether. And sometimes functions become rather complex and it's really hard to determine what the type signature should be like. This might be because the function itself is impure in nature, might be mutating some external state or doing multiple things, you know, within. And of course, we can use other libraries and, you know, tools to further enforce things in our codebase, use immutable data structures, linters and build up some discipline. But even that might not be enough. So this is a recent screenshot of the Slack app captured by one of my colleague at big binary. Yeah, see what I'm saying here. So now I'm not really hating on JavaScript here. I love the language. I still use it. It's super flexible, multi-paradigm. But due to JavaScript's inherent nature or rather maybe it's right to say due to our human nature, the cost of this flexibility can be quite high for us, especially when it comes to software development. And if you don't handle it well, it can get really hard to feel confident about our code, especially as the codebase grows. So when we look at ASELP as a product where we need to get integrated with the user's website or app to display the help widget and to provide help documents to their users, it becomes especially important for us to avoid such kind of issues. It definitely would not speak well about the product if these kind of issues did crop up and spoil the entire user experience of the website. So what do we do? Well, there were a couple of choices out there to tackle these challenges. But for us, one particular candidate stood out Elm. Why? Well, a quick look at the Elm website and the feature that's enlisted at the top is no runtime exceptions. That's a pretty bold claim in front-end land. Actually, there are some cases and known issues where it may not guarantee this, but for the most part, it does. There are a bunch of other features too, like great performance and small asset size. Now, this is the Elm real-world application that compiles to one-third of the size of the React version, which is pretty impressive. And there are a couple of more benefits. So what is Elm? Elm is a functional programming language for declaratively creating web apps. It compiles to JavaScript. So in a typical Elm app, you would have a bunch of modules, Elm modules, and an entry point. You then compile it down to a single output, which would have the JavaScript code. Now, the output is not meant to be human readable. The point here is that the compiler would do the best job for you and you don't have to worry about it. As I said before, it's a purely functional language. It has strong static and type inference. Elm has a huge emphasis on being beginner-friendly. There is a learning curve, but as a functional programming language, it does not bog you down with a lot of things, but just enough to get you started thinking in a certain way. So you won't find funky terminologies that are used by functional programmers. So it's a bit easy on you. Okay, let me give you a typical example. This is an ad function in JavaScript. And here is the same function in Elm. So the syntax, as you see, is worlds apart from JavaScript. It is actually more close to Haskell. And there is a bit of getting used to here, but once you do, it's actually fun. So we define a function called ad, and it takes two arguments, x and y, but notice that we separate them with white spaces. And there is no parenthesis or comma. And that way it's a bit more terse than JavaScript. Notice also that there is no opening and closing curly brackets or anything like that. In fact, the function itself is a single expression. There is no concept of multiple statements and a return keyword or anything like that. And this is how you invoke a function. And since all functions in Elm are pure, which means it cannot mutate any external state. And it purely depends upon, you know, the values that are passed to the function. And that gives us strong guarantees in the sense that whenever we call this function, we're sure to get back, you know, what is otherwise expected. So this function gives this would always be 10. Okay, so let's try it. Let's say we implemented that function, which would display that bit of text in the Slack app that we saw. View all, you know, some number of users or members. Here is the JavaScript version. Again, it's quite simple, but let's just examine this. So if we pass a list of users or, you know, an array of usernames, we get the expected result. But what happens when we pass it nothing or a number? And as we saw in yesterday's flash talk, if the implementation was slightly different, we could get all sorts of unexpected results. Okay, so let's try to do the same thing in Elm. So if we, I mean, you can just have a look at the code. There's nothing much going on here. It's pretty much the same as what the JavaScript code did. So if we pass the right values, we obviously get the expected result. If we try to call the function with another type, let's say an integer, the compiler with throw an error. So this is Elm's type inference coming into play here during the compilation process, and it notifies us that we are not passing the right type of argument. This code will never compile, and it would never make it to the user's screen. Okay, so what happens if we don't handle the Elm's condition, which is very well possible in JavaScript? But the thing is in Elm, this whole if Elm's thing is one single expression, and it has to be complete. The compiler basically forces us to handle all conditions. And if you don't do that, obviously you'll get an error, and this gives us, you know, strong guarantees again. So all functions in Elm are carried by default. So if we go back to the add function, and if you call the add function by just giving it one argument, you would get back another function, which is, you know, waiting for the final argument. So you can create an add five function, which expects just one argument and, you know, just adds five to it. So we saw that Elm can figure out types. It can infer types, and it is pretty accurate at it. But it also lets you write a type annotation on the line above the type definition if you want. So here's how you would define a float, a string, a bool and a list of, you know, integers. And the way we do it is quite simple. You just have the identifier followed by a colon and, you know, the type. And this is how you would define, you know, the type signature for functions. And this, you know, introduces arrows. So if you look at the half function, the way we read it is from left to right. So it takes in a float and returns a float. And the way, and we, and when we have like multiple arguments, for example, the divide function. So how you would read that is it takes a float as the first argument. Then it returns another function, which takes another float. And that function finally returns a float, right? And as, you know, how you said this is also using the Hindley-Milner type system. Now people can make mistakes while defining type annotations. So what happens if we say the wrong thing? Well, the compiler will still figure it out for you and, you know, try to do, try to match the right thing for you. And it would even suggest, you know, it should be a float instance of a int in this case. In other words, the compiler will always verify that all the annotations are correct. Okay, so in ASELP, you can create these articles, right? And articles can have a title, a description, categories, URLs and a bunch of other things, right? So Elm allows you to create something called as type aliases to represent something like this. And which is nothing but defining the shape of the, you know, the record type. And this is how you would actually create a type of article which we defined in the previous slide. It's pretty similar to how you create an object in JavaScript, except we use the, you know, equal to sign instead of the golden sign. And we can use this in our type signature as well. So let's say we have a function which takes in a list of articles and returns a list of and extracts the title out of it and returns a list of title. So yeah, so this is how you would define that. And notice the dot title method over there, a function over there. So that's the same as, you know, calling article.title. It's just that you have record field accesses as functions also in Elm. Yeah. So this basically just extracts the value out of the record and that that's it. Yeah. So Elm has a pipe operator that sort of relies on partial application. For example, say we have a function that takes an article, extracts the description, truncates it and adds an ellipses right to get a short summary, so to speak. Now a better way to represent this is by using the pipe operator. So in this pipeline, we pass the initial input to the dot description function and then the output of that gets passed to the truncate function and finally that the output of that gets passed to add ellipses. And yeah, and that the bar and the greater than sign is how you represent the pipe operator. On similar lines, we also have an operator to compose functions. The only difference being here is that we do not pass the initial input to the pipeline and by doing so, it's you know, it's it's known that we return a function that's waiting for an input and obviously the operator is different, right? So all data in Elm is immutable. So this article type, it gets passed around a lot in a lot of functions in our repo in, you know, Excel. So if you wanted to create a function that takes in an article type and we wanted to update it to something new, we wanted to update the title to something new. The way we would do that is by copying the original article. And so here we are saying that, you know, take the original article and keep all the other fields as it is. But for the title, set it as the new title. I mean, that's how you would work with records. Now the benefit of doing this is that there is going to be a flow of data without worrying that some random function might be, you know, mutating the original value, which is otherwise possible in JavaScript. And these are sources of bugs that can be quite tricky and difficult to track down. All right, custom types. So in ASELP, an article could have this status, which can either be active or inactive. So if the article is active, it will be displayed in that widget. And if it's inactive, it won't be. And the admin users can set the status of the article as active or, you know, inactive. Now we could use strings to, you know, represent this status, but then we have to check the value of the string to be, you know, equal to the string active or inactive. And we'd be concerned about upper cases or lower cases. And what if, you know, there are typos and what are the values changes altogether? So we might have to do some runtime validation to take care of this, right? So a better way to represent this status is using a custom type. So I can have a status type, which is either active or inactive. And now I only need to deal with these two variants of this type. So if I have to set the status of the of an article as active or inactive, I just use one of these variants that we defined in the previous slide, right? And yeah, so you just set it as one of these variants and your status type is now type checked. So if we give it any other value, the compiler will fail. And thereby we can just avoid, you know, writing a lot of runtime validation code. Okay, so let's say that we requested for an article from the server, but that article does not exist. And the server returns a null, right? But sometimes we need, so basically Elm does not really have a, does not have a null or anything equivalent to a null. But sometimes we need to represent this, right? We need to represent no data. So how do we do that? The one way to do this is by using the maybe custom type, which is sort of built in with the core library. And the variants of this maybe type is just either yeah, just a value or nothing at all. So notice the A here. That's that's a variable type, which is to say that the type constructor of just takes, you know, any type. So it's like a boxing type. It, it's a little difficult to explain this. It, yeah, that's what it does. It just wraps around some type, some other type. So we can have a maybe of end, a maybe of string, float or, you know, even a maybe of an article. Yeah, so this is, so we can have a default article, which is just some empty value or we can have nothing at all. But the thing is that we will have to deal with both these cases now. So let's say somewhere in the view we wanted to display some text if the article was found or not found. Then we can use this case expression to do this. So this is basically a fancy sort of way to do switch cases. So the incoming article can have can come in two variants, right? And it can come in only to a different variants, the just and nothing since it is a maybe type. So the case expression allows us to do what is called as pattern matching and you can just, you know, sort of do this by branching out into these two types. Yeah, so basically this allows us to have like, this will always return a string no matter what. So yeah, so that's a basic overview of the syntax and how certain things work in L. But it just it doesn't end with just that. Okay, so in today's day and age, what do we need to do to build a fairly large front end application? You need some kind of package manager, a compiler or a and a module bundler, some kind of a framework to hold things together and a bunch of other libraries and tools to, you know, to be careful about our code and avoid bugs. Now this can be a pretty daunting task to, you know, wire all this together to get things going, especially for a beginner when you don't really understand what these different components might be doing. So in Elm, there is an equivalent of what, you know, all the things that we saw in the previous slide built in. So it has its own compiler, package manager, repel and a dev server. It also has its own built-in framework, which is the Elm architecture and it enforces this architecture to build, you know, web applications. The, the working is actually pretty similar to Redux, as you can see. In fact, the creators of Redux also mentioned that Redux was inspired by the Elm architecture in some way. So, so Elm applications can basically take over a single node in a larger application or they can cover like the, take care of the entire document, so to speak. So you set up your app through what's called an Elm program and that this is the core of the Elm architecture and it lets you define one of these programs using these helper functions. So you can have a sandbox. This is primarily just there for you to learn and understand the basics of the Elm architecture. It's solely there for that purpose and then you have something called as an element function which also lets you create a program. Basically, this will allow you to create an just one HTML node which is managed by Elm. So you can, you know, easily integrate into larger applications that are not built in Elm. Then you have the document type which lets you take care of the entire document. Elm manages it for you. Basically that includes the title and the body as well. And finally, we have the application type of program which is like the real deal. It lets you do, that's what you would use to build a single page application. So you can do routing and stuff like that. Okay, so if you look at the type signature for the sandbox function it has one argument and it takes in these three different parts. And so you have the init thing which basically takes in a model which is the state of the app and would hold the data of the app. Then we have the view which is a function which takes in the model and returns an HTML message. We look at that briefly in the next slide and then you have the update function which takes in a message or some user action. Then it takes the current model and returns us the updated model. Okay, so if we create a sandbox program from a high level it would look something like this. You have the Elm runtime within which your application would reside and the Elm runtime is going to manage the data flow for you. So even the HTML that you define in your application is managed by Elm and it's not even like real HTML, it's virtual DOM. The Elm runtime would finally figure out the actual HTML. So the basic flow would look something like this and this is very simplistic representation of it. So you have the initial model which would give out the view. Then you can have events, basically user actions or something like that which would trigger an update. And that would finally update the model which would return the updated view. I mean we're all familiar with this sort of flow. So in the sandbox program you do not have access to the outside world at all so you cannot do like something like Ajax request or anything like that. You can just describe the HTML. So how do you cause side effects? I mean if you don't do side effects you don't really have a real application. So if you look at the type signature for the element function which also gives a program, an Elm program, there are a couple of changes. It introduces something called as subscriptions which takes a model and returns something called as submessage. We won't look at that right now but the interesting thing is that the init and the update methods are also different here. So the return type of both init and update is right now modified. Instead of just returning a model it right now returns something called as a command message. And we look at that. So unlike the sandbox program, the element program can communicate with the outside world in a couple of ways. You can use commands to trigger the Elm runtime to do HTTP requests. You can subscribe to events like clock ticks. You can pass in data from JavaScript through flags as the Elm program starts. And then finally you can interrupt with JavaScript using something called as ports. So basically you can essentially fire a command to do an HTTP request to the server. And once that gets completed that would trigger an update with the message and the payload. And then you can and that would again update the model and update the view finally. So that's a very basic overview of the Elm architecture. And one other thing that I wanted to share with you was about a great refactoring experience that you get with Elm. Okay, so so you have this article type, right? And in a cell the shape of this article type went through multiple iterations. So initially when we defined it could just have the article could just be assigned to one single category. But then later we changed it so that it has more can be assigned to multiple categories or a list of categories. Then we added something called as URL data to this article type. So the thing is that I mean this whole thing gradually happened over a period of time and as the requirements changed and you know a lot of things happen. But all we had to do really was you know change the type definition and the compiler would obviously complain. But this acted as guides so to speak. So that it would allow us to make changes in throughout the code base and no corner cases were missed primarily. So this is otherwise such a huge issue because it is something if you're not careful enough in JavaScript it could cause bugs and eventually that would finally land up in the user screen. Okay, so this might seem like a lot and yes there is a learning curve. But at the same time I've seen a couple of people a lot of people just you know catch on to the language pretty fast. It's just that the initial effort that you need to put to understand the syntax and that a couple of things that can be a little difficult if you're not used to this sort of a language. But yeah, it's it does it does take some time but you can get over it. And one important thing is that when you're writing applications in L you are building for the long-term benefits. Especially when in terms of maintainability and it's obviously safety first but and you end up building applications that are very predictable in behavior. It is highly opinionated. It can sometimes feel very restrictive at times, especially when you're interrupting with JavaScript or the outside world. I might also add that it has a great community. So the Elm Slack channel basically is always active. There is always someone there you can easily reach out to people if you're stuck and there's always something someone there to help you. And this was a recent tweet by Richard Fledman who works at Node at Inc. where they have like for 200,000 lines of Elm code in production. And yeah, so after two years that's when the finally encountered a runtime expect error and that too it was because of you know, debug.cache. So yeah, so basically that's the kind of reliability that you get from the by using by working with this sort of a language. Incidentally, the creator of Elm, Evan Ciszapliki if I'm pronouncing the name correctly also works at Node at Inc. Okay, so how do you get started? You can visit the Elmlang website. It has great documentation and then you can also visit the guides.elmlang website. It does a great job of onboarding users to the language. Great documentation again. There's the Elmspar example by Richard Fledman. That's a great resource if you wanted to look at the code of a real world application. And then finally as help is it's also open source. You can have a look at that or you can just talk to me. So in conclusion, I would like to say that in today's day and age, there are a great variety of tools and frameworks and languages available to build the front end applications. And when it's when it is a question about building reliable robust front end applications, Elm is one such language that should not be ignored. Thank you.