Seven Ineffective Habits of Programmers - Lecture (Film, 55 minutes)
During the DevTernity Conference, Kevlin Henney delivered a memorable keynote that participants will not easily forget. He began with an introduction that highlighted programming habits, emphasizing that 'not all code is good'. Henney pointed out that there are numerous systematic habits that lead to bad code. In his talk, he outlined seven ineffective habits that programmers often harbor while humorously noting that despite their good intentions, they unwittingly create bothersome habits. Henney adeptly explained why this happens and how to prevent it.
The first issue he addressed was the problem of noise in the code, illustrated by a pertinent example. He delved into detail, showing how verbosity and unnecessary comments can hinder code understanding. He explained that code should be clear and speak for itself, not require tremendous effort to decipher its functionality. He also expressed skepticism regarding dependencies in code, using the infamous 'left pad' as an example.
Another key point in his presentation was about intent behind naming variables and creating functions. Henney highlighted that using long and complex names often leads to confusion and distraction. He provided examples where simple, clear terms could add greater meaning to the code. An added value was his reflection on how programmers frequently employ words that fail to convey their true intention and instead obscure the programmer's original thoughts.
Throughout his talk, Henney stressed the importance of employing domain language in writing code and adapting coding styles to meet team needs. He encouraged participants to think critically about existing standards and experiment with their own methods and practices to enhance the quality of the code generated. He emphasized the significance of tests within the software development process, where the key to success lies not only in reducing bugs but also in publishing intentions and project ideas reflected in the code.
In conclusion, Henney summed up his observations, emphasizing that as programmers, we should strive to write code that communicates its intentions directly, allowing us to spend less time determining the meaning of the code and more time coding meaningfully. The video was recorded on the DevTernity Conference channel and has thus far accumulated 25,315 views and 488 likes. Undoubtedly, his talk resonated strongly, prompting deep reflections on sound coding practices.
Toggle timeline summary
-
Introduction and setup for the keynote.
-
Plans for a brief keynote before the beer party.
-
Acknowledges delay due to beer not being ready.
-
Shifts focus to discussing coding habits.
-
Introduces the idea of effective coding practices.
-
Clarifies the topic is about coding habits specifically.
-
Shares personal interests and credentials.
-
Comments on systematic habits leading to bad code.
-
Notes interest in linguistics and meaning.
-
Explains the definition of 'code' and its meanings.
-
Start discussing habits, defining them as regular practices.
-
Describes the benefits and dangers of habits.
-
Discusses imitation in human behavior.
-
Mentions programming culture and common habits.
-
Introduces seven ineffective coding habits.
-
Discusses 'noisy code' as a major coding problem.
-
Compares Shakespeare's complex language to verbose code.
-
Introduces the concept of simplifying code.
-
Notes how comments can add noise and confusion to code.
-
Stresses the importance of clear communication in code.
-
Emphasizes the importance of spacing and readability in code.
-
Discusses the importance of alignment in coding style.
-
Introduces linguistic morphology and its relevance to coding.
-
Explains the importance of using meaningful names in code.
-
Concludes with the purpose of tests as a clear specification.
-
Wraps up the talk by summarizing the importance of code clarity.
Transcription
I think it's time to get started because I've realised that there's, it's only me standing between you and the beer party. Yay! So, I'm going to do a five minute keynote and then we're good, yeah? Right, had a good day? Oh man, you're going to be so disappointed. Okay, it's going to be an order of magnitude longer than that, sorry, because they haven't got the beer yet. They're still working on it. So, at the moment, I'm going to scare you. This is a picture of hardware, okay? Actually, it's a picture taken by my son and we're not here to talk about hardware, we're going to layer over it. We're going to talk about code. We're going to talk about the fact that not all code is good and it turns out there are a number of systematic habits that people produce. I could have made this list 70 long, but I chose seven because that's a magic number in these things, seven effective habits. I had to clarify, it's quite a long title, my original suggestion when I mentioned it to my wife, I said, seven ineffective habits of many programmers and she says, oh, I can give you some. And I said, okay, let's be a little more specific, let's talk about coding habits, oh, right. But if you want to make some rude remarks about coding habits and things like that, that's my Twitter handle, it's quite easy to find. So something about me, Kevlin Henney, I have an interest in patterns, obviously unqualified to talk about architecture because I have a couple of books with the word architecture on the title. So I'll be talking about that tomorrow, but today I'm going to focus more on the programmer level. This is a book that I edited a few years back. I've always had an interest in effective habits and things that work versus things that don't. It turns out that programmers are not generally stupid and evil, we don't produce bad code, people don't get together in meetings and say, you know what, you know what this system really needs, it needs a class 10,000 lines long, absolutely, let's go do it, you know, that's not how people work. It's normally systematic habits that create a system. Now something else I'm very interested in is language, linguistics, words, things like that, meaning. I run a page on Facebook called Word Friday if you happen to be interested in the same thing. Obviously another thing I'm interested in is taking pictures of books, I think I've got quite good at that. So let's actually explore meaning. I like to collect dictionaries, so let's see what the dictionaries have to say about the word code, because this is something we should all be familiar with. It's a noun, not surprisingly, it's a set of instructions for a computer, okay, that's the kind of really low level stuff, a computer program or a portion thereof, okay, this is pretty good. This is the stuff we're familiar with, but if we push a little bit further, a system of words, figures or symbols used to represent others, especially for the purposes of secrecy. Ah, that's the other meaning, that's the other meaning, right. So sometimes when we say that something is in code, that's not good. It also means something else, socially, culturally, a set of conventions or principles governing behavior or activity, a code of practice. And so let's talk about behavior, let's talk about habits. So what's a habit? Well, the obvious thing, a settled or regular tendency or practice, it's a habit. Habits are good things in this sense. There's this idea that you reach a level of automation, you don't have to worry about everything, some of it's kind of programmed into your spine, you've got this idea of an acquired mode of behavior that has become nearly or completely involuntary. So that's the upside, it's a relatively low energy state, you don't have to spend all of your time thinking about all of the details. But that's also the blind spot, that's also the danger, you don't see it, if it's a habit, you don't see it. We may not even notice where it came from. We pick up habits because we are imitation machines. That's one of the great things about humans, we copy, we look at other people and we see their behaviors and we look at their successful behaviors and we say, yeah, let's do that. And we copy and that's how civilization spreads. It's also how fashion spreads and XML and JavaScript and a whole bunch of other things which I'd rather not talk about but we're going to talk about some of them. A less common meaning, bodily condition or constitution, yeah, this is always a worry to programmers and a costume characteristic of a calling rank or a function, it actually means clothing. So we clothe ourselves in our habits, there's kind of a deeper meaning there. So what about the role, this idea of a calling, a rank or a function, what about roles? So just a quick check, are you familiar with this form of user stories? As some kind of role, I want some kind of feature so that I get some kind of benefit. And normally we apply this to customers, it's their voice. But I think the thing that we haven't got very good at is determining our own requirements. If you are following a coding practice or you are using tools or you're working within an architecture, what are your requirements from that? In other words, as a programmer, what do you want from your architecture? What do you want from your coding conventions? What do you want from all of these things? People are very bad at answering that. And so I hope to try and answer that a little bit by exploring seven ineffective habits. So the problem is when you ask people what they want, they say, well, as a programmer, I want effective coding habits. Why? So that I can be less ineffective? No, no, you need to be more positive, so I can be more effective. No, that's not what I mean, that's really very vague. So let's offer you something slightly better. So that I can spend less time determining the meaning of code. How much time do you spend trying to work out what something means? Either to add to it, or to change it, or even on a good day, remove it. Or to steer clear of it, because you're scared of it. So how much time do we spend doing that? And more time coding meaningfully, so that your code actually has value and that it has meaning. But I want effective coding habits is really vague. So let's explore and try and answer this question. So I'm going to start off with the first one. Noisy code. This is one of the biggest problems in a large code base. How much signal to noise ratio is there? And we use signal to noise ratio, it's a classic engineering term, it's a measure of use in science and engineering that compares the level of a desired signal to the level of background noise. But more generally, from our point of view, we use it informally to refer to the ratio of useful information to false or irrelevant data in a conversation or exchange. You're having a communication. When you write code, you are communicating, not just to the computer, you are communicating your thoughts aloud, or you're communicating your thoughts to other people, and even to yourself. So how much signal to noise ratio is there? And we adopt a lot of conventions, and we end up with noisy practices. So let's have a look at a kind of... This is a... Turns out Shakespeare was interested in code, okay, and it's up there, to be or not to be. That's a logical statement. He's trying to figure out if an object is there or not, okay? It's a deep existential question. And this is one of the famous soliloquies, the most famous soliloquy, perhaps, from Hamlet. Okay, so that's 17th century English. I think we need to bring this up to date, 21st century English. This is from a book by Tom Burton called Long Words Bother Me. He tried translating that soliloquy into business or marketing speak, continuing existence or cessation of existence. Those are the scenarios. Is it more... You fall asleep by the end. And there's a lot of code that is written like this, where people are going, I'll just add more words to make it clearer. I'll just put more words. I'll space that expression out over more things. So here's an example. Ha, yeah, left pad. A handful of lines of code. It's not even very good code. So this is from this. So there's a big question. Why is everybody depending on not only a piece of code that any programmer can use, but that's not particularly well-written? Yeah? I mean, there's a... You know, I had a go at rewriting it and came up with that. This has an important property that the previous one doesn't. It works. I'll come back to that later. So sources of noise. One of them is just verbose coding style. Really clumsy, spelling it out, not really thinking about what you've expressed. And we can't be perfect, but the problem that we have is that often we go with the first thing that comes to mind. And life has taught us one thing. The first thing you think is rarely the right thing. It's rarely the best thing. You need to go back and change it. Once you understand what you've created, then you can revise it. But there's something else as well. There's a lot of noise in a lot of code. People say, oh, yeah, we're busy reusing things. The O'Reilly book cover series is wonderful. Taking on needless dependencies. How many code bases are just noise of dependencies? And if you actually look through it, it's mostly noise. And they're for trivial little things. Yeah, let's depend on that for ten lines of code. Why? Code written by some stranger on the internet is always perfect. Yeah. And if we think that's bad, the current maintained version of LeftPad looks like this. At this point, I'd like everybody to, you know, do an internal face palm. This is not better. It's got a clever little optimization that is not an optimization. Yeah, love those. And it's got lots of really helpful comments. In fact, sorry, it's got two helpful optimizations that are not optimizations. I forgot the other one. It could be a work of art. Not sure. But one of the problems it suffers from is comments. Comments add so much noise to code. So much noise, we have to cut through it. I remember early experiences with this that I actually ended up writing a tool just to delete all the comments from a code base so that I could see what was going on. These days, people just fold them away. Or change the background color or change the comment color to the same as the background color so they're not distracted. Okay, so this one comes from Oracle, originally Sun. Look at that. What a copyright statement. It's astonishing. Outstanding. And what's this for? Oh, hello world. Yeah, let's just get rid of all the comment and then we go all the way down here. It's not even just hello world, it's hello world app, just to make it sound a little more exciting, yeah? And we've got another comment here. Display the string, just in case you were struggling with this one. This is pure noise, you know? If you put this on a... You know, if you pull this up in a typical editor, you're going like, all I see is comment. Where's the code? And you look at the scroll bar on the right, you think there's no code here because I'm seeing all comment. There's only a little bit left over. Let's scroll down and oh. But I like to observe the fact that all of this effort, all of this effort, and they missed one thing. They got one thing wrong. The one thing they could have actually spent their effort on, punctuation, ladies and gentlemen. There should be a comma after the hello. If you're not sure why, the standard way to check this is, let's eat, grandma, and let's eat, grandma. Okay? So, good punctuation saves lives. Keep that in mind if you learn nothing else today. So way back when I was originally learning C, this is from the Notes on Programming in C guide by Rob Pike, one of the Unix demigods responsible for creating the Go language. He wrote this in 1989, and his section on comments is rather good. A delicate matter requiring taste and judgment. I tend to err on the side of eliminating comments for several reasons. First, if the code is clear and uses good type names and variable names, it should explain itself. Second, comments aren't checked by the compiler. So there's always this interesting thing. Who are comments for? The compiler doesn't read them, and programmers don't read them. Who's left? Third, the issue of typography. Comments clutter code. But the best bit, the best bit of this paper is this. And in particular, don't laugh now. Wait until you see it in real life. So I laughed. Five years later, I saw it in code. It was just one of those, I don't believe this, I really thought he was joking. So I made this comment, this is probably my most retweeted observation. We've got an issue here. If we're going to get people, we're going to say, you need to write comments because your code is not clear. Who's the person writing the comments? The person that wrote the unclear code. So they're going to use exactly the same thinking process and just write it in natural language. They're going to explain it using the same thought process that led to the code. So be careful. You need somebody else involved. You want to raise the meaning of the code. Now if I'm going to talk about lots of little things, let's talk about the little things. The things you're not supposed to talk about, like spacing. Oh yeah, we talked about comments, now I'm going to talk about spacing. Oh, but you can't do that, Kathleen. It's a religious matter. It's a personal preference. It's no, bollocks. That's a technical term. Okay, so I joked about this, yeah? I said we write it like this. Actually quite a lot of programmers write it like this. People have some really strange coding styles, and they often pick them up without thinking from their colleagues from their tooling, okay? They're driven by their IDE. Instead of them driving the IDE, it's the other way around. So what we've got to do is take a step back and start thinking slightly more critically. So to get you thinking critically, I'm going to offer you a gray rectangle. What's this represent? This is how many programmers lay out their code, unless they're writing 10,000 line classes, in which case it goes all the way to the center of the earth. But what is of interest is that line. That line is column 80. Yeah, I know. People are going like, yeah, but that's okay. You know, I've got an HD screen, triple-headed workstation, or I've got an IMAX resolution. It's fine. That's great. That's beautiful. That's wonderful. There's only one problem. It turns out, one of the greatest discoveries of recent years, software developers are in fact human. I know. I mean, it came as a shock to me, but that turns out to mean that we have the same cognitive limitations and the same biological limitations as all other human beings, because if you think I'm being really unreasonable with column 80, let me show you how people read. Oh. Oh, that's worse. Just look at any website and look for the really wide columns. No, you won't find them, because people put them in columns. Magazine layout has known this for a couple of centuries. This is how people read. So whilst I'm not suggesting that you're going to put 40 or 50 or 60 columns as your limit, I'm going to suggest that by the time you hit triple digits and you have to move your head to get to the end of the line and you discover that the end of the line actually has a different climate to the beginning of the line, then I'm going to suggest the line is too long. One of the longest lines I encountered recently was in a code base that actually, surprisingly enough, mostly respected the 80-column limit, but when it broke it, it really broke it. It did it properly. It was kind of like if you watch the screen, it was kind of like a bit and go off the screen. How far does that go? I don't know. How far does that go? So we put on our boots, we put on our outdoor gear, and we went, and we found ourselves out at column 360. I was almost disappointed that the developer had not added an extra five characters so that it was 365. We could have one column for every day of the year. So there's a concept here, and I'm going to take from this blog that's all about clean design, but it's not about what we normally think of as clean code. This is actually about visual design, and the observation was made, and what I find interesting is that the author, Daniel Higginbotham, got back in touch with me when he realized I'd used his quotes about code, and he said, that's really interesting because I think the same way on this one, because he makes this point. To answer the question, what is clean design, most succinctly, a clean design is one that supports visual thinking. We do support, we have a visual thinking approach. That's why we lay things out in a particular way. We line things up to offer meaning. We separate things out to offer separation in a visual form. We emphasize things. So people can meet their informational needs with a minimum of conscious effort. You see here, he's actually really answering the question of what do we want? What are our requirements from a coding layout? Coding layout is not arbitrary. I'm not going to tell you there's one true way to lay out your code. Obviously it's constrained by your language's rules, but I'm going to say that you want to work out what are my informational needs, and how can I meet those, rather than, oh, what do I like doing? Most developers answer objective questions with, I prefer doing this, but that's not really the issue. You convey information by the way you arrange a design's elements in relation to each other. This information is understood immediately, if not consciously, by the people viewing your designs. This is great if the visual relationships are obvious and accurate, but if they're not, your audience is going to get confused. You have to examine your work carefully, going back and forth between the different parts to make sure they understand. Now, there are some people who are going like, well, yes, they should examine my work carefully. Yeah, it was hard to do, should be hard to read. So, you know, I want them to examine my work. But let's understand this idea of informational needs. So let's see how people actually end up going around laying out things like method headers. Okay, so here's a method. I think there's actually a Java coding guideline, and this is more prevalent in Java than elsewhere. But don't think if you're not working with Java, you think, oh, that's me off the hook. You're not. Because it's everywhere. But Java, it's particularly popular. And it makes me think that actually somewhere there is a coding guideline that says, make sure that your arguments, one is off the right-hand side of the screen and the rest line up on the left. I think that is in there. It's probably rule zero, and that's why I keep missing it. So what's the problem here? Well, the problem here is that where is our argument list? Where are the parameters? You can't point at it with one finger. You have to point in two places. It's... Oh, okay, well, hang on, you've just turned one thing, one unified concept, a list of parameters into two things. How is that supporting anybody's information needs? So yeah, this sucks. Now, I don't care if you do it like this, or you do it like this, or you do it by some other variation. See, I'm not favoring one approach. I just want to say, what are the properties of your style that we should have? If you have a list of parameters, then it should look like a thing, not two things, not three things. It should be together. However, the one that I'm going to caution against is this one, because this is also surprisingly popular. Now, this has a number of interesting effects. I mean, visually, it looks like a mess if you do that, and if you just scroll through your file, it bounces around. Your lines of alignment bounce around. But actually, there's something more problematic here. The issue we see here... Let's try this or that. I don't care. Or other variations that satisfy the same constraint. What you end up with is, let me think, what do we do? We rename things, because the first idea we had was never always the best. So we come back and we rename it. So when we rename, we lose the alignment. That easy. That is how... That is one of the simplest ways of creating a legacy coding style. And again, every code base I've ever encountered that follows, that's the top style, follows the top style. It is always inconsistent. Now, I had one person come up to me after I presented this observation. It's what I call unsustainable spacing, because you can't sustain it. And he said, I think you're wrong, Kevlin, and I'm going to offer that to you this evening. You may think I'm wrong on some of these things. And that's okay. You're wrong, but it might take you a while to see it, okay? I'm generous like that. We've got until Christmas. The thing is that we get very attached, personally attached to a style. Maybe we like how it looks. That's great. But this guy, very, very adamant. He was very, very concerned. He said, no, I like this style, and I think it's right, okay? But what do you do when you do name refactoring? Oh, I go around all the points in the code that were refactored and just check they still line up. And I said, you might have missed the point of refactoring tools. That's quite a high-maintenance approach. That takes a lot of effort. But most importantly, don't think about yourself. Think about the team. So I asked him, what do your colleagues do? At that point, he gave me a very bad expression. They don't do that. There you go. That's why it doesn't work. Now, of course, there are exceptions. In some programming language cultures, it's very standard to line up by parentheses. And all the tooling supports it. Then fine. Go with it. Lisp is one such culture. But unless everybody is using the same tools on a team, then you can't guarantee that this is sustainable, in which case you've created an unsustainable coding style. It's quite empirical. You can check it in any code base. So yeah. Let's not do that. There's another point here about alignment that I want to make. So visually, we've got, let me think, less than 10 lines of code. And we've got one point of alignment. Remember, alignment is where we're trying to give somebody, we're trying to attract somebody's attention. Alignment attracts people's attention. You're giving it meaning. So we've got one point of alignment, or one axis of alignment. We've got two axes of alignment. Ah, we've got three axes of alignment. Four, five, six. Wow. Basically, that is pretty much, we're going for almost just under one per line. That's a very busy, that is visually intensely busy. It's like, well, how else could we do this? Well, we could try this. Problem is, and this becomes more obvious, and now we understand why people do the pushed out to the right style, because they've got this. We've got three axes of alignment. The problem is, if we block this out and just look at all the non-white space, or the non-punctuation characters, it's very difficult to see where the parameter list stops and the body starts. Okay, there's a couple of variations. We can try further indenting, or we can try moving the curly brace to the left. So therefore, what I have just told you, in case you were wondering, yes, there is a way to determine the correct way to align your braces, objectively. Of course, if it conflicts with your language, then don't do it, because I think compiled code is better, but it turns out there's actually a very simple way to determine visually and by maintenance whether or not a particular alignment model works. We're not very good at this empirical approach sometimes. Okay, so yeah, this is visually simple. Now, another thing, this is a notoriously unreadable book. The first section is written in English. All the remaining sections are written in sigma calculus. If you suffer from sleep problems, this is great, but what I'm really getting to here is Lego, Lego naming. Okay, so I said I'm interested in language. Let's talk about linguistic morphology. So if you walk away from this with one extra piece of knowledge, linguistic morphology. Slip that into a conversation tomorrow. Agglutination is a process in linguistic morphology derivation in which complex words are formed by stringing together morphemes, each with a single grammatical or semantic meaning. Languages that use agglutination widely are called agglutinative languages. Okay, that seems pretty decent. So do we have some examples? Kind of English is kind of a bit agglutinative, not as much as it would have been a thousand years ago, but it's kind of agglutinative. And this is a word in English that means fear of long words. Interestingly, if you look at it, it's pretty much all Greek, as indeed is this, Greek and Latin. This is the longest word in the English language, and it was designed to be the longest word in the English language, and it refers to a lung condition that you can get either by breathing in volcanic ash or ground stone. So it's not really a proper word. For that, you have to go to Norway. And that's a traffic regulation, and it tells us where we find a number of long words because bureaucracy has this habit of adding bits together, like Lego. Of course, it's not Norwegian that's going to win this particular contest on bureaucracy. It's going to be German, isn't it? This is, or was, the longest word in German. It was basically retired as a word about four years ago. It refers to an EU meatpacking directive that is no longer in force. So there's an interesting question, is it still a word if the law is no longer in force? I love the fact that it turns out the abbreviation of this word is 12 letters long. But it turns out that to be a truly agglutinative language, you have to go a little further east. This is the longest word in Turkish. This was designed to be the longest word in Turkish. It means something poetic and profound, and I can't tell you what it is. So what's this got to do with code? Oh, it's got to do with code. Yeah, you ever stick the name controller on the end of something? You ever stick the word abstract in front of something? You ever use the word manager? Did you ever have an abstract manager? Controller, proxy, factory, singleton. Yeah, this is, I love this example. It came from a cartoon at the beginning of last year, Bonkers World. The world is seen by an object or a device. It's a computer. It's a computer. It's a computer. It's a computer. It's a computer. The world is seen by an object-oriented programmer. Privacy manager, delegate. Entertainment provider, singleton. One of my favorites, multi-butt supporter. Yeah. The whole point of object orientation is you're supposed to be able to name the thing. What is that thing? Well, yeah, I mean that thing over there. You mean the Venetian blind? The door? It even has OO in it. That's got to be the right answer. The only one that looks even remotely like its previous form, television remote control, is because that's close to the term we use in the real world. But we end up hiding behind these words. We end up gluing all these words together. And people often think, well, I'm adding meaning. You're not adding meaning. You're diluting it. You're watering it down. You're taking meaning and then hiding behind an ever-growing list of words. If we wonder why it is the code over the last decade or two has crept towards the right-hand side of the screen, it's not just because the right-hand side of the screen has been going further away. It's because we've been racing to catch up and overtake it. 20 years ago, I used to try and convince people that they needed to use longer names. Because back in the 1990s, some people were still in the shadow of the great vowel shortage. Back in the 1970s and 80s, there was some kind of rationing on vowels. You couldn't use all the letters on your keyboard. I mean, that's the only explanation I can find. So, I want to connect to the server. You have to rip out all the vowels and pass them around to your colleagues so they could use them occasionally. But now we don't need to do that. Unfortunately, we've gone all the way to the other extreme. I now convince people, shorter, shorter. This is not a new trend. I said 20 years ago. This book was written 20 years ago. Small Talk Best Practice Patterns by Kent Beck, one of the best patterns books and indeed best small talk books I've ever encountered. He made the observation back then, people will be using the words you choose in their conversation for the next 20 years. Well, here we are 20 years later. You want to be sure you do it right. Unfortunately, many people get all formal. Just calling it what it is isn't enough. So, here's one from some code I reviewed at a client and we had this conversation about what's going on here. You've got a hierarchy and there are objects in it and it's a condition checker hierarchy. I have no idea what a checker is. We don't have them in the real world. And check condition, we're really telling the machine what to do. You need to do this, do that. There's an enduring idea here, a repeating idea of object-oriented assembler. We're going to check the condition because it's a condition checker. I think the readers got the message by now. And I said well, hang on, what is in the condition checker hierarchy and they described it and I said wait a minute, what you've got is a rule body, a body of rules. Each rule is a piece of code. So you mean it's a condition and what you're actually checking is whether or not the condition is true. And they said yes. And I said well that's what we say. Oh, but don't we need a longer name? No, it's a condition. That is what it is. There is no such thing in the real world as a condition checker. That's bureaucracy. Because you will end up with a condition checker manager if you're not careful. Oh yeah, we know where this goes. There will be a condition manager checker manager factory. And we only need one of those so yeah, you know where this is going. So, yeah. Hold back. So as Ken observes, they have to tack on flowery computer science, the impressive sounding but ultimately meaningless word like object. Number of times I see object at the end of a class name. Just in case you weren't clear. Okay. And thing. Yes, I've seen that. Best one I've ever seen is stuff. Component part, manager, entity or item. So, this is not a new trend but it's now more pervasive, it's now more universal. Oh, what else do we stick on the end of words? Yeah, this is the bit where I get thrown out of the building. I've already insulted your spacing style and now okay, so let's take a walk. .NET does this, Java does it and a number of other languages do it. A number of other libraries do it. How do I know that thing is an exception? It might not be clear to the Yeah, now you're right. They might not be able to work out that it's an exception because it appears in a throws clause. They might not be able to work out that it's an exception because it appears in a catch clause. Yeah, you're right. They're really gonna struggle. Let's put the word exception on the end. That'll really help. I'm always surprised people held back and didn't go the whole distance and say, you know, we're gonna put non-exception on the end of every other class. Just to be really really clear, okay? Because you might not understand, okay? Let's see what happens with these if I take the word exception off. Oh, those are actually quite good names. I mean, that's an access violation. Oh, that's what you were hiding. By putting on all this extra stuff, you're actually hiding the meaning. It's an access violation. The argument is out of range and somebody might go yes, but how do I know this is an exception? Really? Bad image format. Oh, that could be a good thing. No, really. The word bad. Very, very big clue. Cannot unload app domain. I wonder if that could represent something bad. Entry point not found because always not found means good. No. Index out of range. Hmm, exception or not? Tricky. Now, you might say, well, okay. Let's look at some other ones. What happens if we take these and we drop the exception suffix off? Yeah, there we go. Look. Meaningless. So, clearly, dropping exception doesn't work. No, no, no, no, no. What we've done by dropping the word exception is revealed how bad the names are. It's an arithmetic exception. What does that mean? It's something to do with arithmetic. Well, you could have just said bad thing happened and we would have been none the wiser. Format. What does that mean? I don't know. Rank. Type access. Even null reference. There's nothing wrong with a null reference. Well, we can have the big debate whether or not you should have them at all. But, if you're going to have them, there's nothing wrong with having one. I mean, I passed null references around and they didn't blow the world up. When did they blow the world up? They only blow the world up when they're dereferenced. Oh. So, in other words, what we've done is we've revealed the failure of the existing names. It's not that there's an argument. It's that it's invalid. It's not that there's a null reference. It's that it's been dereferenced. So, what we're doing is we're trying to reveal the actual intent. By saying it's an exception, when you can actually see that it's an exception because it inherits from an exception, it exists in a throws clause, and it's caught in a catch clause, we're not adding information. We're just adding noise. Best advice? Most self-referential advice I've ever come across on this? Omit needless words. No more words needed. Okay. So, there's a problem of under-abstraction that plagues many codebases. Under-abstraction, not enough abstraction. Sometimes people fear that they might over-abstract, and that certainly happens. But under-abstraction is more common. So, this is a shot from, this is a tag cloud, and an article by Felipe Calzado from a few years back, and I found this article very inspiring. It was a blog post I found very inspiring, and I kind of communicated the advice around a number of people. Because what he's done is he's trying to find out the semantic content of a codebase using a very simplistic, but ultimately profound mechanism. What words is it using? Simple as that. Take the code, lose the case, strip out the comments, strip out the string literals, put it into a tag cloud generator, and see what comes out. And this is clearly a Java codebase, based on the words like import and stuff like that. But what is most interesting is the dominant type. This is a stringly type system. String. If we look a little further, we might find oh, there's int, an integer, and list. So, what is this system about? Well, this system is mostly about strings with some lists and a few integers. Great. That's the kind of conversation you want to have in an interview. So, what kinds of systems have you worked on? I've worked on systems with strings and lists, and we sometimes use integers. Oh, okay. Great. So, can I ask you some questions? Yeah, sure, fire away. You know, if you want to work here, we can tell you everything. So, what kind of systems do you build? Funnily enough, systems with strings and lists and integers. Oh, cool. Oh, yeah, my skills match that. Oh, come on. So, Philippe Casal does this with a different system. Now, I can't tell you exactly what this system does, but once you get past the language infrastructure, there's a printing device, there's pictures, there's paper, there's products. This is a far richer vocabulary. Sure, a string is still there, but it's a lot smaller. The class keyword is also larger. In other words, what you're trying to do here is communicate your intent. I mean, sure, we know that it's all strings, or we know that it's bits and bytes by the time you hit the lowest level, but you don't have to do the compiling. Often, developers have a mental model up here, but somewhere between here and here, it gets compiled down into object-oriented assembler. Oh, yeah, it's strings with gets and sets and creates and checks. We see this in other places as well. This is from 97 Things Every Programmer Should Know. This is a piece by Dan North. And this is a piece. It's code in the language of the domain, and he refers to this. He sort of says, OK, here we've got an example. What does this if statement do? What is the purpose, the intent of this if statement? Now, if you look at the names, the names are all descriptive. There's no abbreviations in those names except real-world abbreviations. ID. Everything is in its full form. Portfolio, trader, contains key. It's all there. Some people might think maybe we should put a comment here. No. What would be in the comment? What we've got here is a failure to capitalize and understand the basic meaning. We've reduced it to primitives. That's what we're saying. Can this trader view this portfolio? It's not obvious that they're saying that, but that code is now inside the canView method. Extract method is a really underused refactoring. The idea of adding meaning to the code by abstracting. Quite literally, abstraction means removal. So, in case you were wondering, yeah, Singleton. I'm not going to talk about Singleton except to say that Singleton is a single malt whiskey. That's my one. This kind of Singleton will improve the quality of your code. Because if you have a little drink of it, you relax. You pause. You reflect on the nature of the universe, the nature of code, and the fact that maybe you won't put that stupid great global variable in today. And you'll move on and your code will be better. The problem here, unencapsulated state. It's the ultimate unencapsulated state, but there are lots of forms of unencapsulated state. One of the most common is, hey, let's make our data public. That's a very popular one. So let's understand the classic bank account example that people like to illustrate object systems with. And yeah, I've seen code that looks exactly like this, and I've even seen it in training courses. Let's make accounts balance. Let's make it public. Do you know that would be fantastic? You know, if you know a bank that does this, I want to bank with them. Ah, I think I'm going to set my balance to something a bit bigger. And some people will go, oh, you know what? I'm going to do this in .NET. I'm going to use auto properties. See? It's much better than having public fields. Not really. Only that much better. Not much better. We can still go ahead and freely get and set the balance. And then we have the challenge of what happens if the balance is actually not a directly held value? What happens if we've got a history of transactions? What happens if we're dealing with something that is cached and calculated? What do we do then? Well, then we have to provide logic, and we have to do a lot of very clever logic, because also when you set, it turns out you can't set it to something arbitrary. It turns out setting it to something negative may not be in the bank's rules. So it turns out you have one of the hardest jobs here. The setter method will become a monster. So let's talk about monsters. Let's talk about vampires. Let me take you back in time to the 1980s. Has anybody seen The Lost Boys? Okay, there's a few people. Yeah, you're not young. I can see you. Okay, so here's the, again, I want you to walk away from this hall with useful advice, information that will keep you alive. How do you defend yourself against vampires? Yeah, Chris got the right answer. It's the one that people always forget. Everybody remembers the idea of sprinkle them with holy water, eat lots of garlic, stand on holy ground, kill them with a stake through their heart. Yeah, that's very close combat. I'm not going to guarantee you will survive that. But the one everybody forgets is don't invite them in. They're not allowed to cross in, unless it's a public space, they're not allowed to cross into a private residence, a home. The advice is there. It renders you powerless. This is what we do whenever people go, just have this piece of data that is actually supposed to be private. What I'll do is I'll make it public. Oh, I'll wrap it lightly as a property. I will give you the collection that is internal to my object. Collections are one of the most obvious cases where this happens. There's loads of examples like this. We reveal the underlying object model, and when we come to change it, we have a major piece of work on our hands. It's as simple as that. Try and code in the language of the domain. The language of the domain is not about setting and getting balances. It's about withdrawing and depositing money. Now, that whole get a set a thing sets us up for the next thing. I mean, I could say it's the same thing, but it's so common that I really want to make a point about it. So, like I said, I'm kind of into language and words. So I've got a copy of the Oxford English Dictionary on my laptop. I think the full printed version, I think they've stopped doing the full printed version because it's impossible to maintain. And the full printed version comes to something like 23 or 24 books. And it's English going back a thousand years. If you want to find out how to use a word, this dictionary is almost entirely useless. It's for language nerds. Because what you find out is not the most common use of a word, but the earliest and oldest uses of a word. And so, let me show you what get looks like. Yeah, if you want to know the full history of the word, there it is. That's what it looked like. And these are the cognate forms in Old Norse, Old Frisian, Middle Dutch. Yeah, very useful if you're a language nerd. Now the other thing I want to point out is the right hand scroll bar. It's proportionate. I also want you to see that there are four entries for get. It turns out that if you print out this definition, it covers over 30 pages. It is one of the two longest words in terms of its definition in the Oxford English Dictionary. The other one is set. And I love the fact that, oh yeah, I'm going to be really I'm going to be clear. I'm going to avoid ambiguity. I'm going to use a name that has no ambiguity. And people like get and set together because they kind of feel like opposites. They kind of feel like they're together. They're three letters long. They rhyme. But the opposite of set is not get. It's reset or unset. And there's two elements here. One of which is the naming aspect. But the other is the pairing, this false pairing. And we end up with stuff like people just without even thinking will promptly go ahead and if they've been writing get, they're waiting for the other shoe to drop and they will be busy writing set as well. Whenever I run TDD workshops, I'm amazed at how many people will put in setters even though they have no tests. They've only tested the getters. And I'll say, well, why have you got a setter in there? Oh, I didn't realize it went in. They didn't realize because it was a habit. Or, even better, their IDE did it for them. That's brilliant. That's what IDEs are for. They allow you to do the wrong thing faster. So, simple as that, we get rid of it. And suddenly, we've got some benefit. Here's the point. There's no natural mirroring. There's no reason they should be there. You should be very doubtful if you see such pairings. They do occur, but they're not common. The other refinement I'm going to suggest is this is a noise word. It doesn't actually add much meaning to the code at all. And suddenly you see that it's not about getting, it's about units, hundreds, and currency. This is the other thing you need to be aware of. In English, get does not mean ask a question. Get means it's a command. It's an imperative. You should adopt a more functional style. Get means change the state of something. It has a side effect, which is what surprises people. When people get drunk, there's a side effect. When you get money from a cash machine, disappointingly, there is a side effect. Get means I'm going to change something. Let's talk about and close with this question of intention and communicating. It goes all the way through to tests. The way that you think about tests, the way that you approach tests. There's a really interesting observation from Nat Price and Steve Freeman. A number of years ago, they ran a session at the XP Day conference in London. It's called, Are Your Tests Really Driving Your Development? They said, Everybody knows that TDD stands for Test Driven Development. However, people too often concentrate on the words test and development and don't consider what the word driven really implies. For tests to drive development, they must do more than just test that co-performs the required functionality. That's the thing that people think of. They normally think, Why am I testing? To test that it's okay. They must clearly express that required functionality to the reader. In other words, the goal is not to show that the code is okay. The goal is to show what you mean by it's okay. That is far harder, far more challenging, but ultimately more rewarding. As they say, they must be clear specifications of the required functionality. Tests not written with their role as specs in mind can be very confusing to read. What are we going to talk about as we close? We're going to talk about this. We're going to talk about books about objects. Actually, these are books about psychoanalysis. Apparently, psychoanalysts and psychotherapists are obsessed with objects. The only thing interesting here is that it's a stack of books. We're going to use stacks, that other old example in computer science. It's a stack of books. What does a stack class look like? Well, I'm going to make it a pure stack, so the pop only has a side effect and doesn't return anything. We'll just keep it kind of simple. It's got a constructor, it's got some private representation, it's got a push, a pop, a depth, and a top. Brilliant. Okay. So, how do we go about testing this? Well, if you get your IDE to help you, it will do this. Which is really not, which might actually qualify as the least useful code generation ever created. Because it allows you to do the wrong thing faster. If you look here, all we've got is test, constructor, test. We've just done a one-for-one with each of the methods. That's not how you use an object. I mean, you can't use push unless you've used the constructor. It turns out you can't really use and pop has two different behaviors. There's popping when you have an empty stack, which is a failure case, and there's popping when you have a non-empty stack. Is it clear from this? Not at all. Some people might try and refine this by observing that the word test is a noise word, but that doesn't really help. So, here's the observation. If you have this one-for-one alignment, what you're going to find is if you actually go into this, you need to use the stack. To use the stack means to actually try and get it to do something. So, here's the test. Let me reformat this so I can then drop the noise words, the language words. And here we see a description of what a stack is. We know that it's got a top method and a constructor and all of this kind of stuff. That's not news to the reader. Tell them something that they don't know. A new stack is empty. An empty stack throws when queried for its top item. An empty stack throws when popped. You've got a language here. It's a full description of intention. These are propositions. When the test passes, you're left with a list of behaviors that it has. When one of them fails, then it has the opposite of what you've just said. So, let's go back to this. How do I know that this is slightly broken compared with this implementation? Well, I put together a sort of this observation that it's not just about method alignment. We end up with the same problem. People often write test against one function. But it's multiple tests for a function. So, I wrote kind of, you know, here's an ad hoc testing framework. Fits on a slide. Then I wrote some tests. Let's see what they say. Here they are when they pass. Now, I've made a logical guess of what the behavior should be. And even if it isn't that, then it's easy to fix. But this is what it looks like when it passes. And this is what it looks like when you run it on the old versions. Those fail. So, in other words, the things that are in green are capabilities the code supports. Things that are in red are capabilities it doesn't support. Very simple idea. A test case should be just that. It should correspond to a single case. Which ultimately brings us to the end of the seventh item. Pretty much the end of the talk. And it allows us to answer this question perhaps a little better than when we started. As a programmer, I want code to communicate directly and with intent so that I can spend less time determining the meaning of code and more time coding meaningfully. Thank you very much. Applause