 My name is Maxim, which you probably can't call my surname, but I'll keep it short. So, I'm here to talk about run-to-jazz. Has anyone used run-to-jazz? Good. I won't be immersed with this stuff. Okay, so, it is about me. I work for Play-to-Leave. We do, like, an audience engagement, making it fun for you to feel servicing with us and get your orders for that. And I'm here as part of JFDI, which is that lovely program. That's an Xerida program, and we're here for three months and then going back to Australia. So, if you want to follow my web source, you can find me on Twitter, which you probably can't get this properly at Australia. So, I'll say this one, I'm not. I'm not a functional programmer. Those people are way smarter than me. I hate math. I have, like, seed math. All the journey from university seems cool. And I'm neither the expert in run-to-jazz. So, while sitting in the context, that's pretty much how it looks when I discover Ramda. I have heard some of you what I'm doing, and the reason I'm giving this talk is because I wanted to know more about Ramda. So, it kind of forces you to learn about stuff you've been talking about, so you can prevent, you know, something. So, like, when you look at Ramda Enterprises, the first question you might ask, like, what the heck is the difference? It looks very similar to underscore low-dash, and for those people who didn't use underscore, that's how it looks like. So, if you have a set of tasks and you want to filter the tasks which are not complete, you just use this function and you pass it the list of tasks and you pass it the filter to apply. So, that's how underscore low-dash does this, and that's how Ramda does it. So, at this point, you probably will be like, huh? Like, they're just introducing a new interface for you for no reason, and that's where the functional programmers or people would probably go into theory about the functional composition and query and explain all the stuff for you, which I can't because I have no idea what I'm talking about. So, in GTI, we just do it. Hopefully, I'm not going to end up like this, but yeah, we'll see. Okay, so, basically, there's two simple concepts which Ramda relies on and what Ramda brings for you. The first concept is called curing, and it has nothing to do with the nice and tasty curing. It has to do with the fact that you can have a function. So, you can have a function. So, is it clear? Oh, why is it all shifted in the wrong direction? So, can anyone see it, okay? Everyone can see it, okay? It's just left-adjusted. Okay, anyway, so I'll try to keep it right-adjusted. So, if you have a function which accepts x and y, so I have a function there and accepts x and y, and then this function returns to x plus y. And that's ES6 syntax. So, if someone's computed by this, then it's the same as old JavaScript, this crap, return x plus y. That's the old way, basically, I'm just passing it to branches and we can do it together. So, if you want to use this function somewhere, you just call A1 plus 2, and that should be equal 3, right? And if I did not... Screw them, think that would work. Yeah, okay, so... So, this is no JS, right? Yeah, this is no JS, there will be no Meteor bar here. Okay, so, what curing allows us to do is if we just apply this function, curing, and this is not actually underscore, as you can see, I'm pretending here that it's underscore, so that it's kind of easier to read. So, if we apply curing on this and then I save it, it's actually going to be exactly the same result, but what curing allows us to do is pass not all parameters at the same time. So, we can say with a function which adds 1, and then this function is not executed at this stage. Then we can say we want to add 1 to 2, and we're going to get the same result as 3. So, if it works correctly, yep. You might be wondering, like, why the hell is it useful? Why do I want to pass multiple parameters, not every parameter at the same time? The reason is that it gives you a regular build of your functions. So, if you have a simple way to add 1, so you don't write everywhere plus 1, you don't do 1 plus 2, you don't do 2 plus 3, you define a higher level of abstraction for this, which allows you to speak in your specific domain language. Is anyone lost at this moment? And I know there's probably an audience which is not going to tell me about this, so I'm going to be like 1 first comment. So, is there anything confusing at this stage? Oh, yes. Can you get to the last one here? Okay, so... Now that you've got a function. Yes. So, you don't have a function which accepts 2 parameters. Usually, when you call this function, you need to pass all parameters. You need to pass 1 and 2, right? While here, what you can do with the current, you call it one argument, and you didn't pass the second argument yet, you're passing it way later, which means you're creating a language for your system, which defines in your terms, in terms of your specific domain. So, like, add 1 is probably a very weird example, but if we do something like, imagine you have a game and you have a way to increase the level of the user. If you do something like this, you do, like, increase level, and then you just say the increase level of the user level, which might be in completely separate parts of your code. It's not necessary we need to be in the same place. So, you pass this as a function which increases the level somewhere else, and then you don't worry about how many, how do you increase the level itself. Did I just confuse everyone completely? So, the main thing is for code rigability to be really easy, because the name of the function is smaller than the final domain, is anything? Yes, yeah. So, if you're not speaking in primitives like plus, minus, multiply, you're speaking in the higher language, which allows you to reason about your program easier. Okay? I think the plus one example is, you should use a different one, because it's such an acronym, right, it's already existing there. So, as I said, maybe you could use something to the power of, and whatever more complicated, not normal. Yeah, so you can have a function. And then it's more clear why. Yeah, yeah, okay. Time 3 plus 1 minus. Yeah, exactly. Whatever complicated formula there is in here. Yes, so I didn't want to introduce the composition, that's why I did it simply, but let's say it's a power, actually, that is a good idea. If only I know how to do it. As I said, I'm horrible at math, so. So, that's multiplication, right? The power would be, we'll just multiply this gazillion times. So, I'll do something stupid and I'll just do x by x. How do you power again? x by x is pretty good, I must say. But that would be limited to specific. That's great. But the hat, right? Yeah. With the hat? With the hat. Okay. So, yeah, I have no idea what I'm doing. Okay, let's pretend this is a power function. So, they don't have a double function, which then just takes the power of 2. The tricky thing is we need to flip them. And the reason is we're only passing 1. So, you're passing the thing that changes as last value, because then you can compose. That's what I'm already saying. So, since the x is the value that we're making, that we put a person called, that we're powering. So, instead of doing this, we'll just flip those around. This function will pretty much double it. And instead of using power 2, you just say, okay, I want to see what's double or 3 is going to look like. And if I did it correctly, it's going to give me 9. And I didn't do it correctly. And the character is a big wise soul. Yeah, I think. Don't trust me in the power thing. I think there's this function. Yeah, that's the one. So, actually what I can do is I can just return this and then flip the arguments. That's going to be the last one. But it's going to work. So, once you've flipped us, it's the same thing that I did just now. It switches the arguments so that you can pass the argument which changes as the last argument. Okay, does it make more sense now or still can't do this? So, you can have... So, if you give 3 in power, should it equal to 27? Yes. So, that probably won't be called double anymore, right? No, it's triple. Oh, whatever. But that would be 27. Q here. Double Q, whatever. Yeah, no, that's not Q. Okay, whatever. I always didn't know how to type Q yet. Okay, here you go. Make sense? Who got this now? No one got it. Okay, cool. Okay, so, that's basically the whole... The biggest difference between RAMDA and low-dash and underscore is that all the RAMDA functions, they all carry the commit screen, which means they don't force you to pass the arguments to them. And if we go back to the slides, now you might be able to spot the difference. See, in underscore, we need to pass the tasks here. In RAMDA, there's no data. There's no data at all. And the data might be passed like hundreds of lines later. Your behavior is completely separated from the data you pass, which makes it way easier to reason about the state, the behavior of the system, because it's not coupled with the state. What happens when this changes this variable and it happens when it changes this variable? We have input coming in, output coming out. Simple as that. And behavior in the middle. Okay, so, with the covering, kind of explain maybe someone get it. I'll quickly go through the functional composition thing. So, basically, we have this flip thing. The math modeling. I'll just copy it and put it into the library again. What RAMDA and underscore allows you to do because they don't have covering, it doesn't really work. What they allow me to do is I have a compose, which is more math like. Basically, if you want to take an array and you want to make it to cope all the values in the array. So, if you write it in a normal JavaScript, you do something like this. For I, I'm a little less than length of array, I guess. And then you do I plus plus, and then you do all this funny stuff. There is one rule three. If you want to do this the classic way without using underscore one, right? You would go and say, I'm all free, which one which I think like that. And power three. So, that's your classic approach. And one of this approach is that it's very fast. But it's very hard to read. Because you have this board here and you have this stuff. And you're actually changing the state at the same time. So, you can't easily say what's happening here when I go and mutate this array somewhere outside of this function. What is that? You just create a path of array. So, you take an array and you map it with the cube at the same way that underscore does it. But passing this argument. So, I'm going to pass this argument now, but I'm going to show you the second way we're going to do it. So, if I do the thing correctly, then we will have one, six, and nine, I guess. Eight. Oh, yeah. One, two, three, seven, eight. Twenty-seven. Hey. We're in some place. Someone is still following this. Okay, so if I did not... Oh, I did. Because I had the other version, so I actually... I cooked it twice, yeah. Okay, here we go. So, hopefully, one, eight, twenty-seven. Oh, yeah. It's stupid. Mocha is the best framework used here, and you can't use equal arrays. I don't know why. It's a lot of things. So, that's a lot of stuff to map easily, right? So, let's say now that we have four and five, I will just make it slightly complicated. So, I thought if I say this is going to not work anymore... Sixty-four. No, no, no, no. I don't know this one, yes. What I want to show you is that, instead of doing this here, I'm going to extract this so that you can still see it. Let's call it something like transform, I can spell it, obviously. You can actually do multiple things on it, and what I'm going to do is, before I'm going to map it, I'm going to filter it. So, instead of placing an array, I'm not going to pass an array, I'm just going to say, I want to filter this, and I want to remove everything, which is over four. And, I don't know, this is my logic, it's like this. So, I'm just going to create a function, which it says is under four. I doubt I can use. And this function accepts an element, and it just returns to you, is the element is less than four. It's simple as that. So, the filter function then, is just have this under four. And again, I don't execute this function in this one. And I don't actually pass. This is just the behavior. There's no description here of what the data is. Oops. Now it's just a weird error thing. So, to actually make it call, I need to pass an array here. So, what I did now is, I essentially, without changing anything here, I made my function behave completely differently. And, you can go on, and you can say, you want to group it first, or maybe you want to then double it for whatever reason. And, we can compose behaviors like this. And, I didn't define double, so that's not gonna work. Let's quickly find double thing. So, this will quadruple, to group it, and then double it. And it looks right, I think. The numbers are getting too high, so I can't tell. The reason why you would do this, is because those functions, they actually have a math theory behind them. And the math theory tells some interesting stuff, like, instead of it rating on the array twice, which you often do, you can actually say that, I want to cube it, and then I want to double it with the composition inside. So, that's probably why most people would be like, what the fuck is happening? So, how many people could compute now? Okay, I'm gonna raise my hand. Yeah, it's getting a bit, a bit harder to read, but I would usually start separating this into, I'm not sure what to call this, double cubed? Yeah, like, it's still working, but I obviously didn't fix my tests. Let's double this, what? 64 and 29. Okay, the reason why you do this, is you can start creating those functions. So, they have this double cube function, imagine it's function in your domain. For example, you need to double-cube your values every time the user gives you something, you need to double-cube it, and then pass it to that base. Instead of writing this code, we're like, okay, so we have this value here, and then we need to say value, what math, how, value by three, and then we'll multiply by two. That's one double limit, but we need to power up again, let's see. Oh, again, so that's the equivalent of this code. So, which one behind you find easier to read? This, or this? It's very quiet, so I... I think so first. It's really... It's more... Can you tell me what this function does within 10 seconds? Oh, wait, I'm going to remove the comments, so that I'm going to not make it easy for you. Okay, now tell me what the function does. So, first part was the... Can you quickly... guess? It's not the admin user, man. Yeah, see, you're reading the whole thing, you're reading, if it's not admin user, then what? Show them something like... Trust that the user is not an admin, and if it's not an admin, don't show him the mediator that only an admin is supposed to see. Okay. What about this one? Because it's self-managed, isn't it? Yes. So you're basically only showing the menu items that that person can... is allowed to see because of his level, right? Uh-huh. Now, see, see that's when it becomes... See, like when you try to read something like this, you need to read this part, you need to read all this fluff around it, and that's the actual... this is the only tool, which measures when it's wrong. It's this... if level is zero, then we return the items which doesn't have a parent, and if level is not zero, we return the items which matches the parent. Okay. So, what I just said in English, can be also expressed... I'm just going to cheat this right all the time. Can be also expressed in my cheaty version, which I didn't finish. Uh... So, in learning the partial thing, that's just me not understanding how to use grammar properly, we're checking that the level is zero, but that's what I just said in English, and then we return items without parent, or return items for specific parent. That's what the logic was. But, to tell this from here, you need those things. You need these sneaky comments, so that explain, okay, this is what we do, this is what we do here, this is what we do here, and this is what we do here. So, the code is kind of self-documenting. It's just raising the abstraction level of what you're working on. You're not working on the primitive, I need to do the four thing here, and I need to do plus one here. You're working in the other main language. For example, see I held this at child level, and I don't look at what this thing does. What I care is, when I combine all this together, what I do is I... I don't compose it a bit weird. It's a math function, so it does everything in the opposite way. So, you read from right to left, not from left to right. This is the equivalent, basically, of a filter of at child level, then you pass the conditions, then you pass the items, which you can pass here, and then you... The items will be filtered by parent, and then you pass the conditions, and you pass the items, and then you pass the items, and then you pass this, and then you pass the items here. So, that's the equivalent of this line. If you want to write the definition, I think I just know that I'm on the train, right? So, my point was that by basic level of abstraction here, you don't need to go down and see, oh, does this thing, that's condition plus one. Whenever you need to add a child level to your menu item, or your menu, and the project this code is based on is actually a telescope. If you go to the telescope, there's so much duplicate code they do of, like, whatever the menu you need to add a child level, which is going to do plus one. So, if you do plus one, you're using a function, which then allows you to change the behavior. If you need to now say that child level is not just plus one, it's plus 10, you just go to one place, you change one function, that's it. Okay, so, I think it's, yes, I'm kind of on time, but not really. If you are, and you want to read people who actually understand the shit, not me, then there's this guy, which is free. So, you just click this link and I'll post the slides. That is very, very easy read. This guy is like, you don't have funny pictures. And he explains the basics and the very advanced part of functional programming in JavaScript. Then there's Scott Sarris, who created Run The Jazz. And you can find his talks here. There's a bunch of them on the composition, functional programming. Way more theory than I can ever imagine. Yes, he goes into all this how he does it properly. And then if you want to see the demo for the person who knows who they're talking about, and that I found unfortunately yesterday at night. So, I wish I had it before. That's a guy who tried to say think, but way better than me. So, if you, if I got any of your interest or you like World Pocket with functional programming thing and you want to read more, here's what I read and I, I think I tried to understand something, but I'm still kind of floating in every direction. Any questions? I also feel people are just like what the fuck is going on? So, are you using this now in your applications? Yes. You refactoring all the code or? No, we started using it from the beginning, because I started the application so you can pull in the underscore or you can pull around there instead of underscore. And I pulled around there but I wasn't sure what I can do. And, yeah. So, that kind of forced me into learning it more but I think I'm still like halfway there in understanding the basics of it. I think the issue is that I think in this way versus the loop, you would be there for the cost which is never too far. Never too far? When you change the command itself, the cost example gets very large. Even the performance? Yeah. That is true. Functional after functional? Yeah. Functional programming is genuinely slow but because... I'm actually using the language that is in my story. No, like JavaScript is... Like if you think about JavaScript, it's not an object-oriented language. It doesn't have classes. We're trying to do object-oriented in JavaScript but it's not what language was designed for. It was never designed to be in it. And we are trying to piggyback it on top of it. The performance benefits of writing in cursive style where just like it's already manually is definitely there. The problem is when you have state, you can't do parallel easily. As soon as we can do parallel which hopefully is going to be when web workers are going to be implemented. So in a year, hopefully, we can use threads in our browser. Kind of threads means you can do parallel programming in JavaScript. And then when the license state is going to make it very, very difficult because you need to release lots everywhere and all this fun of functional programming in this state. Oh, sorry, object-oriented programming in state. In reality, I didn't notice any performance degradation. It's so tiny that you just like out of whatever. And more functions, yeah. It's way faster if you write everything in one method, right? So if you don't have any functions, any classes, write everything in one-gen method. It's going to be super fast. But good luck maintaining this because it's very hard to understand the code which is just mingled in a month. And how do you use it in the same way? How do you replace that as well? Why do you write it? Ah, yeah. So that's a good question. So when I was refactoring this, I kind of... This is the notion of pure functions in functional programming which are basically functions with no side effects. So you pass an input in a function and you get an output exactly the same input passing. You get exactly the same output every time. There's no difference. There's no... If meteor user then will do something different. So to avoid this part, I just separate all this crap into a dark space. And I call this dysfunction I don't test. So I just combine all the stuff that I need including this meteor part and I call this thing. And this thing can be tested without any life meteor. This is... I took this code from meteor from a telescope and I made this function completely irrelevant with code. To meteor. And if you need to pass items here as a meteor collection, I keep it there. You just do this. You just do meteor... I don't know, events to find or fetch. So you chuck all the parts which can change into one place. Because you don't want to... Testing this is really hard. You need to create more events. You need to create this fake user. You need to make sure how this function works on this crap. Testing the function which doesn't actually have anything to do with meteor. Just play in JavaScript. It's logic. And underscore... It's under the score of meteorite. So you do it based on the score. Yeah, underscore is round up still. Oh, you can see that. Or it's up there. Let me see. So it's... Yes, yes. It's not underscore. It's round up. This is our meteorite outside. Yeah, it works the same way in browser. Moreover, because your functions are pure, you can actually serialize this function and you can pass it over the wire to anywhere. Server, server side? Say I should... do this. Well, it's just JavaScript. There's no reliance on meteor. Meteor becomes part of your input. So all the meteor parts, you chuck them into the input and everything else inside is pure JavaScript. So if you need to call to meteor, for example, you want to call NAPI at some point in your logic, this is just a function that you pass into your logic function, like this pure function. Maybe... Yes. Okay, so... Also a quick question. Yeah. Just one point, I think. They need a function of paradigm. They have advantages in terms of performance. So if you talk about underscore, they can actually optimize your... So let's talk about the iterator function, your follow-ups. They can actually optimize your follow-up function because they assume that your function is of a certain type and if it's of a certain type, you can do some pre-optimization. Therefore, your compiler can run it faster. So it's actually faster than native code. That's the... I don't know. But it's just over the... That depends on what function it passes here. It's just a little bit functional, like we just have a few more functions. And we just have to do the construct language. But the cost is tiny. You won't notice that. You need to process the casinian of the iterator and display it. They have the cost of optimization which they convert... a set of calls into loops instead of... They'll call off the mic. Yeah, they'll call off the mic. I just want to point out that there is actually some advantage because the library might optimize your code for you. I just wanted to ask... So if you compare this with, say, underscore on those dashes. Which one is faster? What was the optimization program? I think low dash is faster. There are some benchmarks who say that the low dash is actually faster but I haven't tried it myself. But I've seen people doing it and they say it's faster. So if you consider this performance not through the built-in or modular built-in or reusable to-do code, that means you go low dash. But you need to process a lot of data to see the difference.