 I've been programming for a long time, something like 30 years now, and in that time I have written some good code, I've written some crappy code, and I've written a lot of, you know, okay, so-so, average code. But the software that I'm proudest of is the stuff that's reusable by other programmers, the libraries, maybe even one or two little frameworks, the reusable code. I don't know why, I guess some people are proudest of their really fun games, some people are proudest of awesome graphics demos, some people love a really compelling user interface. I like a library, and basically the purpose of this talk is to save you 30 years of beating your head against a brick wall, figuring out how to do this, and see if I can give you the essence in 30 minutes. So before I get right into the real stuff, I just want to take you all back in time to the early 90s, oh, sorry, that's the wrong early 90s, I meant this early 90s, or mid-90s, when there was a raft of books and magazine articles promising that we were on the brink of a new golden age, the dawn of a new era in programming, when the wonder technology of object-oriented programming would just magically make it so that we're all writing reusable, extensible code for free. If you don't remember the early 90s, you didn't miss much, because this was all snake oil. It's not true, object-oriented programming isn't magic, it isn't pixie dust, it does not miraculously give you the ability to write extensible, reusable code for free. In fact, if you drink the Kool-Aid for long enough, if you believe that with all your heart, despite the evidence, after 15 years, you will write something called Abstract Singleton Proxy Factory Bean, which came out of the Java community about six or eight years ago. If you don't understand what an Abstract Singleton Proxy Factory Bean is, that's okay, you just have to read the documentation, which clearly explains that it is a convenient proxy factory bean superclass for proxy factory beans that create only singletons. Obvious, right? This is why I don't speak at Java conferences, because they would lynch me. So anyway, I'm not here to bash object-oriented programming, I think classes are great, I think inheritance is even a useful tool if you use it carefully. I am merely here to point out that Fred Brooks was right in 1986, years and years before the object-oriented zealots started trying to sell their snake oil, Fred Brooks wrote a paper called No Silver Bullet, in which he claimed there are no silver bullets. There's no magic pixie dust, there's no super-wonder technology that is going to make programmers massively more productive. It just doesn't work that way. In other words, there's no Moore's law for software. Moore has this incredible capacity to double in transistor density every year and a half. It doesn't work that way for software, sorry folks, Fred Brooks was right 30 years ago. So how do you write reusable code? It's not free, there's no magic pixie dust, there's no wonder technology that will instantly make you able to write reusable code. Well, it's work, it's hard work, it requires forethought and attention to detail, but it's not magic. You can do it, anybody can do it. But first, before I start telling you how to do it, should you? Is it really important to write reusable code? In other words, should everything be a library or at least a potential library? No, absolutely not. There's nothing wrong with writing 10 lines or 1,000 lines of code that just solve this problem for this application today. In fact, that should be your default mode of operation, otherwise you will fall into a trap known as premature overgeneralization, which is about as bad as premature optimization. Maybe not as bad as premature optimization, but it's pretty bad. So don't fall into that trap. So, anyways, like I said, I've been programming for a while now. I've learned a few tricks, mostly the hard way, mostly by beating my head against a brick wall, repeatedly doing the wrong thing until I eventually realized, ooh, I'm doing the wrong thing. And then sometimes I figure out the right thing. Sometimes I have learned from others, like reading source code, reading books, but I've mostly learned this the hard way. So I hope I can save you a few decades of difficult experience. And I'm not some super genius. I have seen and watched super genius programmers at work. I wish I was one of them. I'm not. I do it the hard way, like most of us. And if I can do it, you can do it. So for this talk, this isn't like the nine universal principles. I probably could have come up with 12 or seven, but nine fits nicely on a slide. It also fits nicely in a 30-minute talk. So nine principles. Now, I'm not going to insult your intelligence by reading these principles to you one at a time. Instead, I'm going to insult your intelligence by reading through these individuals. I'm not actually going to. Anyway, so the first step to writing a reusable code is writing better code. There are lots of ways to write better code. I recommend these ways. Number one, read more code. This is something that's left out of most computer science education. It's not hugely emphasized in the post-education system of training programmers, although really, you can't work in the real world without reading other people's code. But do it, especially read good code. Don't just read the code written by that older dude down the hall at work. Maybe he's not the best programmer in the world. I get out there into the open source world and look at the good stuff. Look at the beautiful code and read it. Or look at this. There's a whole book about beautiful code, which is exactly dedicated to this principle. Learn from the masters. Write more code. Obviously, you get better at something by doing more of it. But it's not enough just to write more code, to just write thousands and thousands of lines of code. Go back, revisit it. Critique your own code ruthlessly. Refactor it mercilessly. Because if you critique it mercilessly, it will be much less painful when somebody else comes along to critique it because they won't have as much to complain about. Books, read more books. Good advice about life in general. In particular, read more books about programming. There are lots of good books about programming. I like these three, or at least what I haven't actually finished. Beautiful code. It's quite thick and chewy and demands a great deal of attention. But it's worth it. And the other two as well. And lots and lots of programming books out there. Just read some. And please, don't try to learn to program from Google. So a little more technical. Please, write more functions and fewer classes. Again, I'm not here to hate on object-oriented programming. It's a great trick. It's a good tool to have in your toolbox. You don't want it to be the only tool in your toolbox because a person with only one tool. Well, I hope you've heard the expression that if all you have is a hammer, everything looks like a nail. Not everything is a nail. In short, don't write a class when a function will do. On the other hand, if you have a class, the collection of related functions that all operate on some common state, well, that's a class even if you don't call it one. If you're writing in a language like Python that has special syntax for denoting that this collection of functions are a class by all means used that syntax. So here is a code smell that verges on anti-pattern. If you see something like this, a class with a single public method, that is a code smell. If that single method is the only method period, and it's not particularly long or complex, that is an anti-pattern. In particular, this thing loader with only a load method, and if there's like 10 or 20 or 30 lines there, there is no need for this to be a class. This is the sort of anti-pattern that you often see in people fleeing from more rigid and restrictive languages. It's not their fault. They've been trapped in a jail where there is no alternative. If you're programming in Java, this is all you can do. Kindly gently point out the error of their ways and say, you know, there is a better way. The better way, of course, is write a function. That's all it takes. It turns out that just simple standalone functions generally tend to be more reusable than classes. It's not an ironclad rule. It's not a carved in stone commandment handed down by God from the mountain. It's just something you notice after a couple decades of programming that if you've got a 20 line function buried in a class and you just want that 20 line function, it can be hard to reuse. It can be annoying. Why is this buried in this gigantic class? It doesn't need anything else in this class. It can be annoying. Yeah, so on the other hand, here's another anti. This is not as, well, maybe this is as bad an anti pattern. This is in my imaginary made up language, which is somewhere between Go and JavaScript. I think you get the idea. It's a bunch of functions. The functions all take two common arguments, one of which is probably stateful. A connection, maybe it's a connection to a database and HTTP server, who cares? It's probably stateful or long lived, something you don't want to throw away, whereas the article idea is just a common identity. They're not exactly the same, but hey, they're all common. They'll do stuff or tell you stuff about an article, whatever that is. Why is this a bunch of standalone functions? It should be this, a class called article store because this is a collection of functions that operate on some common state. Nothing wrong with classes, when they're the right solution to the problem. Third principle, so I'm old enough that when I was in high school and early undergraduate, Pascal was the language of the day. I see some smiles of recognition there. So we've moved on from Pascal. Pascal is in the past. There are better languages today, but I think we lost something when we switched away from Pascal because Pascal had a neat, not really a feature, it was more of a restriction, a deliberate unfeature, a deliberate restriction of the language, which is that it distinguishes between functions and procedures. I've honestly forgotten the exact particular rules because it's been like 25 years since I used Pascal, but in general, functions compute stuff, procedures do stuff. All the hot, sexy functional languages these days are extremely keen on this distinction. The mainstream imperative languages, including Python, don't care. In Python, in C, in Java, some functions compute and return something, some functions don't. They probably have side effects. And the language doesn't do anything to stop you from mixing side effects with return values, but you should. Your language doesn't care, but you should care. And the reason is reusability because a function, so the best kind of function at all is a pure function. A pure function depends only on its input arguments and the only way it can affect the outside world is through its return value. Pure functions are awesome. I love them. But in the real world, not everything can be a pure function. Lots of things have side effects. Nothing wrong with side effects. You can't put these pixels on the screen without side effects. The important thing is to segregate functions which compute stuff from other functions which have side effects. Please try to keep them separate. It's a rule of thumb that I follow. Every function either returns a value or has a side effect. And if I break that rule of thumb, I try to have a very good reason for doing so. So here's an anti-pattern that C programmers are notorious for. I could come up with an example in Python. It wouldn't operate on strings, of course, because strings in Python are immutable. But this is a C-like language where strings are mutable. You can iterate over the characters of a string and replace some of them. Like I'm going to uppercase all E's and replace them with uppercase E's. You could do the same thing on a list in Python, but I felt like mixing it up a bit and throwing in an imaginary programming language here. Now, there's nothing wrong. Well, personally, I'm not a purist about functional languages and mutable state. If you need to pass a mutable object to something and it mutates that object and doesn't give it back, well, that's just a side effect. Side effects happen and make sure you document them and don't mix them with return values, but side effects are okay. Immutable object, mutable state is okay. But please don't also return a value because now if somebody just wants to count the number of E's in this string, they're screwed. They can't access that functionality because you've clobbered their string. It's really quite annoying. A better way to do this is a function that takes a string and returns two values. Obviously, this is trivial in a language like Python or Go or lots of other languages that support multiple return values. It's a lot harder in C, but it's still doable. And also, obviously, it's slower. Sometimes you have to sacrifice performance in order to gain reusability. Generally, I prefer reuse unless I have a really good reason to prefer performance. So in this case, somebody's gonna, somebody, the person who writes this code is gonna have to allocate a new string, copy and modify into it, and also return an integer based on the computation over that string. That is more reusable and yes, it's slower. If you absolutely need performance, you break the rule of thumb. But personally, I try to follow that rule of thumb by default, keep your functions that return values segregated from your functions that have side effects. More libraries, please, fewer frameworks. If you're unclear on the distinction between a library and a framework, this is the best definition I've seen. A library is code that you call. You're in charge. You call the shots. You decide I'm going to use this bit of the library and that bit of the library and I don't care about the rest. The framework is code that calls you. There's a Yakov Smirnov in Soviet Russia joke lurking in there. I just couldn't think of one, sorry. The framework is in control. You just write some code and hope, you hope you beseech the framework gods. You submit your code to the framework and say, oh, mighty framework, please, won't you run my code? Please, please, please, in the way that I intend you to. And if you're lucky, it'll work and everything comes out hunky-dory and it's all peachy. Unless, of course, buried in that 4,000-line framework is a little 20-line function that does just exactly what you need right now today, but you can't get to it because it's buried deep in the guts of that framework and really, honestly, you know what you're going to do is you're going to copy that code out. It sucks. It's gross, yuck. That's not reused. That's copying. So the trouble with frameworks is typically they're all or nothing. You have to drink the Kool-Aid, sell your soul to the framework, and that hampers reuse. Often, sometimes. Libraries are easier to reuse even if they don't solve every problem. Now, I've been kind of railing a little bit against object-oriented programming, trying not to rail against side effects, railing a little bit against frameworks. None of these things are evil. Object-oriented programming is a fantastic trick to have in the toolbox. I would rather use a language with classes and objects than not. Side effects are unavoidable. Fundamentally, a computer is just a big box of numbers with some wires going in and some wires going out. Anytime you send a bit on one of the wires going out of the machine, like that screen there, that's a side effect. You can't compute without side effects no matter what the Haskell people tell you. Side effects are not evil. They're unavoidable, but please try to keep them segregated and at least be aware of the concept of pure functions. Try to write pure functions, and if you must break the rule of thumb, know why. If you have to do it for performance or if you're doing it because it's 20 lines of code instead of 50 lines, if you're doing it to avoid duplicating code, yeah, okay, have a good reason to do it. And finally, frameworks are not evil. Certain problem domains, I'm looking at you, web development, really call out to constrain the developer down a well-known path of the right way to do it. If you stray from the path, bad things happen, which is why there are so many frameworks for web development, because there are so many wrong ways to do it. Certain problem domains really call out for a framework. Many, many problem domains do not. You don't have to write a framework for everything. So, assuming you've accepted my advice to write a library, your library should not try to solve every problem. It should not try to be all things to all people. Avoid the temptation to satisfy every last feature request or even worse, every conceivable feature request. The reason for this is that the users of your library are your fellow programmers. If you leave a bit of functionality out of your library, who can fix that gap? Your fellow programmers, the users of your library. Now, if 90% of your users have to re-implement the same bit of functionality that you left out of your library, it might be time to add that. Save them the trouble. If 1% of your users need a particular feature, I'd leave it out. And the reason, the really important reason is not the fact that your users, your fellow programmers, are perfectly capable of implementing this code on their own, it's the converse of that, which is that if you've got bad, ill-advised code in your library, you know who can take it out? Nobody. Not your users, not you, because of backwards compatibility. Now, maybe in certain special circumstances for a library that's not very widely used, where you have control, like it's just used in your company and you have control over all the colors, you can go to them and make sure nobody's using this bad piece of code that you wanna remove. Maybe in those particular cases, you, the author or maintainer of the library can remove that code, but it's only you. Really, most of the time your users aren't gonna bother, frankly. It's just too much trouble. So, testing. If you provide me either a library or a framework, and there are no automated tests, that is, what's the nice word? Useless. I can't use that. I mean, it's 2015 unit tests have been mainstream for 15 years now, 15, 16, 17 years now, and there's just no excuse for not writing automated tests for a library these days. Sadly, even that's not enough. Automated tests are a necessary condition for reusable code. They are not a sufficient condition for reusable code. You know, it's another necessary but not sufficient condition, documentation. Unfortunately, the tools for writing documentation are not as good as the tools for writing tests, probably because programmers dislike writing documentation even more than we dislike writing tests. But, you give me a library with no documentation, you're wasting your time. It is useless code. It is not reusable. I can't read your mind. I can probably read your code if I'm really, really dedicated and absolutely keen and burning with a fiery passion to reuse this code, but if I'm not, I'm not gonna bother. Frankly, it's easier to just write it myself than to try to read your code. Give me documentation though, and I might just have a chance. By the way, the bare minimum documentation these days is inline reference documentation, doc strings in Python, Java doc in Java, go doc in go. Every language these days has some sort of syntax for inline reference documentation, which is repeat the bare minimum. Really, I need more than that. I need some sort of high level, descriptive narrative documentation. Probably for 90% of the libraries on the planet, a one page readme is absolutely fine. That's all I need. The really big Harry libraries, that's where you need some separate documentation that says, here's what you do, here's what this library could do for you, blah, blah, blah, blah, blah, blah, blah. But please, please, please, at least a readme. And of course, inline reference documentation, bare minimum. Finally, extensibility and reusability are not the same thing. If you were paying close attention back in the early 90s to those snake oil salesmen, promising a golden age of software development right around the corner, they promised both reusable and extensible software components. Give them credit, at least they recognized that those were two separate properties of a piece of software. Reusable doesn't mean extensible, extensible does not mean reusable. However, just right typing class foo at the top of your module does not make your code extensible any more than it makes your code reusable. It might be a start or it might not. Using objects and classes is largely orthogonal to whether your code is reusable or extensible. You have to design, you have to carefully think about reusability. And honestly, I think I've learned a thing or two about writing reusable code over the years into this talk. I do not know much about writing extensible code. If you do, you should be up here giving a talk next year. Please do, I'd love to go to that talk. I would love to learn how to write extensible code from somebody who's done it the hard way or the easy way better yet. So, wrapping up, there ain't no such thing as a free lunch. There is no silver, there are no silver bullets. There is no magic pixie dust. I'm afraid good software requires effort. And in this particular definition of good, good means reusable. Beware of pompous windbags, clueless pontificators, purveyors of snake oil, and above all, beware of people giving toxic conferences. And here are some links to the books that I like and the video that I like. And there's also the URL of these slides so that you can find these links later. Any questions?