 My name is Paolo Asiarrada, nobody ever remembers that, so most people just call me Pote, I hope you guys will too. I am also a fan of Pokemon. I'm actually wearing a Pokemon shirt right now, and you probably won't be able to tell because of the distance, but I have a Pikachu on my phone, so I'm really looking forward to seeing a full-fledged Pokemon talk from Elisa, but maybe in some other conference. So I wasn't really going to bring this up, but it just sort of turned into a thing, so I'm going to do it. Yesterday, we had David from Mexico coming and presenting here. We also had Seostian from Colombia, but actually I flew all the way from there to here in order to be here for Nickel City Ruby. So yeah, I'm sorry, PJ Formation, we're just sick. So the reason I bring that up is because back home, I'm a part of this software collective called Thirteen Floor, which is a really interesting experience. And I bring this up because the collective actually sponsored my trip here. They paid for my plane ticket. They made it possible for me to be in this room, so thanks to them. I also want to thank the organizers of Nickel City. I've been witness, I've had a glimpse of how much work and pain they went through to get, like, to put this all together for all of us, and so I think they deserve a round of applause right now. Anyway, I think it's really come together. I'm having an amazing experience on this conference, so thank you very much for inviting me and, you know, making me a part of that. But anyway, enough of that. I'm here talking about simplicity, and it's a really important topic to me. That's why I'm here presenting, because talking about simplicity and minimalism and thinking about that has really shaped me in many ways. It's changed the way I approach software and it's changed the way I approach solving problems in general. And so that's why I wanted to share a little bit of the thoughts I've been having for the last maybe two years about how simplicity can help you maybe become a better programmer, at least, you know, having more peace while doing it. So why are we all here today? We're all here in this conference because in maybe different degrees, we're all obsessed about quality. We're obsessed with the quality of what we do. We want to become better developers. We want to become better designers. We want to be better at what we do. And that's a really healthy thing to want, right? We all want to improve, like, better ourselves. And I think that's really important. Why is that? Why is it that developers have become so obsessed with it? It's kind of tricky thinking and measuring the quality of a piece of software, right? You can't just, like, say, well, I'll give this, like, objectively, giving, like, four out of 10 stars to a library or gem. Like, it doesn't really work that way. And so what we've resorted to doing is to think of all these attributes that we think are important for a gem or a library or a piece of software to have. And, like, sort of through that indirectly, we're kind of measuring, in a way, the quality of a piece of software based on these attributes. So we're going to go over a few of them, which I think are maybe the most important ones. User experience is one of them. And when I'm talking about user experience here, I'm not talking about our end users, right? I'm talking about your experience as developers using libraries, using code that you wrote or somebody else wrote, right? We saw on the talk yesterday about C extensions that a big part of writing a library is sitting down and thinking of the API that library is going to have. And that's because you're trying to solve a problem for somebody else. You want that to be simple. You want people to have a good time using your stuff and solving problems on top of your software. And most people here, I'm thinking they're going to agree with this, because user experience is one of Ruby's strengths, right? Why do people use Ruby? Because it's a good experience, because it looks nice, because it does what you think it's going to do most of the time. So user experience is important, and it's a big deal, and we should all care for it. Reliability is pretty important, too. There's a reason so many people stopped using, say, image magic, because it can make your application blow up. And if your application blows up often, users are going to turn away from it. And so, for example, maybe Twitter has gotten away with being unreliable for a long time, but most of us are not doing Twitter. Most of us are doing applications or libraries that if they're unreliable, users are just going to go away from them and they're going to stop using it, or software is going to die because of lack of users. So it's also pretty important. On the same vein, like security, particularly in this day and age with DSA and the Snowden thing, we know that it's very important to keep data of your users safe. Maybe in a bad weekend of some really nasty person stealing all your users' data can just completely kill your application, completely make users never want to touch it again. So it's also a big deal. In the Ruby community, we pay a lot of attention to maintainability. That's why we have so many conventions and best practices around it. And that's really important. We do OK with it. We care about it. We have peer review. We have tests. We care about the readability of our code. So that's one we have pretty much covered, I think, fairly well. And then we have performance. It's easy to turn a blind eye to performance from our point of view as Ruby developers, because most of the time at the beginning of a lifecycle of an application or a gem, you can just throw resources at it, spin five more dinos, and it will perform. And while that is true, it's also true that maybe if what you're trying to do needs to happen fast, then you're not going to be able to get away with it. Or maybe if your application or your gem doesn't perform fast enough and you have to spin all these dinos or whatever to scale it, you're making your business not cost-effective. So it can also kill your application. So all these things are important. All these things matter and are really important to us. But let's not kill ourselves. They don't only matter to us because we're perfectionists. They matter to us because we're playing with live ammo. If we're releasing gem or we're doing an application, a lot of times there's a company behind that. There might be a startup or any sort of company. And your application failing, your software running out of users, might mean a company closing. It might mean people losing their jobs. And that is a pretty big deal. So it's a good thing that we are least aware of all of this stuff. And we actively pursue it. We actively try and make it better in our application. So when I was starting to think about giving the stock, writing it down, I wrote the abstract. I wrote, like, I sketched it out. And I showed it to a friend who is a very smart guy, very critical. And the first thing he told me is simplicity these days is kind of a buzzword. If you want to get your point across and you want to show why you think it's useful, then you need to give a proper definition for it. And he was right, of course. Like, how can I ever speak about this or get my point across if I can't even define it? But it turns out defining what something simple is, it's a lot trickier than what you might expect. And that's because it's so easy to let our perception of a problem alter how we assess how easy it is, like how simple it really is. And so, for example, if I show you this code that could be taken from any Rails application, raise your hand if you understand what's going on over here. OK, so most hands are raised, which makes sense. This is standard Rails code. But consider for a moment a person from outside of this conference, someone who might not even be a developer, right? Someone who doesn't get excited at a Raspberry Pi. If you show them this code, they're going to think it's witchcraft. Or maybe not witchcraft, but they're certainly not going to think it's simple. And why is that? That's because perception and all the stuff we know, all the preconception and all the previous knowledge that we have impacts a lot, or perception of how simple something is. And it's really hard to let go of that. And it's really hard to not be affected by it, right? But if you think about the stuff you need to know in order to understand this, you need to know computer programming. You need to be familiar with Ruby. You need to be familiar with Rails. And not only that, because familiarity, while you can sort of understand what's going on there, doesn't mean you actually really understand it in a way, right? How many of you have ever run this application, this command in your Rails application? So there's a lot less fewer hands. What this command does, it's going to output a list of all the rack middlewares that are mounted and active on your Rails application. So this is a tree of a brand new like Rails application and all the rack middlewares in it. All of these components are going to at least be partially executed whenever an HTTP request hits your Rails application. You can't even read that. You need, in order to make it sort of readable, you need to have the one, two, three, four, five slides, and there's still some of them out. So it's very tempting to call this code simple, but really it's not, right? Like there's so many things going on when this code is executed that you're not really seeing. So the complexity is still there. It's just that it's hidden. It's put away from your site. And so maybe you don't think about it too often because that's the intent that you don't have to deal with it, but that doesn't mean it's not there. What happens if something breaks? What happens is one of these components is introducing a bug in your system if one of these rack middlewares or any other thing in the Rails stack or any big system is messing with your HTTP request and you are suddenly forced to go through all of this to find a bug. You're not going to be happy. You're not going to have a good time. You're going to suffer a lot for it. You're not going to have a good experience. But we still need a definition, right? I've been jumping around it and I haven't been able to find any so far. So what I did is I cheated. Just as we can't easily define the quality of a piece of software, we also can't easily define how simple it is. So what I did is I asked myself this question, when do we care about complexity? Because maybe in a lot of cases we're not really going to care about it. If we're a nice citizen and if we follow through all the assumptions made by Rails or whatever other, I pick on Rails a lot because it's easy, but this really applies to any big system. The complexity in them matters when you have to confront it. When you are forced to deal with it, when you have to look under this rug, you've been sweeping all your debt into and find something and fixing it. So it matters when you need to understand what's going on. And so this is sort of the definition I liked the most, that something is simple when you're able to understand it quickly. And it's hard because in order to understand something you were going to need to have to keep the whole stack, the whole flow of the code in your mind. And this can be really hard to do if there's a lot of stuff going on in your application. One of the things I find that helps a lot to keep everything that's going on in your mind is to have a smaller stack, right? We had a really good example of this yesterday on Sarah May's talk about RSpec. It turns out that one day she found herself needing to change the behavior of before blocks in RSpec tests. And she went down this rabbit hole, right? Because she found out that in order to understand what was going on, she needed to read like how many, I don't even know how many lines of code. And that's because RSpec is huge. It has 13,000 lines of code, more or less. And of course, you don't need to understand all of it, but you're still going to need to read through quite a bit of it to understand a part. And I can guarantee that if she was, like maybe this wasn't even her choice, right? But if she was using an application, a gem like Minitest that has a fraction of the lines of codes or something like Qtest that it's even smaller, then that problem wouldn't have existed. It would have been much easier for her to fit all of the behavior of the gem in her mind and alter whatever part she wanted to alter. Now, you might be thinking, you know, well, it's all very nice. Simplicity sounds really good and minimalism sounds really good. But how does this really change anything? Because we also need to keep in mind that we don't, like simplicity for its own sake, it's meaningless, right? In the end, what we care about is the quality of the code because those attributes are the ones who can destroy your application, our lives, and make everything terrible. So a few months ago, when I was tweeting about this, I had a friend, like it's paraphrasing, but he was telling me, you know, like simple software isn't inherently good. Good software is good. And I agree with that. But I think a smaller second, simple software, makes it easier for it to be good, for it to have all these attributes. And we're going to go over a few examples of that. When I asked people why it was like the worst user experience that they've had with Ruby, everything, everyone pointed to net HTTP. I don't know if that's readable from there. Let's go over this line-by-line to see what's going on here. So in the first line, we're calling this constant URI that's not really explicit, but we're passing a string to it that it's a URL, and we're saving the output of that to a variable. Great. The second line is pretty self-explanatory. We're just creating a hash with some parameters that we're going to use in an HTTP request. Then on the third line, we're calling another external thing. Another, in the URI constant, we're calling another external method that we're not really sure what it does. But we know that the output of that, we need to save it into the query attribute of our magic URI variable. Great, okay, now, sorry. We're ready to use that, and we need to call yet another external module on net HTTP, getResponse, and pass this object to it. And okay, fair enough, now we're done. We can save that to a variable. We can check its body, and if we want to know if it was successful or not, we need to be aware of yet another constant, which is the class of the response net HTTP success. So I guess we're done, that makes sense in a way. I'm going to show another example of this, and it's written in Python. That doesn't mean I'm trolling, or I think Python is inherently better, but they have a great, they have a really good request library for HTTP that kind of shows what I'm aiming at here. This is how you do an HTTP request with that module. You first declare a dictionary with whatever payload you want to do, and then you take, you call request, which is a module that gets just one external thing you need to be aware of, and then you pass this stuff to it, and you can save that to a variable. And in order to know if a request was successful or not, you don't need to interact with yet another variable that you don't necessarily have to know about. It stands to reason that if you're doing HTTP requests, you know what the status codes are, and you can just use that to know if it was successful or not. So this is much more intuitive, and intuitive really is just another word for understandable. So I think you guys would agree with me that the second experience there was much better, like it's much better to just have to be aware of one external thing, and then being able to solve your problem with it. Now, reliability. This, let's agree, let's think or assume that if we add 100 features to whatever code base that we're going to introduce one bug to it, the figures are pretty much probably worse than this, but let's just, the numbers don't really matter. This is just like for statistical purposes. Let's say that this is true, so it stands to reason that statistically if you add more stuff to your application and to your code base, it's going to be more likely that you add bugs to it because there's more moving parts. There's more code. There's more opportunity to screw up, and there's more assumptions that you're making about your application that might not be entirely true or that might change in the future. And so, conversely, it stands to reason that if you have less features and you're doing less stuff, that you're statistically going to have less bugs. But this is just incidental, really. I don't think like this is the biggest impact a simple second have on the amount of bugs you enter and the reliability of your software. I think the really powerful part about this is that if you understand all the stack and all the flow of the code, then it's going to be way easier for you to spot the problems and to fix stuff, right? Because you're going to keep everything in your mind and then it's like much easier, it's going to be evident. Oh, right, of course, this is exploding because of this other thing that I already know that's happening. So that's how simplicity can impact the reliability of a system. I'm tempted to say that simple software tends to be more reliable because there's less opportunity to screw up. Now security, really, security vulnerabilities are a subset of bugs. We can pretty much reuse the same argument here because if we are adding more and more code, it's more likely that we're going to be adding a security vulnerability. And so if we have less code, then it's more probable to not do that. But again, this is not the powerful part. The powerful part is that if you know everything that's happening, it's going to be more apparent to you when there's a vulnerability or when there's a problem. So Rails is a really good example of this and it's not a good example of this because there are so many vulnerabilities popping up now and then. It's a good example of this because of the situation that Rails has a really smart core team. It has a lot of really smart people looking at it all the time. But it also has a lot of features and it has a lot of code and it has new code going into it every day. And so it doesn't really matter that there's so many of us using Rails and being able to spot those problems because there's no way anyone, no matter how smart they are, can keep up with that. And so this is a really good example of that. It's always going to be a catch up game. It's always going to be Cat and Mouse because with so many new features and so much new code, we're also always statistically going to be adding bugs and vulnerabilities. So maintainability is pretty straightforward too, how simplicity affects it because if you think about it, maintaining software is just a cycle of understanding what it does and then changing it, rewriting it. And so if we make the understanding part simpler and faster, then it's going to be much easier for us to maintain it. It's very straightforward to see how it impacts it. And the same thing with performance, right? If our library of a method or whatever is doing a certain amount of stuff, it's going to take some time to do it. But if it's going to start suddenly doing more and more and more things, it's going to need more time to do them. But again, this is not really the important part. This is just a byproduct of it. The important part about this is that bottlenecks are going to be apparent because a simple stack is going to make it easier for you to keep it all on your mind. So if you're aware of everything that's happening, it's going to be much faster for you to find bottlenecks just as it's easier for you to find bugs or vulnerabilities. And so I think all of these problems that we usually have most of the times that performance or maintainability or any of these things are suffering or degrading, I mean, it's good that we actively try to fix them, but I think that we're kind of just treating the symptoms because most of the times either of these suffer is because of complexity that maybe doesn't need to be there. And maybe those problems that we're struggling so hard to fix wouldn't even be a problem if we weren't trying to do that much stuff with our software. So what I propose is let's stop worrying so much about only the symptoms and about only directly performance and quality maintainability and all these things because if we focus on reducing the overall complexity of our systems, then all of these things are going to follow. All of these qualities are going to be positively impacted by us changing our frame of mind and reducing the complexity of our code base. Now, I know that when I talk about this I make it sound like it's really easy that we can just like flip a switch in our brains and suddenly, well, yeah, let's all write simple software and then everything will be fine. But it's not always as easy as that, right? Because our job as software developers is to solve problems, to add features. And every problem we're solving, every feature we're adding has a minimum intrinsic amount of complexity associated with them. That's just unavoidable, even if you're the best program in the world. But if you're solving a problem, then you are adding complexity to your code base. That's completely unavoidable. What thinking about software and about solving problems in a simple way has done for me personally is that it's made me even more aware that everything we do is a trade-off. And so when I get a pull request or when I'm thinking about adding a feature to a product, I don't only think about how useful that feature is. You still have to think about it because that's important. It can help you make a decision. But if I get a pull request that gives me a feature that maybe is useful for 10% of my users, but it doubles the amount of lines of code in my application, then I have more things to worry about because I have to think maybe this extra complexity is going to come and bite me in the future. Maybe it's going to make it harder for me to maintain it. It's going to introduce bugs. So it's not the only consideration anymore, is it? And it's not only that. It even becomes more subtle than that because as I was saying before, problems have a minimum amount of complexity that they add to your code base. But you start thinking about these problems that you're solving and you start thinking about, is it really worth solving that problem? Because maybe there's another sort of more subtle problem behind it that, and this is just a reflection of this other problem, that maybe it's actually smaller, you know, like more subtle and easier to solve. Maybe if I solve this, this won't even become a problem. And so this has made my work that much harder in a way. Because I have to think about all these things. But it has also impacted very positively on the stuff I produce. I found that I'm much happier with the design of my gems and of my applications when I start continuously paying attention to this. And so what I'm here to tell you today is not, you know, stop using Rails or stop using Ruby or, you know, use whatever stack. We can talk about that after the talk if you want about the stuff I consider to be, you know, like the stack I use. But that's not really the point, is it? My point is that the message I want to leave for you guys here is that you make sure that these choices become conscious. That you don't just, like, take a gem because it solves a problem and you add it to your code base without thinking about it. Because maybe that gem is going to have a lot of problems and maybe that gem is going to have a security vulnerability and you're going to be hacked and you're not going to understand what is going on because you have no idea what is happening behind the scenes. Thinking about it in this way and changing the way I work to reflect this has given me a lot more peace of mind because the more I understand about my software, the more I understand about everything that's going on, the more power I have over it. And so that's the message I want to leave for you guys today. I think this has helped me a lot and I think maybe it can help you guys too. Anyway, if you have strong feelings about this, either way, I'd love to talk to you after the conference and I'd love to have your feedback on it. That's all I have to say about that.