 Am I in the wrong place? So many of you to stick around. So thank you. Thank you very much. Hello, RailsConf. Hello, everybody. So I am going to introduce myself because I think that there are many people here who don't know who I am. And the way that I found that out is because I kept trying to airdrop my cat and they declined it. So that was me. Hi, I'm Tender Love. That is my given name. I look a bit different than I do online. This is my online persona. And I guess, as Justin says, this has to be my brand. I'm stuck with this for the rest of my life, so I'm sorry. I work for a company called GitHub. It's a website where you can go and share code. It's a legit company to work for. I went to the office, and the office is actually called Legitub for French people. OK. I'm on the Rails core team and also the Ruby core team. I have some cats. This is one of them. This is C-Tac Airport Facebook YouTube Instagram Snapchat. It's her full name. We call her choo-choo for short. This is Gorbachev Puff Puff Thunderhorst, the third. He's not a very good conversationalist. Frequently, he ends up just making mistakes and putting his foot in his own mouth. So I have stickers of my cat, and hopefully you got them from me, because this is the very last talk, and I don't know if I'll be around. But I have stickers of them, so if you'd like a sticker, come see me. But all right, let's move on a little bit here. Speaking of things that are orange and like to puke on my floor, I want to take a minute to talk about Hacker News. So I drew this slide. So I like to be on the internet. I'm on the internet on the Twitter. And a lot of the people that I follow, they think that Hacker News sucks. They're always saying, oh, Hacker News sucks. Hacker News sucks. And I'm like, why do they say this so much? Are they actually reading it? Is that if you hate it so bad, why are you reading it? But the thing is, I actually like to browse Hacker News and read the comments and stuff. I read them so that you don't have to. But the reason I read them is because I like to think about how they got it wrong and how they can fix it. So recently there was an article that was like, why Slack is inappropriate for open source communications? And I'm like, why is it? I don't know. So I was reading the comments. And one of the comments was, we are temporarily in a kind of dark ages for end user open source software. And I was like, we are. It's actually true. In fact, the other day, my friend, he got bit by a rat and he actually died of the plague. It's literally the dark ages. It's really the dark ages. I drew that too. So another article that I read was, Electron is flashed for the desktop. I'm like, really? It's flashed for the desktop. And Slack, it often idles at 5% of our CPU. It uses up 5% of the CPU all the time. And I was thinking, oh, that's interesting. So let's say you have your CPU and Slack is chewing up 5% of that CPU. Well, one way to solve this problem is to actually just purchase a larger CPU. You can see clearly now that it uses much less than 5% of the CPU. So the lesson here is bias, bigger CPU. You dummy. I mean, if Alan Turning were reading these comments, he would be turning it as grave. He is a real person. Just, so I read another article about language features that I thought was interesting and said, no generics and no sum types. I think this is about Go or something. These are no longer groundbreaking features. They're the minimum. So it means that if your language doesn't have generics, it means your language is a failure. It means your language is a failure. And actually, this comment is true. It's totally true. And the reason this comment is true is because insurance companies only cover generics. So if you take your programming language to the hospital, they're just gonna say, no, I'm sorry, your language has been denied. They will not take that. I drew that too. So anyway, this is all I have to say about Hacker News. Just don't read it. I mean, unless you want to know all the future episodes of Silicon Valley. So I'm from Seattle. We have a space needle. And I'm a huge fan. I'm a really huge fan of supporting local businesses. I love to support local businesses. And in Seattle, my favorite thing to do is I like to drink a lot of local coffee. So I was trying to find out about different local things to do here in Arizona. So I went and I decided to try out some of your local brew, which is Arizona tea. So I actually had to go to three different convenience stores. Or I went to three different convenience stores and none of them had Arizona tea there. So I started to think like, well maybe in Arizona they just call it tea. You can't actually buy it here. And then I found out it was for sale at CVS. So I went to the CVS and purchased some. And then I looked on the back of it and it turns out it's actually made in New York. And I asked the teller about it. I'm like, oh, this is made in New York. I thought this was an Arizona thing. And she said, no, no, only tourists drink that. And I'm like, okay, well, I'm a tourist, so thank you. So, all right, I want to get to the next section of my presentation, which is one of my favorite parts of the presentation. Every year when I give a keynote, I like to have this section in my talk, which is the Trolling DHH section. It's an annual tradition. Unfortunately, this year was really hard. It was very hard to come up with ideas because I think the main points of DHH's talk was that he's gotten older. And as he's gotten older, he's learned that other people also have valid opinions. And I mean, there's not much bad you can say about that. So I didn't know what to do about this. But okay, I'm gonna sew a little bit of doubt here. So I've got a question for all of you. If Rails is so good, then how come there isn't a city named after it? The other thing that he mentioned in his talk was that there's no way to scientifically prove which language is best. And actually, this is completely wrong. This is a totally wrong statement. Just ask any Haskell developer, and they will tell you there is a mathematical way to prove that Haskell is the correct language to use. Anyway, so I'm a faith-based programmer, so I'm done. Every day I say the programmer's prayer. And I also religiously listen to George Michael. The other thing that was wrong with his presentation is he clearly did not put the clear winner of the console wars, which was the Neo-Geo. This is the winner. It had 24-bit audio, like 16 or 12-bit crap, come on. Anyway, so I realized this year that I've been doing, I've been doing Rails for over 10 years. I got my first Rails job in 2006. That's when I started doing Rails professionally. And I wanted to tell you a story about my first, not Rails program, my first Ruby program, my first real Ruby program. My first real Ruby program I wrote in 2003, so it was 2003, 2003, and in this year, this year Lord of the Rings was coming out. Lord of the Rings Return of the King. And I was really excited about this. I was excited, you'll notice the release date on that is December 17th, okay? Now, my birthday is December 16th, and they were coming out with this movie, this movie, they're gonna play this one and the other two back-to-back in a movie theater, so it's like 10 hours of movies, right? And they were gonna do this a day early on my birthday, so I really wanted to see it. Now, at the time, I was a J2E developer, and, oh, this is a secret, so I thought they were only gonna be my five best friends in the audience, so I wasn't gonna say that part. I used to do J2E development, and it would take about 10 minutes to compile our code, and I have an extremely short attention span, so 10 minutes, I'm like, I forgot what I was doing. But anyway, I'm like, what should I do with this 10 minutes of free time? Thought to myself, well, I wanna buy these tickets, and I go to the website, I try to buy the movie tickets, and the website breaks, just doesn't work. It's like crashing under load. I mean, it's 2003. People did not know how to sell tickets online at the time. So I'm like, okay, well, I've got 10 minutes. I'm gonna try writing a Ruby program that will go buy the tickets for me, okay? So I wrote this Ruby program during my compile time that would go to the website, enter all the information, including my credit card number, and try to purchase these tickets. And the thing is, I knew what would happen when it failed, when the website failed, right? So I would go to the website, I'd fill it out, and I knew what the page looked like when it failed, but I didn't know what a success case looked like because I couldn't buy the tickets. So what I did was essentially is like, I'm like, okay, if I don't get a failure, if I don't get a failure, I'm just gonna log a message, okay? And I thought, well, I'll see it in the terminal, I'll see that in the terminal, and then I'll know, oh, I need to go check out and see what's up. So I go back to writing some JSP or whatever it was, like probably configuring some XML files. And later on, I noticed, like, I noticed, oh my God, the output on my terminal is different. What is going on? And I see all of a sudden, like, it had actually been succeeding, and I scroll up through the terminal, and I'm like, oh my God. So I'm like, what do I do? What do I do? How many movie tickets did I buy? So I called the credit card company, and I asked them the most, I don't know, like non-legit question ever. I'm like, hi, I was wondering, how many times have I charged my credit card today? Like, who asked that? I mean, if there's a suspicious question, that is one of them. So the person was very helpful, and they said, oh, well, you've only charged your credit card once, and I'm like, okay, great, just once, okay. So I wanted to make sure that I actually got the movie tickets, so I called the movie theater, and I don't know, like, looking back on this, I don't know how they actually had this data, but they did, so I asked them, like, hey, I tried to buy some movie tickets from you, and I'm just wondering if, you know, your site was down, I was just wondering if the transaction actually went through, and if I actually got the movie tickets. And a person looks up the data for me, and they say, yeah, yeah, you were able to buy some tickets, but it looks like we've tried to charge your credit card hundreds of times. And I'm like, oh, really? I don't know. I don't know. Like, what are you doing? I was like, oh, I was just hitting refresh, I don't know. So that was my very first serious ruby program was back then. Okay, so I want to talk, let's talk a little bit about technical debt, and I should move a little faster, I have a lot of slides here. So let's talk a little bit about technical debt, Justin talked a little bit about it in his talk, but I want to talk about a new strategy for dealing with technical debt that I've come up with. So we know that developers want to pay off technical debt, so as a developer, you want to pay off technical debt, but, you know, many of us in the Ruby community have grown up and become managers. I've been in the Ruby community for an extremely long time, and managers don't actually want to pay off technical debt. Because it takes time away, they'd rather be adding features or whatever it is that they want to ship. So what's happening is we've got this community that's growing up and we're ending up with all these people who used to be developers and now they're managers and they had published all of these gems and all of these gems have some sort of technical debt in them. So what I want to do, my idea is, I want to create a meta gem and this meta gem will actually package up all of these gems that have technical debt in them. And what we're going to do is we're actually going to call this meta gem a bond. And now these bonds are made of gems that have classes and these classes have extremely low FICO scores. So what we're going to do is we're going to take those classes and we're going to shop them around to different companies like Test Double. And if Test Double won't give us good FICO scores and we'll go to a different consultancy is the one down the road and see if we can get a better score. So we're going to package all those gems, try to get them better scores, gems or as we call them tranches. So my other strategy for this is that what we can do is we can take dependencies from other communities. For example, younger communities like the JavaScript community, they have newer developers and they want to pay off their technical debt more quickly. So their packages are probably triple A rated. So what we want to do is start pointing at things like Webpack, for example, which has a good credit rating so that we can actually sell these gems a little bit easier. Now what I think this is doing, I don't want to be too forward about this, but basically what this is doing is when we depend on these younger communities, that's actually helping us feed off the blood of young people. Sorry, rather than doing our, rather than being able to focus on our, we want to depend on these younger communities so that we can focus on our core competencies, which is concatenating a bunch of strings. All right, so earlier today, Sarah was talking about how the different talks at RailsConf are going to be, we have like forests and forests and trees and getting into the weeds, the individual discussions are getting into the weeds, and I'm sure you're thinking, okay, well, Aaron's from the Northwest, so we're probably going to have this beautiful, like beautiful looking forest. We're going to have a forest talk here since this is a keynote, but as I go on with this, I'm afraid you're going to see that we might start getting into the weeds here. We're going to get into the weeds with this talk, but what I really, really want you to know is that this is actually a forest talk, okay? This is a forest talk. It's just that it's a dead forest talk, okay? It's a dead forest talk, and you'll realize this at the end of the talk. Hopefully what I want you to take away from this talk at the end of it is, where did my 40 minutes go? Give me back my time, Aaron. So before we go too further though, this is not a joke. I need to do a part that's not a joke, okay? So five, five, five dollar, five dollar foot long, no, okay, all right, sorry. 5.1, Rails 5.1. I am very pleased to announce that Rails 5.1 is out. I am honored. I think this is the first time I've been able to announce Rails release, and I want to say thank you to the rest of the team, thank you to the contributors, especially thank you to Rafael. He did so much work to make this happen, so please. All right, so I originally wanted to title this talk. I don't have time for this. I want to talk about things that I would like to do, but I don't have time to do them, and I like this title because it's non-committal. Like I don't, you know, it's just some things. I don't know, I don't have time. There's some things I'd like to do, and I don't have time. It's also a humorous use of a common phrase, which I think is good. The problem though is that when you're a keynote speaker, the organizers tell you, you know, oh, you can talk about whatever you want to. There's no pressure, there's no pressure. And of course, whenever anybody says that to me, it just means it's all of the pressure for me. It's just extreme pressure, an extreme amount of pressure. And in fact, I actually took the serials, Briggs test, and somehow my result was stress. I don't like, so, so I, you know, I'm thinking I want this, you know, I like this talk title, but then I'm overcome by fear and self-doubt. I just think to myself, you know, what if I totally screw up? I'm gonna sound like I was arrogant, like I didn't prepare for the talk, and you know, I didn't do enough work. So I thought, okay, well, what if I say, what if I call it like five things I don't have time to do? So I'll change it to that, so it's more concrete, people know what to expect. But then I got even more worried. I'm like, what if I don't actually have time to present five things? Or what if I want to talk about things that I do have time for? And now I'm limiting myself. What can I title it now? So the real title of this presentation is some things that I don't have time to do, but you should do them. Maybe like three things, but I have time to do the other things. So that's the actual title of the talk. I've split it into two segments, the probably important segment and the definitely not important segment. So we're gonna go through the probably important segment and then after that, I want you to all shut your brains off and just relax because trust me, this presentation is a huge waste of your time. So we're gonna talk about HTTP2 and RAC and I'm gonna refer to it as H2 from now on. This is a thing that I do have time for. Let's talk about what is H2? H2, well it's a version of HTTP that's one better than H1. Most of us, I realize, most of you are using HTTP 1.1, so it's actually 0.9 better than that, but it's still better, still an improvement. So really what it is is this list of stuff. It's a binary protocol in multiplexes, which means that you can do a request and a response over the same TCP connection. It's secure, it only works over SSL. That is not technically true. It'll work over a plain text connection, but all the, or an unencrypted connection, but all the major browser vendors only support it over SSL. The other major thing is push responses, and I'm not gonna talk about the first three because they don't really impact us as web developers. I'm just gonna talk about the last one because that's the major change for us as application developers. So push response flow, in a normal H1 application, your request and response will look something like this. You have an HTML page, that HTML page gets returned. It depends on jQuery and say my cat CSS file. So we have to go back and forth and get all of these. Now with H2, when a user requests that index.html page, we know that they're gonna need jQuery and the CSS file, so what we can do is we can say, okay, when you make a request to index.html, I'm also gonna push down these other assets as well. They're gonna come down along with it without you needing to request it. So we're saving time by pushing these needed resources down to the client. Now, unfortunately this has a problem. There's some problems with H2. And the problem is that H2 is stateless in the same way that HTTP one is. So we don't necessarily know whether or not somebody has received that asset. So we have a problem where maybe we send those assets down to the user and they already have jQuery. So in that particular case, the client may actually cancel it. So we'll have to, we'll send them index, it tries to send them jQuery, tries to send them the CSS file, and the client actually has to say, no, no, I don't want that, I don't want that. And in some cases, it may not say, oh, I don't want that, it may just take the asset, and now you've actually sent the asset to the client once. So the client can cancel or we may actually resend the assets. Both of these are problems with this type of push service. So the solution is H2.o.Insult. Ah, I feed on your pain. It energizes me. No, okay, really, the solution is H2.o. in cookies. So let's talk about H2.o. H2.o. is, and yes, this is an annoying URL that is example with L as the number one, okay? Yeah, I know, right? Anyway, H2.o. is a proxy. It's an HTTP2 web server. It's a proxy server. And I'm gonna talk about the solution that it uses for dealing with this asset problem. And it sits in front of your application just like, say, Nginx would, for example. So we have a client here and the client talks to our proxy, our H2.o. proxy, and then the proxy talks to our application server. Now the proxy speaks H1 to our app server and it speaks H2 to the client. So if we wanna do H2.pushes, we actually can with an H1 web server. And the way that we do that is we can use the link, what's called a link header. So when we send the response, for example, this response, the proxy will actually get the response, look at these link tags and say, okay, I'm gonna push those assets down to the client. So in this particular flow, our server responds with some value like that. It sends it over to the proxy. The proxy says, okay, I am going to push these assets down to the client. Now H2.o. what it does, what the web server does is it actually makes a fingerprint of those assets and stores them in a cookie. Now if you've already pushed those assets down to the client, it won't push them again. So it knows whether or not it needs to actually push those, push those assets down to the client. And this is extremely nice for us because it means that in our application we don't have to do any state tracking. We can just say, I'm just gonna push these down. I know it's an index, I'm gonna send you the link headers, you deal with it. So the proxy takes care of all of that for us. Now there's one problem with this response and that's that if you look at the response here, we actually have to send the link header after we calculate the response code. So what if we don't actually know that it's a 200 yet? What if we wanna send some assets regardless of what the response code is? So the way that we can do that is with a new, there is a new proposal being proposed, verbs, whatever, called the 103 early hints response. And what this is is just a new response code that basically has no body and it looks like this. We just stuff our link headers into that. So that previous example would change to this. So we can send a 103 with the link header and then go on and do the rest of our page processing and H2O understands this 103 response. So this allows us to send push responses without calculating the status code. So let's talk about rack support and this is going to come into rack 3.0. The main thing that we're missing from rack is we're missing this push response. So essentially what we're going to do is add another hash key. Woo, yeah, yes. Now I'm not very excited about this solution because I don't really like the API of just passing hashes and stuff everywhere. But the win that we get from this is that it's backwards compatible. You'll be able to upgrade your applications without breaking anything. And you can actually gracefully upgrade your application so we can say, all right, I'm ready to take advantage of pushes so I can do that now with my web server. And this is all coming in rack 3.0. Hold on a sec, getting a little dry here. Local T, support local. Actually you know what, I'm going to set this down here. I don't want to, I like the joke but I don't like it enough to ruin my laptop. So all right, this was the part that you had to pay attention to and now feel free to shut off your brains for the rest of the presentation. We're going to talk about code smells. So I want to talk about code smells. So I've been working on a project at home. I've been collecting a lot of data and this is some data that I've been acquiring. I have a digital signal that I've been collecting at home. And I apologize, the signal is it's not very good. The data is kind of crap. And I want to do some analysis on this data, okay? So I want to do some processing on it and I've been trying to do the processing in Ruby. Now unfortunately, it's a lot of data. I've been recording a data point every second since what is that, January 23rd this year. So it's still recording as we speak. And I've been trying to do data processing on it but I need to do a lot of math and I'd like a way to increase or speed up mathematic operations in Ruby. So I was thinking lately about doing some Ruby VM tricks and I'm gonna show you what I've been thinking about doing today. So first we need to talk about how VM works. The way a VM works is it's pretty easy. We have a program and there's a stack and then there's a program counter and this program counter always pushes at the next instruction to execute. So the way these instructions work is they just manipulate this stack. So first we'll push on a number four to the stack. Then we'll push a number three onto the stack. Then we'll add and the way add works is it pops the two values off the stack and pushes the new value onto the stack so we get seven. Now the way that this is actually implemented is something like this. We have a list of instructions and we have a loop. We loop over the instructions, we get the next one and we look up what the method for that next one and then we execute that method and we just keep running through this loop over and over again. Now there's a way that we can actually speed this up and we can actually eliminate this loop that loops over the instructions and we can do that by generating the virtual machine. So if we generate the virtual machine and we can generate a bunch of functions and each function represents the instruction sequence that we're going to execute. So this is what the VM might look like. We have a few instructions implemented there and we have this small bit of code at the end of each function that's been generated. That bit of code right there is generated and what that does at the end of each function is it looks up the next instruction to execute and then just calls that one. So we're able to eliminate that infinite loop. This technique is what's called a threaded virtual machine. So you can think of it as threading, we're going through one function and popping out of that function into the next one and we keep going and going. So we're threading through the instructions rather than doing a loop. Now there's a problem with these function calls. The problem with function calls is that we can end up with a very deep stack. So what we'd like to do is eliminate these function calls. So we can actually do that by getting rid of the, getting rid of the function lookup. So what we say here is we say, okay, this is our normal lookup process. We actually look up the function and we call send and that goes and calls the function. Instead what we can do, and this is a trick that you can't do in Ruby, it's a trick you have to do in C, is we end up with a switch statement like this, a label with a bunch of go-tos. I use the word jump because that is, I don't know, I guess it's more socially acceptable than go-to. So what we do is we actually look up the address of the place that we need to jump to. So we have this generated bit right here. So we say, all right, we're gonna generate this, we'll look up the address we need to jump to and then we jump to that. So we don't actually have to, we don't actually have to call a function anymore. We still have a problem here. There's a way we can speed up this VM even further and that's eliminating that table lookup. We can get rid of that table. So instead of looking up the address that we need to jump to, instead we embed that address into the bytecode itself. So when we're compiling your code we embed that address into the instruction sequences. So then when we look it up, we just say, okay, jump to this address directly. We don't have that jump table anymore. And this is what is called a direct threaded VM. And this is the VM that's used in Ruby MRI today where the interesting thing is that these addresses are just integers, they're just arbitrary integers inside of your computer's memory and we just jump to them. So MRI's VM is direct threaded. So what I would like to do is create custom instructions built from machine and build machine code at runtime. Since those instructions are just integers, they're just places to jump to, we could actually just insert our own, our own address and jump to that thing and have it execute there. So I put together a very simple example of this. Please read it carefully. This actually uses LLVM to assemble machine code and we can execute that machine code from Ruby. The only thing that's missing here is actually disassembling the VM code and inserting our own integer to jump to. So my first idea of stuff that I don't have time for is creating custom instructions at runtime that we can actually speed up our mathematical operations. So okay, we've got one way we can speed this up. Now back to the data. I've got a faster VM would definitely help analyze this data but a fast VM isn't gonna do us any good unless we have algorithms that can help us deal with, help us deal with analyzing this data. So in order to analyze this digital signal, I would actually like to build a police scanner. So now I am 36 years old. I am soon to be a, I am now a homeowner. I need to be sitting on my front porch listening to a police scanner because that is what old people do. Yes, you'll be me in the future, I'm sorry. So I bought one of these. This is a very neat tool. It is a software defined radio that you can, a radio you can plug into USB. Now I'm gonna give you an example of what the software actually looks like when you use this on your computer. It looks like this, this is live. I'm actually scanning, doing some police scanning right now. That bar in the center there is a digital signal. The digital signal indicates what channel people are broadcasting on. So the digital signal is used to coordinate between different channels. This is what's called a trunking scanner. So you can see up there I'm actually manually moving the signal left and right. So the audio voices are actually analog and the thing that coordinates which frequency those analog signals are on is that digital signal that's there in the middle. I'm gonna mute this. So you get an idea, you get an idea of what we're dealing with here. So you can move it back and forth. This is an example of an FM band radio so you can see it's a little bit wider. This narrow FM that police use, this is what it looks like. In the middle there is our digital signal, our digital trunking signal and over on these little bars that you can see jumping around, those are our audio signals that we need to listen to. So we have to be able to decode that digital signal in order to find the audio signals to listen to. So to do this we do digital signal processing and this is actually split into two different signals. There's two types of signals, continuous signals and discrete signals. Continuous signals are like maybe the light is coming to you. You see light or you hear music. A discrete signal is what we deal with on the computer because we actually have to take samples of those things. We can't store an infinite number of points on the computer so we deal with discrete signals. And I made this. Persona 5 people please appreciate this, thank you. I worked very hard on that. So discrete signals are just a list of points. So again we've got this discrete signal here and I do apologize for this crappy data. It is really just crap data, I apologize. But this is a discrete signal that I'm trying to deal with. So the way that we deal with these is through a process called convolution. And this is what convolution is, is taking two signals, combining them into a third signal. And this is kind of what we're doing here. I apologize for the star there. The star is actually the mathematical notation for convolution. Unfortunately it's also the thing we use for multiplication in computers. So convolution is taking these two signals and coming up with a third signal from that. The formal definition is like this. We're not gonna, I won't describe it here, we'll do it in pictures. So we have three signals here. That top one is our original signal. The middle one is the signal that we wanna convolute with and the third one is our resulting signal. So the code for actually doing this is this is the code for doing it in Ruby. And I want you to notice that it's based on arrays. We're using array indexes in this and our array indexes start at zero. This is important. So convoluted, our convoluted signal length is actually the signal, the length of the two signals minus one. And the way the algorithm works is we have a signal at the top there. That's our origin signal. The signal at the bottom is the one we wanna convolute with. And we take those points on the bottom signal and multiply them times the points on the top signal and then sum those to get that, the points and the resulting signal. So we actually move it along. It starts at zero like this and we move it along like that and keep calculating those and that's how we come up with a new signal. So we're gonna look at a few low pass filters. Low pass filters are just these little chunks that we apply to the signal. So this is an identity signal. It's just the number one. And if we take the original signal, convoluted with the identity signal, then we just end up with the same signal again. We can actually use this to define an amplifier. So instead of multiplying by two, one, we have a two. So it looks the same, but you can see that bottom signal is actually twice as high. We can use this to shift a signal one to the right. So if we set point one to one, we've actually shifted our resulting signal to the right by one. And we can take these little kernels and combine them together to do interesting things to the signal. For example, we can make an echo. So we have a amplifier plus a shifter, which comes up with an echo. We can even come up with an average. So we'll take these two signals and figure out the average of a signal. And the reason I wanna do this is because taking the average of the signal will smooth out that random data at the bottom, but keep those sharp edges, which is what we're trying to detect. We can actually use this for radars as well. So for example, if we transmit a signal like the one on the left and we get a signal like the one on the right that contains random noise in it, we can answer the question, does one signal contain the other? And we do that by taking the received signal and convoluting that with the transmitted signal. And if that received signal contains the transmitted signal, then you'll get a very high spike where it is. So we can actually detect when our signal is there. Another neat thing that you can do is you can come up with a Gaussian distribution. So if you take one signal and you convolut it with itself a few times, you'll actually end up with a Gaussian distribution like this. And I just think that that is neat. So again, here's our convolution code. And remember, it's based off of zero-based indexes. And I thought to myself, I've gotta do all these transformations and I wanna graph them and I want to graph them in R because doing it in R is pretty cool. Like it makes you look smart and stuff even though the graphs are crappy, everybody's like, oh, crappy graphs, you use R. So I thought to myself, okay, well, I'm gonna port this Ruby code to R and then graph that data. So I learned about R the hard way. I took this, I just ported the code straight over to R and it turns out that in R, arrays are actually one-based. They're based on one. Now what's really extremely fun about this language is if you ask it for the zeroth element, it gives you the type that's stored in that array. So in this case, numeric, I have a list of integers. And what's even more fun is that you can perform mathematical operations on that type and it just works. No error. So I'm like, why are these calculations totally wrong? I was very frustrated. So I thought to myself, I don't wanna figure out how to port my Ruby code to use one-based indexes. I'm not that smart. There must be an easier way. I thought to myself, there must be an easier way. All right, so back to the data, back to this data. All right, so I've got this data and I'm sorry it is crap data. We're trying to improve it, but it is crap. So I didn't wanna figure out how to deal with these one-based indexes. So my next thing that I want to do, and I just don't have time to do it, is implementing Khan's, Karr and Kutter in different languages, but using only lambdas. And you may be asking yourself, why? Why would you do that to yourself? And the reason is I like learning new languages, but I don't have much time. I don't have much time to learn a whole bunch of new languages. So I thought to myself, what is the bare minimum that I can learn in any particular language in order to get endorsed on LinkedIn? And I thought to myself, well the one thing that I can learn, if I learn lambdas in every single language, then that should be enough to get me into any, get me endorsed on LinkedIn. So lambdas is the thing I wanna learn in any target language. So what are Khan's, Karr and Kutter? Khan's actually forms a cell of a left and right thing. So we just have two things here. Now the function Karr returns the left side of the cell, so it'll give us back the left side. The function Kutter will actually return the right side of the cell. Now can we do this only using lambdas? And the answer is yes, we can. And I've written it in three languages here for you. This is R, Node, and Ruby. And I call it Node because I don't know the difference between Node and JavaScript. And I actually posted this function onto Twitter and I was like, oh, why do I have to type return so much? And then I got tons of responses that are like, well, use ES6, bro. And I'm like, I don't know what that is. So this is kind of a mouthful and I need to move. But what it is is Khan's is a function that returns a function and that function that it returns takes a function and calls that function. So it returns a function. All right, okay, so don't think about this too hard, please. So Karr, what it does, it's a function that takes a function and calls a function and passes a function. And the function that it passes returns the left side. And actually the easiest way to see this is using R. So I've defined Khan's and R. And if we call Khan's, you'll see that it actually returns two things, a function. So like I said, it returns a function and it returns an environment. And the environment is the thing that actually captures those two values. You'll see Karr is just a function. And I can pass the return value of Khan's to Karr and recover my original value. Now here is the Kutter implementation and it actually just returns the right side. It looks exactly the same as Karr. We're just returning the right side rather than the left side. So with this, we can actually form a tree of cells. So we can say like, okay, we have a one and a two or we have a one on the left side and the right side points at another cell and then we can just keep doing this and end up with null on the very end and we can actually turn this into an array. So if I implement a function called each, we can iterate over that list. Now here's an example usage. This is in JavaScript. We can see we cons together a bunch of stuff and we can actually loop over those and get our values back. So what's neat about this is it means, well, we don't need loops anymore. I don't need to know how your language implements loops. I don't need to know how your language implements arrays. If I implement my own hashing function, I don't need to know how your language implements hashes because I can just use a tree. So what about numbers? Well, we can actually eliminate that too. I don't wanna know how numbers work in your language either and we can do that using a thing called church numeral encoding and what that is is we define a function that calls something zero times, that's zero. We define a function that calls a function that you pass in once, that's one and if we call the function twice, that's two or three times, that's three and that's the way that we encode these and if you look at the very bottom there, I can prove to you that three is equivalent to three by passing in a function that just increments by one. So we get three back from that. Now I'm lazy, I don't wanna define every single one of these so I can actually define a function that's called add since we know that we just need to call that function the number of times for the number that it is. So we can define the function one, we define add, then we can define two and three and et cetera, et cetera, et cetera, so I have all the numbers and this is called church encoding. So I no longer need your numbers. I know how to do add, I can figure out how to do subtract and multiply and divide so I don't need your mathematics. I can even circumvent logic as well so if I implement, I can implement true and false in lambdas and I can implement conditionals with those. I'm not gonna go into that because I do need to move along. So we don't need booleans, we don't need conditionals, I don't really need any of your language, I just need lambdas. So back to my crap data, back to our original problem, I didn't wanna rewrite my algorithm using one based arrays. I wanted to rewrite that, I wanted to write it using zero based arrays and now that I can implement an array in any target language that I want to, I can make my arrays zero based. So what I did in ours, I implement Khan's car, Kutter, then I implement each, then I implement each with index and now I have an array and I implemented array indexing so I can say like at, I wanna get an element at a particular index and I'm gonna make that index zero and I can actually take those vectors from, vectors from R and turn them into Khan cells and now I can actually port that convolution code straight over to R using zero based indexes. Yes! All right, okay, okay, okay. So I'm pretty proud of myself, I feed in some test data, I got some test data there, I'm able to plot it, I can perform filters on it, I can do, I can define a filter, plot the data, the filter and then do a convolution on the data and plot that as well so I can see, this is our, these are our crappy graphs, you can see I know how to use R. So I'm pretty proud of myself at this point, like yes, nice, it looks good. So I'm like, okay, let's take our real data and input it and I take my real data that I'm trying to analyze, I input it and unfortunately it says error. Evaluation nested to deeply, infinite recursion, it turns out that R does not support tail call recursion so this blows out the stack and I just think I hate R. So things I don't have time for figuring out R. All right, back to the crap data. So, I've accomplished nothing. I wanna share with you something that I built that actually acquires this data, so I wanna show you where I got this data from and what I'm trying to, what I'm actually trying to figure out with this data, so I wanna show you something that I built. What I built was, I have this contraption right here, it's composed of a bathroom scale, so we have a bathroom scale, we have an MSP430, this is a microcontroller that is able to read off of the scale and give us the weight data over a serial connection and then I have a Raspberry Pi plus a motion sensor and the Raspberry Pi will read that weight data over the serial connection. So, I have it set up at home like this, so at the top there is, at the top is where I have the Raspberry Pi mounted with the motion detector and at the bottom there, that orange bar is the scale. Now, on top of the scale, I actually have what is known as a litter box and when the cat goes in to the litter box, I can detect that and the cat leaves and I know that the cat has left. So, that is where this graph comes from. I'm not done, okay, I'm not done, I'm not done. So, on the left-hand side, this is where the cat enters and on the right-hand side, that is where the cat leaves and if we calculate the difference between those two, we can figure out approximately how much was left behind. So, I have calculated to be about 100 grams. All right, so let's wrap this up. I wanna wrap this up with a little kernel of knowledge for you to take home so that you don't feel like my entire talk was a waste of time. So, what I really wanna let you know, what you should take home from this conference today is that it's very hard to make shit scale. Thank you very much, it was an honor to be here, thank you.