Conf42 JavaScript 2022 - Online

Are promises our only choice?

Video size:

Abstract

Promises are the standard approach to handling asynchronous operations in JavaScript and TypeScript. While they are flexible and fun to program in, important downsides make our codebase less maintainable. For instance, errors in a promise are typed as any, they use eager evaluation, and you can completely omit a catch operation for error handling. So there should be something else we can use, shouldn’t it?

In this talk, we will be learning how to use functional programming and some alternative asynchronous computations like TaskEither, ReaderTaskEither, and Futures to show how we can handle side effects and create more robust applications.

Summary

  • Jamaica real time feedback into the behavior of your distributed systems. Errors in real time allows you to not only experiment with confidence, but respond instantly to get things working again. We are going to be talking about promises and some functional programming alternatives.
  • When Javascript is running asynchronously, instructions are not necessarily executed one after the other as synchronous operations. Some of the examples of how to handle or create asynchronous code can be callbacks, promises, or a simple weight. But there are some things that can be better and some others that we might forget to handle.
  • functional programming is the process of building software by composing functions, avoiding shared states, mutable data and side effects. It is a mindset, but technically is a programming paradigm. And Javascript is a multi paradigm language, so we can apply it to it.
  • Here are some functional alternatives to promises. These options come from the FPTs library, functional programming typescript. Flutter that we are going to be checking remote data also comes from the library. And we also have this alternative that is effects that we will be talking about a little bit later in the demo.
  • A task is basically a promise that can never fail. The main benefit of a task is that it is lazy. Lazy means that the task is going to be run only when it is needed. This is the main difference between a task and a promise.
  • Composable means that we can combine functions, simple functions, to create a more complicated one, or function that can resolve something or care. Let's check the difference between composing if it's possible, in a promise, and a task. It is not lazy and is not referential transparent.
  • We are going to be using not only a task, but a taskeither. This is an algebraic data type. It is a much more strict way of error handling. It obligates you to tell if the operation or whatever you are creating is either an error or a successful type and task.
  • In the case, if it's not initialized, we might have to set here all the user states to handle those possible cases. Instead, here we already have them thanks to the taskeither. Not only useful, but also restricts the developer on how to handle things.
  • remote data is a library that is completely compatible with fpts. It divides the request or whatever asynchronous operation that we are doing into four different types or states. What happens on pending, what happens on failure, on success.
  • Flutter has a library for functional programming called futures. It has the same advantages of a task either of functional programming. It is also cancellable, which means that you can cancel a promise. This is super useful for systems like react or view or something that is reactive.
  • Effects is library that allows you to build software in a purely functional manner. Once you get the concept and the mindset of functional programming, it's going to be easier for you to use any of this. Use these libraries with caution because as everything you can start implementing them without the good practices can overkill into your application.

Transcript

