 So, first thing I want to know before I get started, the link down there at the bottom, all the slides are up and available. That mirror screen thing is going to drive me nuts, I'm going to leave it though. If you can't see, like if you're in the back there, there's stuff hanging down. I ascribe to the top two-thirds kind of slide configuration, so if you can't see something, definitely go to the link. Yes. There, that's good. Can everybody see me okay? Okay, great. So, assuming this will work, which it doesn't, not surprising to me. Okay, that makes it much easier. Very funny. All right, so that's me. You can find me on Twitter. That's my blog. Lots of nerdy stuff, math, many other things. That's my GitHub account. Many nerdy projects also. There's, at the end of this, there's a reference to it, but there's work that follows this bits and pieces of math with actual concrete stuff. And there's plenty of concrete stuff in the presentation as well. So first thing, I work full-time on jQuery Mobile at Adobe. I'm extremely lucky to have that job. And I'm very grateful that Adobe funds me to do that. We are hiring, so if you are a Rubyist and you don't have a job, you're doing something wrong. But if you don't have a job and you'd like one, there's great jobs at Adobe doing Ruby, Creative Cloud and some other things, some smart people there, and Typekit, actually. Anybody heard of Typekit? Right. So they got acquired and they're hiring. So if you're interested, the link's at the bottom. All right, so I feel like this definitely needs a little bit of motivation. Generally speaking, when you go to a JavaScript conference, you're not expecting to hear about math. And that's fine. I wouldn't either. And so let's talk a little bit about why I did this. So first and foremost, I don't really like using the laser pointer, but I'm going to call out the mullet. I really appreciate that. Math is pretty awesome. And I have kind of a tumultuous relationship with it. I didn't really like math until a couple of years ago when I kind of gave it a second chance. So I think my story is a common one. Lots of people go to high school and college and learn calculus. It's, they do a poor job of relating it to the real world. Me and a lot of my friends think that calculus should be a part of, like, a physics curriculum. Long story. But the point is, is that calculus can sour people on math, and math is so much more than calculus. There's, I mean, we live with math every day. The computers that you're using right now, the phones that you use, the modern conveniences we enjoy are almost all entirely due to math. So that's amazing. There are domains to math that cover incredibly diverse set of topics. So operational semantics, logic, category theory, you know, vector math, all these crazy amazing things that are not calculus and are not quite so annoying and abstract, and they're very concrete. So we're going to see a little bit of that today, hopefully. Hopefully I will de-sour you on mathematics if you don't like it now. JQuery. So it's JQuery, obviously, this doesn't really need saying here, but it's very popular. Something like 50% of the top 10,000 websites is ranked by Alexa for whatever that's worth to you, use JQuery. So if we can get something out of this, if there's something concrete on the other end of this presentation that we can get out of it that improves JQuery broadly, we're making a big impact. So that's a motivating factor. Speed. So speed is nice. People like talking about speed. Nobody loves performance presentation. And one thing I'd like to note is that's a tachometer, a tachometer, that does not give you any information about how fast you're going. But it looks nice on the slide, so. Okay, so let's talk a little bit more about the problem that we're solving, this method chain thing. So this is a very common idiom in JQuery. So you might characterize it as the foundational idiom in JQuery, methods that you chain. It's simple, you understand what's going on, it's almost literate. But specifically what happens under each of these is not always obvious. If you've been using JQuery long enough, you already know what's happening in the background. So let's look at the kind of a naive underlying implementation of each of these. So hide. So hide might look a little something like this. The two things to note here most importantly is that it's a big loop over all the elements that have been selected from the DOM, so divs here. So all the divs in the DOM are being looped over and this, the key bit here is that the underlying DOM element is being manipulated, so the attribute is being set again. This is hyper naive, but this is hiding the stuff that we've selected. Second add class, again, another loop. It also alters all the DOM elements in the set. Same thing, big loop, DOM alterations. Show, again, very simple. Big loop, DOM element alterations, very similar to hide. So what we've got is this big set of loops. And I think generally speaking when you start programming, if you have a CS degree, someone along the way has said, it's good to do less loops. When you start learning about big O notation, obviously this is upper bounded by N, it doesn't really matter. There's three loops. The upper bound is still N, big O N, but it's one loop is better than three loops in a lot of cases. It's sort of something you might, it's sort of semi-intuitive at the very least. So what you might want to do, you might do, if you wanted to have less loops, you might squish everything, so squish everything down into this kind of single loop. So if you took all those three methods and you kind of toss them together, this is what you'd get on the other end. This has two problems. So one of them, obviously, is that these are very naive, they're very simple, but more complex than the actual implementations are much more complex than this, and it's not always clear how they should be squished together properly, right? I mean, even if you put them together just one on top of the other in the same loop, there could be conflicts, variable shadowing, all kinds of stuff. And the second problem is that you have to copy and paste. So we all know that copying and pasting is error prone, just even the very act of it, you can lose things, leave it behind that are very critical to the functionality. So this clearly will not work. If we are interested in reducing the number of loops, the number of ends, these are two problems that we have to solve. So an important note here is that it's not always obvious that less loops is better. And in some cases, it's not. But so I've done a little work on this, obviously. For some very simple examples, in this case, remove attribute, which the reason I chose it is because these squishable stuff inside of remove attribute is available on the dollar function. So it's easy to squish. There's no copying and pasting, so I chose this way. And what you get at the top blue bars and all those tests and the different browsers is the squished version versus the bottom red bar, which is just the chained version, the normal version. So it amounts to about a 5% to 10% performance improvement. I mean, this isn't going to change your life right now, clearly. But there is a performance improvement to be had. So it's good. It's well founded for certain sets of functions. Additionally, I pulled this one out of jQuery mobile. We have this enhanceable helper that's very similar in that it exposes the underlying squishable functionality. And again, pretty good performance improvement. Worth noting, in Safari, for some reason I am not clear on, it's not an obvious win. So it's within the plus or minus the kind of error bar there. But it's worth investigating. So the point being is that if you're not happy or comfortable just assuming that less loops is better, in most cases, well, not in most cases. In some cases, even in the cases where there are few loops to squish, it still has value in terms of performance. OK, so category theory. Let's get into this. And this is what I'm going to cover today. If I can get through my slides, I think I have 130 slides. So I've got to move quick. The things I'm going to cover today are, one, what a category is. Two, I'm going to build two categories so that you get an example and using things that you're used to, so DOM elements, JavaScript functions. And then last, I'm going to give you what's known as a functor. And don't run for the door because you heard the word functor. It's not that scary. OK, so just to start off, I'm going to get a little context in here. It's helpful to understand where category theory came from. So these two guys, Eilenberg and McLean, were sitting around working on some crazy math stuff, algebra, algebras. And what they were seeing was that there was this common activities, this common stuff in between all the algebras that they were working with. And just like any good programmer would, when you have commonality, you want to dry things up, you pull it out, you abstract it. So what they did was they saw all these similar behaviors and they wanted to abstract that stuff out. And so what that eventually became, obviously, didn't instantaneously become category theory. Over time, became category theory. And very specifically, some of the stuff we'll talk about today. So what specifically is a category theory? In mathematics, when you say this thing is a category, what do you have? So first and foremost, and I do have math notation in my slides. Again, don't run for the door. The thing on the left there is just a way to say the objects of a category. So an object or a category more specifically has two things. It has objects and it has what are called morphisms. And morphisms, it sounds like a scary word, but it's not all explained in a second. The objects are just things, so very abstractly things. So if you're talking about JavaScript in terms of a category, you would say JavaScript objects. So stuff you might be familiar with. And this complied a lot of stuff. For example, hask is a category if you've heard of Haskell. And the objects in hask are Haskell types. So it's just things, concretely things, or not so concretely things. The second piece is morphisms. So morphisms are just mappings. They're actions or things. So it's kind of a nouns and verbs type of relationship. And these are the two sort of concrete pieces of a category. Now there are two laws, the first of which, two laws that a category must satisfy to be a category. The first is identity. And the notation is actually pretty intuitive. So ID, identity, takes some object and gives it back. That's all it does. It's very simple. And it's not very obvious why that's necessary, but in a lot of mathematics, and my understanding of this is that in a lot of mathematics, it's just simpler to have something to put together with other things in terms of notation, in terms of simplicity, in terms of readability. So it's there for to shim stuff as necessary. So the category has to provide some sort of identity morphisms, some sort of identity action that just takes an object and then just gives it right back. In JavaScript, this is exceptionally simple. It just takes some A and returns the A. So not so hard to get. Composition, so the other thing that a category has to provide is composition. Now, many of you may have heard the term composition in terms of functional programming, and that is very similar to what we're talking about here. So in the notation, there are two functions, G, two example functions, possible functions, G and F. G takes an A, gives you back a B. F takes a B, gives you back a C. If you glue those two things together, and you can think of that little circle notation down there on the bottom is glue, if you glue them together, you get something that takes an A and gives you a C. Pretty simple. So that's composition, very abstractly, and four categories. For much more concretely, for JavaScript, you can build this yourself. It's very simple, like if you've used underscore, they have a compose function. Just takes two functions and returns a new function that takes one argument, hands it off to G, let's G operate on it, G hands off some result to F, and then the whole result is returned. So that's all that composition really does. It just glues two things together. It sort of chains them together in a nice, and in a single package. So the function that's returned is that package, that chain. So let's talk about our first category. The notation here, the four letters in the init cap is convention from the mathematics. So the second category will look a little bit odd, but that's why that's named that way. So let's talk about this category, HTML. So first thing we gotta do is we gotta define our objects, right? We said we'd have two concrete things. We have objects and morphisms. So first thing we gotta do is come up with objects. This is very simple. The objects in HTML are just DOM elements. So what you're familiar with, the stuff that's underneath jQuery, if you don't actually manipulate the DOM directly in your day to day, but DOM elements that you would get from JavaScript API. What are the morphisms? What are the things? What are the actions in this category? They're just functions that take DOM elements and return DOM elements. So they might manipulate them. In this case, this would be identity. But the key is that they can only take DOM elements and they can only return DOM elements. You can't take a DOM element and return an integer. The constraint that we're placing on here, placing on them verbally, because obviously JavaScript doesn't have a type system, is that they take DOM element and return it. So that's kind of on you if you wanna participate in the category. An example would be sort of from earlier, if you wanted to set the class to foo, would you take a DOM element, alter it, and then return it? Identity. So we need to define this behavior. We need to satisfy this law for the category. And again, it's very, very simple, just what we saw earlier in our example. The only difference is that it takes an HTML element. Composition. Again, the exact same thing that we saw earlier because it's just a DOM element, it's composed and instead of just some random thing, integer, whatever, you have to take a DOM element. That's the stipulation here. Okay, so we've defined our first category. Again, the thing I wanna go over here is that the reason why it seems so simple is because it is that simple. There's not a whole lot of complexity to these ideas, and it is in a lot of ways what gives it its power, because it's so abstract and sort of basic. Again, the common elements of some very already abstract things, you get that commonality between lots of stuff. So why category theory applies to JavaScript as well as Haskell as well as physics and some other crazy things. Anyway, if you feel a little bit confused by why it's so simple and why you thought it would be so complex, that's fine, it's supposed to be simple. So again, naming init cap, generally category names are four letters or less. So we're gonna name this category jQuery in short. The objects of jQuery. So what are the objects of jQuery? Well, they're jQuery objects. And to be clear, I don't mean, a lot of times there's this confusion between when you say jQuery objects between the dollar function and the results of like a selector, right? What I mean is the results of getting dom elements out of your document. Okay, so in this case, some element with the ID sample. So those are the objects of jQuery. What are the morphisms? Well, just as you'd expect, things that alter jQuery objects, the stuff you're used to using every day. And you can start to see where this is gonna tie in. Maybe you're starting to feel where it's tying into our original problem. Okay, so we've got those two laws. And now these get a little bit more complex. So this requires some knowledge of how jQuery methods, the methods you use every day hide show ad class that we showed earlier, work. Specifically, when you define a method on jQuery.fn, the context is available to you as the jQuery object will be available to you as a context, as this, when it's invoked on a jQuery object. So this thing becomes our first argument in identity. And since we don't, in identity, all we do is return the thing that we've been given. We just return it here. So this is exceptionally simple. As an example, if you did this, if you invoked this new thing that we just created, it would just give you back that same jQuery object. It wouldn't do anything else. Okay, so identity. Composition, this one's super fun. So again, we have two functions or two methods, jQuery methods specifically. We wanna run these things together. But remember, we said that it's not coming in as an argument. It's that this, we need this, we need the context. So this is our object that we're gonna be operating on. And we're gonna use apply to pipe the context into these jQuery methods that we wanna chain together. So instead of doing chaining like dot method chaining, here we're kind of doing it for you. And that will be our composition for this category. So again, g gets to manipulate this and we'll return this because we all know that all good jQuery methods return the jQuery object they're operating on. And then f gets to go. And then the whole thing gets returned. So let's take a quick, let's take a quick look at what an example this is so that it's totally clear. We got two jQuery methods that we're defining and ostensibly they alter the context, the jQuery object and then they return it. Using our new compose function, we smash those two things together and we have to define it on a jQuery object obviously. And then what ends up happening is that these two things become functionally equivalent. The chain that you would otherwise use is now just one thing. Now there's not a whole lot of value in this. Again, I'm sort of setting the stage for the real value but we're defining our categories here. We're trying to adhere to the laws we've been given in category theory. So that's composition. All right, the last piece of category theory is the functor. And if you've been, if you're out there and your eyes have glazed over and you've sort of given up, you can tune back in here and you'll get almost all of it. So this is the important stuff, just pay attention for this. So a functor is a purely category theoretic construct. So we want it, it is a mapping between categories. So if you have objects in one category and you want to get it into the other category for whatever reason, because there are operations, there are interesting things going on in that category, you need a functor. You need to get between the categories with a functor. So it's a mapping. We need three things. The first equation is something that will map the object. So we need some way to get the objects from one category, in this case HTML, into another category, jQuery. I'm going to go back to this. So to be totally clear, we are mapping from HTML to jQuery, not the other way around. So that's our functor. It's a one-way thing. It doesn't go both directions. The second thing you need is something that takes the functions, the morphisms, the stuff, the actions, and also maps those across. So it takes them from HTML and gets them into jQuery. And last, there are more laws, but again, I only have so much time. The law that you have to adhere to, this is called preservation of composition. And we'll get into the specifics of this. Don't worry about the equation. We'll cover it. These are the three things that we need to get a functor together so that it adheres to the laws. And it will act as a functor in a properly defined category theoretic functor. So first, let's take a look at getting those objects from HTML to jQuery. This is very simple, right? So many people don't know this. And this audience might be better informed. But taking a DOM element and just wrapping it with the jQuery function. We'll give you back a jQuery object with a DOM element in it, as though you had selected it from the DOM specifically. So that's the first part. So we've taken a DOM element, which was in our category HTML. And we've sort of transported it quite easily into our category jQuery. And that's the result. We get a jQuery object back. Next, we have to deal with the morphisms. So we have to take these kind of pure, simple JavaScript functions that alter DOM elements. We have to get them into jQuery. We have to get it so that jQuery can use them to manipulate that set of things. And this bears an example. So the first thing I'm going to show you is set foo. So this is that very simple function that I showed earlier. It does something very simple. It just changes the class and changes it to foo. So normally, when you're just in HTML, so when you're just living in that one category, that first category, you're just going to use it like a regular JavaScript function. You're just going to invoke it, right? But what we really want is we want to use it like a jQuery method, because these are the morphisms of jQuery. So we need to take that first thing and turn it into the second thing. So how do we do that? So I'm sure some of you have already figured this out. But you can quite easily do that using map. So if we defined our set foo jQuery method and we started working on it, we started working on the jQuery object, and we said, OK, how do we take set foo and start pumping HTML elements in there? Well, the obvious thing to do is to map it over it. Map each similarly, give you all the HTML elements. It loops over the entire thing, just as we showed earlier. The use of map is very specific, though, because map requires that you return the element again. So it's a little bit more rigorous. And it also means that set foo can be the HTML morphism that we saw earlier. It can be that DOM element altering function. If we took that return statement out, it wouldn't really fit with our category that we defined earlier. So map is actually the way to do it in terms of category theory. So map. Map is our second piece. So we've got both of these. We've defined both of these. OK, we've got our objects, and we do that with a jQuery object. And we've got our morphisms, and we do that with map. So we've got the two pieces that we need. Now we just need to take care of that law. So this equation is actually pretty simple. What it says is that when you compose the, in our case, jQuery morphisms, it should be the same thing as composing the HTML morphisms and then using them with jQuery. OK, and I have an example. Don't worry, I know that sounds complex. So let's go back to our original example, where we composed two jQuery methods. So we've got these two jQuery methods, and we're going to stuff them together and we're going to create a new one. Now remember, we said that this thing was functionally equivalent to those two chains. So composing them, smashing them together in this case, is the same thing as chaining them. We established that. What's interesting is that if the functor law, if we can say that that functor law holds, it's actually exactly the same thing as just composing the two underlying manipulating bits and then mapping it once. So recall that that first one up top is two methods and two loops, and the one at the bottom is just one map. So this one is one loop, and the other one is two, and that applies broadly. So you can do this with as many chains as you want. So the functor law, what the functor law is telling us, and this is the key insight, is that if we adhere to some of these laws, we can say with good confidence that this is exactly the same thing as chaining it, but with less effort in terms of execution. OK, so meanwhile, back in the real world, everybody's wondering why this matters. You might even be saying to yourself, where's the beef? So I'll show you. Let's go back to our original example. Now I'm going to take out hide just for simplicity's sake. There's nothing particularly important about it. I just want to make this simple enough to understand. So you have these two jQuery methods, add class, and show. We've got two loops here, right, as we described earlier, and we want to make it one loop. So let's take a look at these two things. So we have these two things. Now what do we do if we want to get these things composed together, squished, in a way that solves our problems? Well, first thing we need to do is we need to, well, sorry. So that's the stuff that matters. That's the stuff that we need to squish together. And this is a squished together version, right? But we said that this has two problems. It has the first problem, that you have to go find it, and you have to know that it'll work, and then two, you have to copy and paste it, all of which is bad. So what do we do to fix that? How do we use the thing that we learn from category theory to fix this problem? So first, we need to expose this stuff. We need to stop mapping it directly, and we need to make sure that the underlying stuff is available to whomever, myself, whoever's going to be using this. So for now, we're going to wave our hands and say that because I'm defining it just as a function, it's global. And then, because we've defined it globally, and we've said that composing those two things is the same thing as chaining it, these things are effectively the same, right? So let me go back to that again. So these two things are the separated version of that top thing that's squished, right? But now, we have that compose function. So these two things are functionally equivalent. And that's what we wanted. We wanted a really simple way to squish everything together, right? We want the performance benefit, but we don't want to copy and paste, and we don't want to sit around and worry about whether we're going to have issues throwing these things together. And that's what we got. So we solved both of our problems. We've introduced a tiny problem, though, and it's a good problem, though. That's why it's a smiley face and not a frowny face, is that when I said I sort of hand-waved and said it's global, that doesn't work for everybody, right? So if we want this to be something serious and concrete, we actually have to make that available. That's where this comes in. And again, you might be wondering, John, this is interesting. You've got a performance benefit here. You even showed me some graphs that said it was 10% faster. Is any of this available to me today? Can I go compose these things? And the answer, obviously, is no. So we're going to talk about what we can do to fix that. In this scenario, so if we have an example in this set foo scenario that we described earlier, this is what you would do. So you'd sort of expose these things. And then inside the jQuery method that you define, you sort of map the HTML altering thing, right? So in this, actually, if you go into jQuery, a bunch of extra complexity, a lot of the methods actually do this on some level or another. They might use some of the internal methods. They might even use map. But internally, what will end up happening is they'll loop this sort of HTML altering stuff over the entire set. So for our example set foo, we've got the pure function exposed globally, globally. And then we use the map internally. So the answer to this, one answer, possible answer to this would be to say, for all jQuery methods, if you are able to and you think it's a good idea, you can expose that underlying piece of functionality as the composable property on the method itself. So this would be one way that everybody could know, like, oh, maybe I've got this big, long chain. Maybe I can smush some of these together. They could go look to see if that property was available. So what would that look like if you wanted to do the squishing yourself? So we have a chain here set foo, do bar. And both of those happen, thankfully, to some intelligent person who paid attention to my talk. They happen to have the composable attribute and the underlying manipulation to the DOM is available. All they have to do is use this compose function, ostensibly a helper with jQuery, and smash those two things together and map them over and you get some sort of performance benefit. That's the ideal, at the very least. But this is nice. And in a lot of ways, it's not a gigantic amount of complexity to add if you're actually evaluating performance. Generally speaking, when you do performance enhancements, there's some sort of trade-off. You're sacrificing some sort of obvious abstraction for something that's a little bit better. In reality, it probably has to be something a little more complex. And you don't necessarily have to worry about this. But likely, it has to partially apply some of its arguments. So there aren't very many jQuery methods that don't take any arguments. Most of them require some sort of input from you in terms of a selector, a string, some sort of information. So to get that composable thing out, you need to partially apply these arguments. If you don't know what I'm talking about, it's OK. So there's more to this. There's more on this concrete stuff that you can get into here. So first of all, the proxy. So I built a small library. You can actually, if we're at the case that jQuery methods define these things, or plug-in authors decided to start doing this stuff, you can actually warn the users automatically when they have chains that have these composable attributes. So it works as a very simple proxy in the prototype chain. And it can log to your console in the case where there's three methods in a row, two methods in a row, five methods in a row. You can configure it. The object size can be taken into account. And in that way, we can make sure that there are actually performance benefits when you're warned. And you don't actually really have to think about it. You just drop it in the DOM, and then you look in the console, and you look for optimizations. So with being able to reduce pain in this way makes it much more viable. There's still a lot of performance testing to do. So I've done a fair amount. I think it's well-founded for smaller sets with two or more chains. Well, probably three chains is probably a good place to start, or three methods chained. But it requires a lot of testing. So sort of assuming that it's a performance benefit because you're removing the number of loops that you're doing is not very smart. And it would be very interesting to see it implemented on an actual project. So I happen to be a jQuery mobile contributor, but I don't think they want to bother with any of this. If you're interested in this, and if I haven't totally ruined your day with math, there is more stuff on my blog about it. There's another article that's almost purely about the category theory, which has value. And I sincerely hope that it gives you an idea that the math doesn't have to be painful, that it doesn't have to be like calculus. There are interesting applications even in your day-to-day. So JavaScript, obviously, is your day-to-day. And we've applied category theories seemingly something very abstract to the very concrete. And that is category theory. So I have three minutes. I did not think I'd be able to do that. Happy to take questions if there aren't any. Hey, I have a question about the original performance stuff. So I'm assuming that you just smushed and then ran the performance and did not actually do the partial application slash. Basically, your compose method and your partial application creates a bunch of new functions, presumably. Which is overhead. And that's actually part of the performance testing that has to happen. I still think that, and moreover, the examples are two chains. And in theory, there are much larger chains to be had and bigger performance benefits in terms of function call overhead. But yes, you are correct. OK. Great talk. Great concept. I don't mean my question to sound like I'm questioning it. What would be the difference functionally between doing what you suggested and taking any collection, saying dot each, and then doing three chain methods together individually, as opposed to then looping through it three times? Then you're doing one loop. So let me be clear before I repeat the question. You're saying just do each and then just kind of use the underlying stuff together. So that's what, OK. So the question was, why not just use each in a chain as opposed to using the jQuery method itself? So that's actually what we're trying to avoid. So the idea is that we don't want to do the extra loops. We want to eliminate those extra loops. And every time you use each, or I think what you're saying is that just use the three function calls, yeah, you can do that. But again, I think that the composer, to you who lose question also, that there's a performance benefit there. But I think the composition, one, provides a bit of rigor. Two, it gives you a sane way to put those things together without causing more mistakes. And three, it adheres to what we talked about in terms of category theory. You don't even have to do it with map, actually. You can do it with each because everything is a side effect. And actually, more importantly, because there are side effects, a lot of times the functor law doesn't apply. But it's an interesting insight into performance as a consequence of category theory. So you're not wrong. It just didn't fit into the map. Hopefully that answers your question. Lou, OK, so it's possible he just asked this. I heard your response, not really his question. But so theoretically, if you have four functions in a chain, and say the collection is like 20 objects along, so you'd be iterating 20 times and doing each one of those chains or something like that. Correct. If you were to say you select the same 20 item collection, and then you say dot each for instance, or a map, or whatever, and then inside the each loop, you call each one of the functions individually, each one of the four chain functions individually, you're theoretically still looping over each collection. But the collection has one item, if you will, in each set. I see what you're saying. Sort of what you're saying. So part of the performance issue here in understanding the performance tradeoffs is that the loop isn't that much overhead. It's actually, it's a couple function calls maybe. It's array access and maybe some incrementing somewhere in there. So the benefit is really, it can be quite small at times. But there is still a benefit there, because you are only doing that once, as opposed to resetting your increment variable and not doing the array access again and not doing the function calls again. So there is a benefit there, but that is similar to what he asked, which was, can't you just shove them all together? And you can. The downside being is that you still have to do a little bit more work, and there's maybe correctness issues there. I hope that answers your question. If it doesn't, we can talk after. I think I'm out of time anyway. Somebody in the back there. Do you have any plans to hack some code up together, like a patch for jQuery to make their, I don't know, to apply this, I guess? Yeah, I mean, it's a nice idea. Reality is that this should be very far down the list of their priorities, if we're even there. So it's not, it's a nice idea. There is, it's, again, I took the time to make sure that it's well founded. It's sort of an academic exercise, too. But what interested me and the reason why I wanted to give the talk, and I actually really appreciate the fact that they let me give the talk, is that this is the kind of stuff that interests me. Math, math is applied to everyday stuff, can be very interesting. And that's why I was kind of excited to give the talk. So no, I don't think that they're gonna implement it. I don't think that it's worth their time to be totally frank, especially for what, what appeared to be initially for small gains. Now, if I come across some set of, some set of conditions which increase the gains, and we can detect those, obviously, maybe I'll make a case for it to do the work myself, but realistically no. There's nobody else. Thank you very much. Thank you.