This transcript was autogenerated. To make changes, submit a PR.
Jamaica real time feedback into the behavior of your distributed systems and observing changes exceptions. Errors in real time allows you to not only experiment with confidence, but respond instantly to get things working again. Close everyone. Welcome to the stock. We are going to be talking about promises and some functional programming alternatives for asynchronous operations like task taskeither, remove data or futures. But first, let me introduce myself. My name is Natalie Rocha. I am from Kito, Ecuador. I am a software developer at stack builders, and I also like to play the guitar a lot, and we run a business here for planning social events. Yeah, that's something you can know about myself. But let's dig into what asynchronous computations or operations are. Right? As you know, JavaScript is by default a synchronous language. Let's say it's single threaded. All right? So this means that instructions can run one after the other and not in parallel. So if we want to interact with external data, like reading files, or fetching data from third party APIs, or executing time operations, when the interpreter reaches these sort of tasks, it actually blocks everything else that can be executed until that operation is fetched or returned, or succeeds or fails. Right? These are called synchronous operations. So to solve this issue, for blocking that thread, we can use asynchronous code, right? Think of it as code that can start now, that you can ask for something and JavaScript interpreter can solve it later, right? So when Javascript is running asynchronously, instructions are not necessarily executed one after the other as synchronous operations, right? Some of the examples of how to handle or create asynchronous code can be callbacks, promises, or a simple weight. We are going to be centering ourselves in promises. Here we have some of the main characteristics of promises. And first of all, promises solve the callback hell, right? So callbacks are just functions that are passed into other functions. So for example, if you wanted to resolve an asynchronous operation, one after the other, you had to call one function. Then inside that function you call another function and then another one. So as you can see in this graphic, this is what you ended up with, right? Promises are declarative, which means that we write code that describes what we want the computation to do instead of telling it the flow or exactly adding the steps that we want the computer to run, right? So it's a more functional approach. After that, it has control flow, which means that we can tell when an operation succeeds, do this, or when it fails. We can error handle in another way. So it has control flow when we are computing right. Another thing is that it has railway oriented programming. So this means that we basically have a couple of rails. The left one can be the error rail and the right one can be the succeed rail. Okay? So when any kind of computation is in the succeed rail, it can actually jump into the other one. It changes the rails to go into the failed rail because that promise failed. That is sort of how it works. And they are also fun to programming, so they are really simple to think about it, they are really simple to get it running. As soon as you start programming, you can make a fetch to an API can, whatever, catch whatever else. So yeah, the promises are really great, but as good as promises are, there are some things that can be better and some others that we might forget to handle or things that kind of happen without the developer knows. So that can cause errors in our applications, for example, egate evaluation, error types and checkered exceptions and others. We're going to be checking more of this in the demo. Right, but first let me explain a little bit about functional programming, just in case you don't have much concept of it or how does it works. I'm going to be explaining just a little bit of what it is, because it can be a little bit hard to get into it at first because it is actually more like a mindset. You have to start thinking in a functional way. But just to give you some idea of what it is, let's explain it a little bit, right? I mean, functional programming, as I said before, is a mindset, but technically is a programming paradigm, right? So is the process of building software by composing functions, avoiding shared states, mutable data and side effects. Okay, another characteristics and principles of functional programming are, for example, that it is declarative. So again, we have to tell the computer what we want and not necessarily add every specific instructions, like in imperative programming, of how we want the program to be running, right? So it's more like when you define a mathematical function, you create a function to describe what you want the result to be. Some other principles are the immutability. It specifies that basically you cannot transform things. Like for example, you define a variable to be zero, then in other part of the program you decide that that one is going to be one. Then that is going to be transformed into arrive, then into a string, because those are things that we can actually do in JavaScript. But in functional programming, immutability has to be present. We also have pure functions, which means that if we define a function that sums one value plus the other. The result is going to be exactly the same every time we sum that value plus the other. Those are pure functions. Also, functions are first class citizens that we can pass. Functions are as parameters to other functions or higher order functions. So these are concepts that are present in functional programming. You can dig a little bit on it, but it's a really cool paradigm. And Javascript is a multi paradigm language, so we can apply it to it. Awesome. Now that we sort of know what functional programming is, if you didn't, here are some functional alternatives to promises. We have tasks, task eater. These couple of options come from the FPTs library, functional programming typescript. It's a really cool library that has many modules that can help you program in a very functional way. Your code. We also have futures. They come from the library. Flutter that we are going to be checking remote data also comes from FPTs. And we also have this alternative that is effects that we are going to be talking about a little bit later in the demo. Cool. So let's jump into the demo to check the functional alternatives to promises. Okay, so for the demo, I have created several examples that explain the alternatives and the difference with the promises. So let's start with lateness. For this example, we are going to be using FPTS task. So what is a task? A task is basically a promise that can never fail, which means that it doesn't need like error handling or stop, because it's always going to be resolved and succeed. So why to use a task? I think the main benefit or the main concept of a task is that it is lazy. Lazy means that the task is going to be run only when it is needed to be run. Like when we call it or when we, I don't know, we use a use effect or stuff like that. But they are always lazy. We can create them anywhere in our code. We can define that promise anywhere in the code and it is never going to be called it unless we do it. And that is the main difference with a promise. Right? Why? Let's check this code here. If we define catch that returns a promise that can be resolved and we can get the data from that promise if we call it like this, even though we are supposedly saving it into a constant, this promise is going to be called as soon as we load the application. Let's check it. So here, I don't have it called. If I save this, as you can see, it is called as soon as we load the application. Why this happens like that? This is because the promises have eager evaluation which is exactly the opposite to lazy evaluation. Eager evaluation means that whatever thing you create is executed or run it as soon as it is created. That's one of the first main difference between a promise and a task. So here we can check a little bit on how a task is defined. As you can see, it has exactly the same code as the promise that we have up here. Well, the only difference is basically the repository or the GitHub user that we are calling. Right? And here we do the same like then, and we get the data. We can also do this, but I will explain that later. So as you can see, there is not much difference. The main difference is this part, which is exactly what makes a task lazy. If we remove this should be like that. As you can see, the type fails because a task cannot be running immediately as a promise. So here it's going to say it cannot be a promise. So the concept is exactly that a task is a promise that is lazy and can never fail. Okay, awesome. So if I want to call the task, you can do it with no problem and you can map it, you can get the data as exactly the same as a promise. But the benefit is that it's not going to be called immediately. So we can call it in a use effect. Or in this case, I just created this small function that is going to be runted with this button here. So if I run the task, the task is going to be called only when I decide to call it. Okay, awesome. That's the first example. Let's move to. I would like to show you composable. Composable means that we can combine functions, simple functions, to create a more complicated one, or function that can resolve something or care, transform some data that we have into something that we actually needed. So for this case, let's check the difference between composing if it's possible, in a promise, and a task. So first of all, as we said before, promises have bigger evaluation. So as soon as I call this promise here, I can't actually compose the functions, or I can't actually use the data, or I can actually use the data before this has been retrieved. So here, let's check. In a normal promise, I fetch right, then I get the Json, and here, finally, when I call it, I get the data, and only once I get the data, I can start making things like filter or mapping or things that I need to do, right? So let's check the difference with the task. Cool. Here we are creating the task. As you can see, it's exactly the same as the promise as we explained it before. But the difference is that it's going to be lazy. So we are not calling this, and let's check this difference without getting the data, as you saw here before in the promise, without getting the data here, I can start composing the functions. So for example here I use a pipe. Add pipe is a utility function in FPTs that helps me with composition. So what it does is exactly that, to work as a pipe, I get the data that is running into another pipe, which is going to map something, filter, transform, reduce. I can compose and combine as many functions as I want in order to handle the data, right? So here what I'm doing is starting with a task which is here, but I'm not calling it yet. I am just saying that I'm going to use that task and I want to map that task. This map is more or less, you can think of it like then in a promise for the task. It's not exactly that bad. It's when you actually resolve the task that you are passing here, and then we can start making whatever we want without calling the task first. So here what I'm doing is calling a filter to get only the Javascript repositories. Then I'm converting it to a map to get only the names of those repositories. And then I can set task repos, I can console log, I can create an alert, whatever I want. What I'm doing right now is just using react user state to save that data here. So as you can see, even though I do not have called the task yet, I can start manipulating or creating composition of that data, which give us a lot of advantage when programming, and it is also more referentially transparent. So I'm going to explain that a little bit later. By the way, as you can see here, if I call the pipe here, here at the end of that composition is where I call that task. Not inside, not before, after. So I created here a function that is going to call that task, and that is exactly what this thing is doing here. So let me show you here in the code, as you can see the promise, run it immediately. It does the things that it has to do. And if I run the task, it runs the composition, the pipe that we created, and that should be it. Okay, let's continue with referential transparency. I talked a little bit about this before, but let's check it in the code to notice the difference. I created a couple of functions here. As you can see, we are creating an array or a tuple of promises so just the, no science, just create an array, I create a new promise that is going to do something. Basically what it does is going to resolve into can array of the promises that were called here. So just call the promise here and here and that's it. So if I call this right, as you can hear it says, as you can see here, it returns me exactly that. I just run the promise number one and the promise number two and that's it. But this code seems a little bit repetitive. So what we can do is just create a promise and then create a functions that return a promise and then call it into the arrive, as you can see here. Right. So what I am doing here is creating a promise. I create it and insert the promises that I want to run in here, which should return to the same thing, right? But it doesn't, as you can see here, it returns only the first promise. Why? Again, because of bigger evaluation. It is not lazy and it is not referential transparent, because when we refactor this function into something that should have had returned it the same, it didn't. So it loses the referential transparent that we think into functional programming, which is if I create a function that something shouldnt return a thing, but it doesn't, it returns another thing, which means that it's less referential transparent indifference with a task. So a task, as you can see here, we are doing exactly the same as the promise. We create a task here, we create the array of tasks we call it, and when we run it, it actually returns, run it one and two. That is referential transparency. Awesome. Okay, let's continue with short circuit. This is something that we have all the time in Javascript. So we create an EV that says x or x is equal to one or y is equal to two. So the short circuit is that if one fulfills the condition, it passes, it fulfills the other one, it passes. If it doesn't fulfill both conditions then it shorts circuits and it doesn't continue with the process. That is it. So let's see the difference on how promises and tasks handle this. First of all, let's check how the promise was defined. I have it here. What I'm doing here is just creating a simple promise that is going to delay the printing. And here what I am doing is a promise all which what is supposed to do is to receive all the promises into an array and solve them all. If they succeed, then we console, if they fail then we error. So here I have an arrive with many delayed promises and one that is going to be rejected. So what we might expect is that if one or two succeeded and this one shorts, it quotes, then this couple of promises shouldn't run. But let's check how it actually handles this. If I run the promise, as you can see, it shorts it quoted the one that failed, but it actually evaluated all the other ones that we had there. And yeah, that is because the promises actually doesn't have a way to run in a sequential form. Only if we run them with then. So we might have had to run it to wrote this with the delay, then another delay, then short seed quit and that would have stopped the performance. But let's see the difference with a task here is the same. I just created a delay task that is going to, let's see, I'm going to show the taskeither later, but what it's going to do here basically is to evaluate into something that is going to be print in certain amount of milliseconds, otherwise print errors. And here the same, I create the array of tasks because I can actually create array of tasks here. If I created the promises before, well they might have run it immediately. But here I can actually create this whatever I want into my code and then call it here. So when I click on the result, the pipe is going to receive the task array, which is the one that we have here. Then we can sequence it. Because remember, when we have tasks, we can actually compose the function before we actually run it. So I can sequence these tasks, then I can map them into console log. And if they fail, this is the either. If they fail, I can console log as anger. Okay, so let's see how it works. Run the task and it's evaluating the first one. And as you can see, once it evaluates in the second one, it immediately failed. And as you can see, the other ones were not run. So that's another cool difference that you can actually create a sequence, you can traverse, you can do anything you want, you can run in parallel with the task, which is really cool. Awesome. Let's continue with another feature that I think is one of the best. It is the errors handling here we are going to be using not only a task, but a taskeither. This is an algebraic data type. I'm not going to go that much into that, but adts are really awesome. I strongly suggest you to check them, but taskeither is one of them. Let's see why and how it works. As you can see here, we are using taskeither same library, fpts, and we are also using an taskeither let me explain a little bit about the taskeither. The taskeither in fpts is the way that we can handle the errors. It is a much more strict way of error handling. Also it's more explicit, more readable. And basically what it says is that it has a couple of possibilities. It can either be left, which is for failed operations, and it can be right, which is for the successful ones, and that's the way it can be handled. Also the types and stuff are really clear on how to use them. And another cool thing is that, well, I will show you this. Let me see if I can actually, let's run it here, actually console log what a response, this response is looking like into the browser. Let's see. So what I am defining here is just the user state, which has a type of either. So as you can see, either has the possibility for us to let the developer know what is going to be the error, what type is going to the error have, and what type is going to be successful. So the error is just going to be error. It can be an HTTP error, it can be any error that you define it. And here I'm defining that. I'm going to retrieve an array of GitHub repositories. So let's see if I can show you how it works. Here. It's an object. As you can see, the response is not what we might expect, like an empty are right immediately. What it does is to create this tag that says that it's right. If this left is going to be left, and then it has the value right. Now it has the value in the right. That is an empty Ari, which is the one that we defined it here for default. That is one of the main difference. So it actually obligates you to tell if the operation or whatever you are creating is either an error or a successful type and task. Either is the computations of the task, which is what we just checked before, and an either, which is what I'll explain it now. So task either is a promise that can actually fail and that you can handle the errors with either. Awesome. After that explanation, let's check a little bit on the difference of how promises actually handle the errors and how the task can handle it. Here we have a promise, as you can see, nothing new. We create a promise and that's it. But what happens if this fails? We can actually let it pass and do nothing, and we can actually omit completely the catch and that would make the program. Let's see how it works. If I run the program with failure, it actually runs here, the error, but it doesn't show anything to the user. Or I don't know, if you don't have an error boundary or something, it can make the application explode in the browser and stuff like that. Right? But we can also add a catch, which is a good practice for the promises. But let's see the difference here. If I write a catch here, let's see what type the errors gives me. You can see it's can any. So an error can be of any kind that you want. That is why when you control something into react or anything that you are building, you can do whatever you want with the error. But as you don't know what it is, what type it is, it can always be confusing for the developer either to handle it or to know what kind of error is actually getting for me to handle. Right? So that is also one of the disadvantages that the promises might have. But again, they are awesome and it could work for sure. But let's check the difference with a task, right? So here I am defining the same task, I am getting the something. Also really cool is that for example in the promise again, I actually have to define it like success promise, failed promise, run it all again. But for example, in the task I can actually define either successful or failed one and I can pass it here as a parameter, it's just a function into another function as a parameter, which is, as I told you before, a functional programming practice. Cool. So if I run the task here with a task, either just these ones that we created here, because this catch can either be an error on a response or a response, the same here, what is going to happen is that at first we are going to receive the request, then we are going to can, this is another kind of composition that we can do to chain different asynchronous operations here. So what I'm doing here is chaining and trying catch the resolution of the data, right? So if the request succeeded, then I'm going to go ahead and get the JSON, return the JSON to the developer to do whatever the developer wants to do, and otherwise I'm going to have to return an error, right? If I try to return like the typical, I don't know, console log something, this is immediately going to fail. Because we are defining that the task either has to be either an errors or a response. So we are forcing the developer to know that here we have to actually return that type of error. And the same, when we actually run the task and receive the data, we can actually handle it like that. Right? So let's see how it works. If I run the successful task, it actually run it like this, just normal. If I run the failure task, I present the error, right? So let's see how we presented the error here. Let me check. Here it is as we are defining the response, which is an taskeither, right. We actually don't have a way to say, I don't know, like map immediately into that taskeither. You know what I mean? Like for example, here in the success promise, we are going to be able to map immediately into the promise response map. And then we do it because the data is what we got and then we do things, right. But in the case of can taskeither, we can't map into can taskeither because can taskeither is either a left or a right. What we have to do is to fold it. To fold it means that we can actually control what happens when something turned it out to be an error and what happens when something turn it out to be successful. As you can see, there are a couple of arrow functions that I define here. So let me remove this. If I actually default, we're going to see the typed much clearer, clearer. So as you can see, we have the on left we're going to have an arrow function that receives an error and you can return a react node or whatever you want. And on the right we have that. We are getting a GitHub repo array and we have to return a react node or whatever you want to return there. Right? So this is something really cool that we can do with the ether and tasks either. And here as we actually are getting the GitHub repo now I can map what we might have to do with the promises is actually here in the catch, we might have wanted to set error to something. Sorry about that. To set the error to something, I don't know, like it failed and stuff like that. The same might happen in the case of the loading. In the case, if it's not initialized, we might have to set here all the user states to handle those possible cases. Instead, here we already have them thanks to the taskeither. Right. So that is something really cool that we can control and is also not useful. Not only useful, but also restricts the developer on how to handle things. Right. But as I said before, how do I show the clients that my request is in the pending state, in the loading state? That can be kind of tricky and it has many different or many challenges, not only in the promises, but also in the tasks. But I wanted to show you remote data, which is here as an alternative to use task eaters. Okay, so let's see how it works around here to remote data. And that's it. So this is a different library, remote data. TS is a library that is completely compatible with fpts. So we can continue to use that functional approach. And what it does is to have this remote data type which divides the request or whatever asynchronous operation that we are doing into four different types or states. The first one is initial, which means that it hasn't been called or anything. The second one is pending, which means that it's actually started, but it's loading. The other one is failure, which is failure, and success, which is success. Right. So this is really cool, because what we can actually do is not only set our response into a taskeither, but into a remote data. So response now is not can taskeither, that can be a left or a right, but is a remote data that can be in all of those states, right? So the first state or the default one shouldnt be initial because we haven't run the operation yet, right. So when we define the task, this is exactly the same. We define the task either that can be an error or a response. And here is where we can do like when it's initial. If it's not initial, then it can actually be in these different states. So we make the request and I am adding here like can artificial loading, just to show how it might load. The other one is a can that creates me the try catch to get the data as we did before. And the last one is a catch, which actually returns me. If it is an error, I can set the response to be remote data failure. And if it is a success, the response should be a success. Remote data, that's it. As you can see, we are piping this. Then we can call it, we'll run it here and that should be it. So it's awesome. So when we get the response, check it out how it looks in the code here. You remember that before the taskeither, we folded. We can do exactly the same here. Instead of folding the taskeither, we fold the remote data. So let me check how it looks. We try to fold here. As you can see, it says uninitial. What happens on pending, what happens on failure, on success. So it's exactly the same concept. On initial, I'm going to show can alert, that says not collect. On pending, I'm going to show the loading on errors. This on response this, and this is awesome because again we restrict the developer to handle all the cases and also it's a lot more specific for the user. Right? Check how it works here. I'm going to make my network connection a little bit slow to check how the pending works. And if I run, as you can see, it does not call it yet. Then it says loading takes a little bit and then we have the success, which is awesome. If we make it fail, I don't know. For example, let's try to call something that actually doesn't exist. We are going to get the invalid Json, which is exactly what we wanted, right? So that is something that I wanted to show, which is really code about remote data and how fpts and functional approach can help us not only to improve the promises, but also to get a lot more functionalities and possibilities to handle our code in a more functional way. Right? Finally, what I would like to show is something about another cool library that we have for functional programming, asynchronous operations, which is future, right? So to make it short, basically futures doesn't have taskeither or tasks or stuff like that, but it actually has futures. A future is what we can define as a lazy prompt in flutter, right? It has exactly the same advantages of a task either of functional programming. You can compose it, it's lazy and everything, but it also has can awesome feature, which is that it is also cancellable, which means that you can actually call a promise and cancel it, or unsubscribe or finish it whenever you need it. This is super useful for systems like react or view or something that is reactive. Because let's say that someone clicked into run this promise and then click it another place that doesn't need that promise. If we run it in the normal way, that promise will run until it finishes. But here we can actually cancel it when it's needed. So let's see how it works. First let's check a little bit in the code. So long story short, the same we define the future instance, which is this one. Here we create the future and the same as the task. Either it can be an error or a succeed. So here to make it sure, what I did is just to define a future instance that is going to return something if errors or string if succeeds. This is just the timeout that is going to wait 3 seconds and return that my future was fulfilled. And here is can awesome function, which is the one that allow us to cancel whatever we were running. So I just added here a console log and we clear the timeout. Right. This is what is going to be called when we unsubscribe this future instance. So how do we run a future? The only way to run it or to do it is like calling it. You remember in taskeither what we did was just call the computations of the pipe that we created. But here we have this function that receives a future. And if you can pipe it again into a fork, this fork is going to allow us to send the same data as the taskeither. What happens when something is unsuccessful and when something succeeded? Right. That is it. What I'm telling here is that the future I want to console log if it failed, and I want to set the answer into my user state here into whatever the future succeeded to. Okay. And the final function that I have here, this actually has nothing to do with the cancellation itself, just a button that helps me to call the cancel. But let's see, let's see what type this one returns, which is the fork. Right. It returns a cancel. So it means that by default whenever we call future, it returns me a cancel. A cancel is a function that calls the uncancelled callback or whatever you want to call it that is going to stop my prompts to be resolved. So what I did here is just to create another function that is going to be called by a button. If the cancel exists, then call the cancel. Oh, sorry. Then call the cancel function. The cancel function, as you can see what it is, is just this set cancel that I am using here. I am going to show you why this is because let's run it here to explain that if I run the future with this button, it is going to start and it's going to be fulfilling. So what this button did, let's check it out. If I run the future, it is actually going to set the cancel and run the future, which is this function that returns the cancel. Right. So what I'm doing here is actually creating or saving the cancel function that was returned from the future into this cancel user state, which is of typed cancel. That is why we have to do it like that. I know it can be a little confusing at first, but it's the only way that I can subscribe into that future and I can cancel it later. Right? So if I run the future again and I cancel it, it immediately gets canceled and it doesn't returns me the promise that I ran it. So this cancel basically does that just clear the timeouts or whatever catch that we might have done and that's it. So it's really useful for anything that you might want to cancel. Whenever the user is moving from one place to another, clicking one button and another one, it's really useful to have this cancel feature. Okay, awesome. And that was it. So I will also like to mention other topics that you can check. Effects is library. It's an open source library that allows you to build software in a purely functional manner. And it's awesome. It's sort of the competitor of future, but yeah, once you get the concept and the mindset of functional programming, it's going to be easier for you to use any of this. Also rxJs, which can also help you handle the premises in a more observable way and in a more reactive way. ADTs algebraic data typed are the basic concepts of functional programming, and it's going to help you understand a lot more how this whole thing works. Functional programming itself, there's a lot to learn there and you can always start checking things with fpts. I would recommend for the front end and you can always use it for backend applications with node, which is awesome for creating needleworks and validations. For example, you can create simple and easy validations with ioTs. Just going to help you have type safety and validations immediately. It's really cool. And besides that, just to jump into some conclusions, I can say that promises are great, but they can always be improved. Functionet programming is a mindset, a paradigm that can help you to have cleaner, more testable, more control, and more readable code over all your application. Please give it a try. I know that the learning curve can be a little bit high, but it's worth it. It's worth it to have different approaches on how you can write your applications. Besides that, use these libraries with caution because as everything you can start implementing them without the good practices or making them an overhead can overkill into your application. So please use them with caution. Try not to overload everything into one application. Just decide what is better to your needs. Also, something that I found with these libraries is that documentation can be a little bit hard and sometimes a little bit to understand and to find in some cases. But the good part is that they are all really well typed and it helps you a lot when coding because the types can self explain the functions and how they work by themselves. So when you style the application, I'm sorry, when you install the library, you're going to have the help of the types and also some inside documentation that you have there. But it's always better to have first a clear idea of what functional programming is the basics and then start using them. And last but not least, enjoy programming. And thank you very much for watching this talk.
...

Naty Rocha

Software Developer @ Stack Builders

Naty Rocha's LinkedIn account



Awesome tech events for

Priority access to all content

Video hallway track

Community chat

Exclusive promotions and giveaways