Seven Ineffective Coding Habits of Many Programmers
CC Attribution - NonCommercial - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
Henney, Kevlin
Habits help you manage the complexity of code. You apply existing skill and knowledge automatically to the detail while focusing on the bigger picture. But because you acquire habits largely by imitation, and rarely question them, how do you know your habits are effective? Many of the habits that programmers have for naming, formatting, commenting and unit testing do not stand up as rational and practical on closer inspection. This talk examines seven coding habits that are not as effective as programmers believe, and suggests alternatives.
 Right, good afternoon. Is that coming through? Yeah, okay. Thank you to Thomas Eccley for taking a picture of me and posting it saying if anybody looks like an evil genius, it's me. Thank you. I like that. That's a good start to the day. I'm going to use that one with my kids. It's just that, you know, do the right thing or else. Okay, so yeah, I was, you've had a hard choice. I know you've had a hard choice because I've looked at the program and this is a hologram of me. The real me is in one of the other talks that's going on at the moment. There's quite a lot on at the moment. Yeah, we're going to let us learn about holograms. That's right. We're going to look, no, sorry. That's far too technical. We can't do that first thing in the afternoon. That's why we're on. That's why there's these speakers on at this time. So I'm going to give you seven things. I like magic numbers, seven. We're going to go for seven. Seven ineffective coding habits of many programmers. Chances are you do at least one of these. That's not necessarily a bad thing. I have done at least one of these. I'm not going to tell you how many. That's the whole point. We learn by trying things out, but we need to be a little more empirical, a little more experimental with some of our habits because we acquire habits. That's the whole point. We pick habits up because they are low energy. You don't have to think about everything. If you have a habit, then it makes it easy to do something. This is a good thing, not a bad thing. The problem is though, we sometimes pick up habits without really thinking about it. We suffer from a lot of cargo cult programming and borrowed habits, habits that we picked up years ago from different environments that no longer apply. Or habits that we're doing because, well, everybody else does them. If you are a parent, you may have already encountered this one. Why are you doing that? Because so and so at school does it. Oh, okay. If so and so jumped off a cliff, would you do it? This is a standard parent line. You get a free pack of parental quotes when you get a kid. I'm working my way with my older boys, turning into a teenager, so we're finding a whole new chapter. It's fantastic. That's the point. Do we just do things out of habit? Do we follow habits out of habit? That is the problem. I want to question some here. You will undoubtedly disagree with me on a few of them. That's a good thing because it shows you're awake. But please reason through them. Really think about it because as I said, I've tried some of these I've sleepwalked into in other cases. I've kind of felt there was something not quite there from the start. So those things, I can't actually speak Chinese, but these have been conveniently translated for me. A couple of these things might be relevant as I talk. This is probably more relevant. I write when I'm not writing code. I write a little bit of short fiction. And this means that I do really care a lot about readability and reading and style. And Doug Crockford noticed in the very slim volume, unsurprisingly slim, JavaScript, the good parts, it turns out that style matters in programming for the same reason it matters in writing. It makes for better reading. And I want to emphasize that that we, many of our reading habits are precisely that. They are habits. Reading is not a natural state for a human being. If you've, again, if you've got children, you realize that reading is one of the last things they actually get to do, that they actually learn. It's really not one of those things like eating, walking, talking or anything like that. Reading is a far more subtle thing. And therefore, it taps on parts of our brain that we're not expecting. It taps on areas that we would consider now when we talk about visual design. It taps on areas to do with reasoning. It's not a single place. Reading, it covers a multiple, a very wide range of brain matter, if you like. And it is a learned practice. So anything you can learn, you can learn something else. But I want to try and talk about this in terms of properties. Let's, so let's start off with picking out the signal from the noise. Just as a general point, if you remember a few years ago, it was very popular for the Earth to end. This was, this was announced on Friday the 13th, which is, you know, by the world, I was in New York, it was World Trade Center. If you're going to announce the end of the world, that's a really good place to do it. And a good date. But this guy was just lost in the noise. Turns out the world didn't end then. And it didn't end in October that year either. And it didn't end at the end of 2012. We were supposed to have Ragnarok in February. That didn't happen either. You know, it's a good excuse for a party. So let's talk about noise. Let's talk about picking out the signal from the noise. Signal to noise ratio. This is an engineering term. But we often repurpose it. We talk about it as a measure used in science and engineering comparing level of a desired signal to level of background noise. But in everyday conversation, we talk about it as the ratio of useful information to false or irrelevant data. Okay. So in a conversation or exchange. So let's pick on a fairly famous piece of English. William Shakespeare apparently wrote other stuff, but here, this is the only bit that ever gets quoted. This is quite a nice piece of English. It's quite dramatic. He makes extensive use of short words. And yet, it's very, very deep in meaning. Can we make it clearer? Could we perhaps translate it into office speak or business speak or marketing speak? Well, conveniently enough, somebody's already done that. A fellow called Tom Burton in a book, Long Words Bother Me. Very interesting book on language. And he translated this into marketing speak. Enough with a to be or not to be. Continuing existence or cessation of existence. Those are the scenarios. Is it more empowering mentally to work towards an accommodation of the downsizing and negate? Good grief. I mean, you know, this, you could put this on a PowerPoint in a standard business meeting nobody would notice. This is, it would just slip in there. And the problem here is that we've added more words. We've added longer words. Have we actually added any meaning? No. And this is the problem. We have a lot of habits. Without realizing it, we add noise to the code. So we can take, so this is one of those little examples. I kind of recycle a bit. Recently used list, very simple example, a list that holds your recently opened files. So a list of strings, but it has the property. Just go in at the head like a stack, but they're also unique. Like a set. When you reopen a file you have already opened. It doesn't occur twice. It just goes in once. And I use it as a programming exercise. It's a really good little lab. And so one group, one pair a few years ago produced this, this C-Shop. And they said, well, we finished the exercise, but we're really not sure that, well, we're not happy with the code. Because the kind of model answer is about this long. Now, what's interesting is not simply that it takes up half the space, but when you actually look at the lines of code that do stuff, it's about a third. So if we get rid of all the curly brackets and other spacing forms and declarative noise, then there's a very big difference between the two. You know, five lines versus actually quite a few more. Imagine this style carried out over a whole code base. It's not the case that the example on the right is easier to read than the one on the left. I want you to think, what happens if you use the same kind of thinking over a whole code base? I've seen those code bases. You're sitting there looking at classes of thousands of lines long. And you know that in there somewhere there is a small class struggling to get out. But it has identical functionality. Actually, the one, that one's slower than that one. So the, so the, so there is this case. There's so much noise. Which one do you want to work through? It's greater cognitive effort, more cognitive load. One of the most common sources of noise is comments. Thanks to Oracle for this one. But as I've, so there's the real, you know, all of that just for Hello World. I love the fact that they listed as a Hello World app. That makes it sound so grand. But one of the things that I've, I've, I noticed I used this for a couple of years this slide in different contexts. But I, I realized after a while when you actually cut through the noise and you look at the one line that actually does something, it's wrong. There's a missing comma. Oh, it's wrong in English. I mean, the Java's fine. You can convince a Java compiler to do anything. Yeah. The English is wrong. It's missing a comma. It should be Hello, comma, World. Okay. This is really important. It's not just trivia. I'm not just picking, picking minus syntactic points here. There's this kind of classic saying people say, you know, there's a difference between let's eat grandma and let's eat grandma. Punctuation saves lives. All of this and they get the one thing that matters, the real piece of communication to the user and it's wrong. You're never going to notice that with all that noise. So a long time ago when I was first learning C, one of the things that was given to me was this article, well, this paper by Rob Pike. He wrote it in 1989. So I must have read it fairly soon after. Notes on programming in C. And there's some really good stuff in here. And there's a couple of things that definitely show its age and its time and its language. But as he says, comments, 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. Now let's turn that around. He's sort of saying clarity is a consequence. You know, if it does this, then you shouldn't need comments. Now let's turn it around. Use good type names. Use good names in order that you do not need any auxiliary mechanisms. You may need some, but the idea is minimize that which the code cannot say. Just get rid of the noise. You may not be able to eliminate it completely, but the idea is it should be your goal to rewrite the code. Sometimes a very useful technique is to imagine that somebody has removed the commenting feature from the language. How would you write your code then? Okay, for some people, they probably will make the slightest bit of difference. But for those of you who are here, it will. Think about it. What would you say? Would you say anything differently? Okay, say it like that. And then allow yourself comments back. Is there anything left that you would also like to communicate to the reader? And often it's the stuff that's not obvious. Second comments aren't checked by the compiler. Actually quite frankly, they're not checked by the programmer either. So I don't know who the audience is. Yeah? The compiler skips and programmers skip. We even use different colors in our IDEs. I've even seen people use white on white background in order to skip that. Some IDEs come with the ability to fold away the comments because that's how important they are. So we don't read them. And if you read them, then it's ultimately, it's a bit like reading the instructions. It's a sign of defeat. Yeah? I bought a new Blu-ray player last week. And I sort of strode into the house proudly with this one. None of the cheap ones are only good, I said to my wife. Oh. But it's not the most expensive one in the shop. Great. She knows how much the most expensive one is. But it was quite good. And she said, you're not going to look at the instructions, are you? No. Yeah? That's the fact. You can file those away wherever you file them. I'm going to set this up because I am programmer. And if it doesn't work, then it's the designer's fault. I got lucky. It worked. So the point is there's no guarantee this stuff is right as we just saw with the distraction and the code level. But the other thing is the, there's a visual aspect here. The issue of typography, comments clutter code, I'm going to come back to that visual aspect again in the next item. But I think my favorite piece in this Rob Pike paper was this. And as he says, don't laugh now. Wait until you see it in real life. In real life. I did laugh. And then five years later, I found it in production code. It's just that I was stopped in there and I was reminded. I said, I've seen, yes, somebody actually wrote about this a few years ago. Absolutely astonishing. If you are, if you do not know what this is going to do, you have no business looking at this code. Okay? It's really not in your place. Yeah? So we have this other issue. So I tweeted this a while back. It seems to have been retweeted quite a lot. Common fallacies is to assume authors of incomprehensible code will somehow be able to express themselves lucidly and clearly in comments. If you think about it, because I've often said to people when we've talked about comments, they say, oh, well, you know, programmers sometimes, you know, the code can't be, can't be easily understood. So somebody wrote it. Who's going to comment it? The programmer that wrote it. So we're going to get the same person to write the comments and they couldn't clearly express themselves. I mean, some things are genuinely hard, but quite frankly, most code doesn't fall into that category. And if you can't express yourself fluently in code, it often means that you're on a learning curve or, so that's the good bit, it's always nice to be able to say, look back and go, damn, I was such an idiot. That's great. It shows progress. Either you're on a learning curve or you flatlined. Your learning curve is dead. That's it. So there is this question. We need to really revisit this stuff. This stuff gets in the way. Now, this kind of suggests that we want to look at other aspects of the code. What I want to look at here is the one that people say, you can't touch that. You can't talk about that, Kevlin. You're going to talk about indentation and spacing. But don't you know that that's not a reasonable conversation that you can have. You will never have a rational conversation about spacing with developers. Just leave that one alone. It's a personal preference. It's untouchable. It's like they're talking about the baby's names or something like that. You just don't go near it. Yeah, that's why I put it number two, not number one. I'm going near it. Right. So, remember this? Remember this? How would a programmer do it? They do it like this. We have a bit of a problem here. We have a bit of a problem. Let me show you the shape of the problem. So, this is slightly beyond HD. HD is 16 to 9 in terms of its ratios. But there are some 21 to 9 screens coming out. And we fall in love with our high resolution monitors and our widescreen monitors. You can actually now project the whole of the Serengeti across your workspace. And it's magnificent. And it's beautiful. And you need a pair of binoculars to see all of the antelope from one side to the other. After a hard day's working, your neck is aching because the code has been going from one end to the other. And this is the problem. This is how many programmers lay out their code. They say, well, that's great because I've got a big screen. We don't need to live in the years of 80 columns and 24 rows anymore. Yeah, yeah. Because we've got better technology. What is this, we? I'm still wearing the same eyes. Actually, they're not, no, they're worse than they used to be. Okay, you still got, we haven't evolved yet. We have not kept up with screen resolutions. Come back in 2000 years. Let's see how we're doing then. Probably need another 10 or 20,000 years before it really takes hold. But that's the thing is our ability to perceive has not changed. The bit we can focus on, it's a tiny little bit there. We've got peripheral vision to around there. When you read, if you watch any kind of eye tracking study, it's very interesting. People don't read the way you think they read. And if you have to start moving ahead, that's never a good sign. So the problem here is that that's column 80. We get a lot of stuff out here. And I had some very interesting episodes. There was a couple of years, actually, I was here in Oslo, doing a code review with one group. I do strongly recommend doing code reviews on whatever is not your work machine. Because where do we read code? We read code. We read code on laptops. That's got an HD resolution. That's fine. Put it on a decent screen, double headed monitor, no problem. Put it through a projector, though. And there's loads of projects. I saw a projector the other week that was still at 1024 by 768. Most projectors are sort of 1280 or above. But the point there is use a projector. And this is exactly what happened. The program, we had two lines of code following each other. And they were identical up until the right hand side of the screen. And the program said, oh, yeah, they are actually different. This argument list is quite long. And the method names are quite long. But they differ somewhere around here. And then I think the comment that you always have to chuckle at, it worked on my machine. That's not just about it ran on my machine, but actually does the code look any good? This is another, I tweeted this a while back and somebody else made the other suggestion. And very good observation. I hadn't really thought about it. But increasingly, I read a lot of stuff on tablets and phones. Try doing a code review. Go to the coffee shop. Take your tablet with you. You'll suddenly say, oh, well, this would be great. Hang on. There it is. The point there is you need to appreciate how people read. Don't work to one resolution and one idea of how people read. And actually find out how people do read. Turns out they read a lot more like this. I'll give you column 80 rather than column 60. See if you can stick to double digits. I tend to use column 80 like a sort of a soft, soft stop. But if I hit three digits, I know something's going wrong. And when I pointed this out to this guy, he said, so you mean 160 is too long? Yeah, I think so. And he looked at this one that was 200. But that's nothing. I visited the company a few weeks ago. And it was like a graph, the code. If you zoomed out, it was just sort of, but, but, but, so we went out. We found something at column 352. It was a line that went out that far. We were kind of disappointed that there weren't an extra 13 characters to make it up. There were one column for each day of the year. But the point there is that that's difficult for people to read. Why is this difficult for people to read? How do people lay stuff out? How do people really lay stuff out? Go and pick up a newspaper. Go and look at a website. And you will discover that people do not actually try to use up the whole horizontal space. In fact, they actively seek to not use it. This relates to a point that we need to embrace. It's a thing called clean design, or it's visual design basically. Now normally when people think of clean and the word code, they're sort of thinking Uncle Bob and his recommendations. That's great. That's the functional side of it. That's the syntactic, the semantic. But I want to talk about the visual aspect. To answer the question, what is clean design most succinctly? A clean design is one that supports visual thinking. So this idea of visual thinking, the idea of arrangement so that people can see what's going on. If you look at the way that posters are laid out. If you look at the way that ordinary web pages are laid out. And look at the pages that you think are good. Look at the pages that you don't think are good. See how they structure it. It's the same human visual perception system that's responsible for code. So therefore you need to think how somebody is going to read this. So this is the idea. People can meet their informational needs with a minimum of conscious effort and also physical effort. You don't really want to be doing that a lot. You convey information by the way you arrange a design's elements in relation to each other. When you put things above each other, it signifies one thing. When you put things apart from each other, it signifies something else. And this is something important because what you're doing is you're actually showing the reader how to think about something. They're not just looking at the words and the parentheses. You are showing them these ideas are together. These ideas are separate. These ideas follow this idea. That's what you're doing when you lay things out. Now you may not be aware you're doing it, which is where we end up with a slight problem. There's a bit of a gap sometimes. And there is this idea of a term I came across just last month. Structural honesty. Does the structure of your layout, is it honest? Does it convey what you actually are trying to show with the syntax? That's a very interesting idea. So, you know, if the visual relationships are obviously accurate, this is fine. But if they're not, your audience is going to get confused. They will have to examine your work carefully. Now, you may be so proud of your work that you think this is a good thing. I put so much effort into it. Of course, I want people to examine it carefully. Or alternatively, there is, it was hard to write, it's going to be hard to read. Yeah? You've got different ways of coming at this. But I want to talk about this from another point of view. So, the first thing is structural honesty. That's the first requirement. Because people normally assume, as I said before, that spacing is somehow a personal or just arbitrary cultural preference. Java programmers do it one way. C sharp programmers do it another. C programs have half a dozen different ways of doing it. Python programmers have one way of doing it and there is no other. There's lots of different variations. And we assume that these are somehow given and are not open to question. I'm going to question that. I don't think they are a given. So, let's look at some things in terms of visual honesty and visual structuring. So, how not to lay out a method header? I see this so often. It's so common in code. I'm going to blame most of the, am I going to blame the Java guys? Yeah, I'm going to blame the Java guys. They do this most. Followed rapidly, hot on their heels by the C sharp folks. I tend to find this less in other languages. I'm not going to say they, I don't find it. But in terms of cultural tendencies, the problem with this is this is about as structurally dishonest as you can get. Because where is the argument list? You're only allowed to use one finger. Ah, see the problem? We have a phrase, an argument list. Okay, where are the parameters? They're in two places, but it's one parameter list. It's on two different sides of the screen. Much more exciting if you've got really long names because it could be off the screen. So, are you calling that single argument method? Which single argument method? I'm calling the two argument one. No, there's no two argument ones here. Well, yeah, there is. Just keep scrolling. Keep scrolling. There it is. The point here is that this is about as dishonest as you can get. It's kind of like, ha ha, full juice. There's one over here and one over here. So, if I had to pick the worst style, this is probably going to come close to it. I'm not going to tell you what the right style is. I'm going to tell you what the right properties are. We need to approach any convention that we adopt in terms of requirements, not end user requirements or customer requirements, but requirements. What do we want from a layout? The first thing I want is this idea of visual reasoning and structural honesty. So, if you got that, that's a good start. So, that suggests you can do it like this because the arguments are grouped. They are vertically grouped. There is one consistent reading order. Alternatively horizontally, there is one consistent reading order. I don't care which one you do. You can even try and mix them about a bit. I don't care, but the idea is they both have this property. But there is one to not do. This one is very common. Now, we may say, well, that's fine. I don't see the problem with that because it's structurally honest. It is structurally honest. Everything is in the right place. The argument list is in one place. It is vertically organized. It has a simple structuring principle. But the problem with this is nothing to do with that. It's to do with the second requirement, which is sustainability. What do I mean by sustainability? Well, let's look at a couple of method calls. Same principle. We have that there. We align it with the opening parenthesis. I'm going to say, do it either like that or like that. There's a couple of other variations. I don't really care because the one thing that we know happens in code is change. Change is the most common thing. The minute you do a rename, boom, it's wrong. It becomes structurally dishonest. In other words, the reason I don't favor that style is that unless everybody is working with an editor that naturally aligns this, you would more likely to find this in the list space than you are in the enterprise language space, then this first style is doomed to failure. It will never work. That's a very, very grand statement to make. It will never work. Okay, let me put it another way. It will only ever work if nobody ever touches the code. Again, never. In other words, it's one of those techniques, one of those ones that comes out and it looks right the first time you write it. But from that point on, it's doomed because the minute that anybody does anything that causes a shuffle, it is unstable. It's unsustainable. I'll leave aside the fact that you end up with this kind of alignment problem that it bounces around the page as you scroll through a file. It's completely arbitrary alignment. It's like rolling dice to figure out which column should I put something in. But that's a personal preference. I want to attack it on the fact that it's just not a workable style. This is the one that upsets people most, I've noticed, whenever I say this. I actually had somebody come up to me after saying this, say, well, I disagree with you. Well, of course you would. You know, get over it. So every time I do this, I make sure I go around, or every time I do a rename, I go through the whole code base to check that everything is still aligned. This is what we call a high maintenance approach. It takes a lot of work. Why do you choose an approach that's difficult to maintain? Do your colleagues also do what you do? And then a dark cloud appeared over his head. No, they don't. And I said, there is the floor in your otherwise, well, heavy, heavy working plan. So the point here is, yeah, it kind of looks pretty the first time you do it, but, you know, we can read anything. Choose something that's easy and sustainable over time. Which means I'm now going to talk about something else to do with spacing. Which is this point about arbitrary alignment positions. So this is a, this is a formatted according to kind of orthodox Java style. And if we look, we see that there are a number of points of alignment where the eye is drawn. It's drawn to that line. It's drawn to that line. It's drawn to this line. We've got three lines whose only meaning is we just happen to be here. And then we've got three lines over here that actually represent logical indentations. So we've got six points of alignment and not very many lines of code. It's quite busy. Okay? Your eye is having to do an awful lot of work. So reduce the number of points of alignment. Stop pushing people out to the right-hand side. Okay? If something's important, it should be on the left. Is the parameter list of a method important? You betcha. It should be somewhere people can read it. It should be either a natural follow on or immediately to the left. People read from the left. Okay? Okay? There are alphabets that don't, but we're talking code here. Pretty much all languages that we're dealing with go from the left. So therefore adjust to what people are doing. Don't maintain a fantasy. Putting your argument lists, putting your arguments over to the right. It's a stupid place to put them if it's off the screen. But we've also got this arbitrary alignment thing. So let's realign it. Well, this is better in one sense because we've now got three points of alignment or three lines of alignment, which is great. There's only one problem. Visually, what does this look like? Well, if you kind of squinted it, actually, I'm not going to, don't worry, don't squint. We'll just replace them all with X's. Let's just get rid of all the punctuation and see what you're actually seeing. Now, I can't tell the difference between the argument list and the first declaration. This style, there's a technical description of it, does not work. Okay? It does not work because visually there is no distinction between two fundamentally different ideas. Here are the parameters to your method and here are your local variables. That's kind of important. Call me a bit old-fashioned. I think that's quite important. So we have a couple of choices. Again, I don't, well, there's more, but again, I don't care which one you choose. You can either sit there and go, whoa, double indentation. Okay? Put them somewhere else. That kind of looks okay. It's visually distinct. Alternatively, stop putting your Kelly brackets in the wrong place. Yes, there is such a thing as a wrong place. It took me 25 years to discover it. I've used all the styles, even some of the crazy ones. I've tried everything and it's just that actually there are reasons. I can read all of them, but it turns out there are some that actually make more sense and it's this idea of sustainability and visual design that actually makes, tips the balance. So that's some food for thought. Let's deal with something slightly less contentious now. Oh, yeah. And of course, that obviously has visual distinction. Let's talk about Lego because Lego is good. Any excuse to talk about Lego is a good excuse. Except that we have a bit of a problem here. Lego naming. What's Lego naming? Well, Lego naming is where you take sort of parts of Lego. I'll have a kind of a red 2 by 4 and I'll stick that with a kind of like a white 2 by 2 and I'll put this together and I will create a name. This is kind of like what my kids used to create in terms of those towers that you're sitting there going like that's going to fall, that's going to fall, and there will be tears. This is how we name things. What's the process? It's called a glutination. Linguistic morphology is where you derive complex words by gluing together other words. Some languages do this more than others. Okay? So here's the longest word in the English language. I think it's kind of ironic because it was invented to be the longest word. Nobody actually uses this and it's basically made up of Greek and Latin rather than English. So, yeah, not interesting. Here's something closer to home. This is a bit of Norwegian. Yeah, you bet. I'm not going to pronounce it. However, I'm afraid, yeah, you know which language is going to win. Of course, it's German. Although technically this word was, it's no longer a word because it was retired last year. It's about 64, 65 characters. It refers to an EU regulation that is no longer an EU regulation. The abbreviation is 12 letters long. But it turns out that even if you can read Norwegian and German, this is not a very natural way of dealing with words. This is too long. You can't grasp it in one go. You have to kind of pause. You will eventually abbreviate it. So what's the problem with our words? Yeah, identify names. There's even sites that make fun of this kind of whole approach of stacking standard terminology together. There's method name and class name. You can just go there and refresh the screen and it will give you new class names and method names. Just made up of standard parts. What are the standard parts look like? Well, they kind of look like this, you know. It's one of those things. Oh, it's a proxy service manager controller. Factory. Factory. Just remember for every factory, factory you ever create, somewhere on the internet, a kitten dies. Okay? That death is on you. We just take these names. We add them together. We say, oh, look, I'm creating meaning. It's now really meaningful. I refer you back to the Shakespeare example. I've made the name even longer. I've poured more meaning into it. No. What you've done is this is like homeopathy. What you've done is you've diluted the meaning till it's all gone. There is no medicine there. There's only sugar. That's it. It does nothing for you. But does it really take a long name? I mean, sometimes we end up with these names and you're sitting there going, well, I can read all of the parts, but I have no idea what the whole thing means. Yeah, but surely you know what a manager control proxy is. Funny enough, not today. But we've got a factory for one of those. Don't even begin on the name. It tells us something about our coding style as well. It tells us perhaps that we are failing to find the right abstractions, the ideas that name things directly. We often find this as well. There are these naming habits. It doesn't even have to be long names. So here's one from a piece of client's code that I counted a few months ago. It was about three months ago. And even at this short length, condition checker, not a long name. Check condition, not a long name. But I was looking at this thing. It's like condition checker. We've got validators and checkers and all kinds of stuff. And I said, what's the condition checker do? Well, we call it to evaluate a condition. You mean it is a condition? Yeah. And what do you check it for, whether it's true or not? You mean this. Yeah. Oh, that's what it means. That's what it is. It's not a condition checker. There's not some kind of condition sitting out there in sort of a platonic space somewhere. There's not some kind of abstract condition that we somehow have to reach. Is there a fire? Not something that we actually have to go out and check for. There is this idea very, very direct. It's a condition. Is it true or is it not? And it's a very simple statement. Now, when you start applying that, it also takes you other places. So here's something. I was going to do this in C sharp. I decided, no, I'm going to put this up in Java because it allows me to use the throw signature, which is not something I'm a big fan of, but it allows me to cover two things at once. We have a very standard vocabulary. And sometimes people say, oh, it's okay because it's standard. That means I know how to read it. Yes, the problem is you may not be communicating meaning. So create connection. That doesn't seem particularly harmful. But how many things do we have that are called create that return something? Do we need the word create on everything that creates a new object? Is that helpful information? Remember you have a fairly limited bandwidth. There is a reader out there and you have a few characters in which you can say, this is what I want you to notice. And you might not otherwise pick up. If you try to tell them absolutely everything, here is a method that uses objects. Well, they probably already know that. So don't tell them that bit. Here is a method that's going to return you something that has been created. Okay. But give me a better sense of it. And then we have a habit that I, you know, I was completely blind to this from till about 18, 20 months ago. Completely blind to it. We put exception on the end of exception in so many cases. This is a very common.net and Java habit. And I noticed I was going back to some C++ code and I suddenly thought, why am I not putting the word exception on the end of all the exceptions? And I suddenly realized, because I don't need to. Think about it. So first of all, what are you really doing? You are creating connection. This is a mechanical description. What are you, what is your intention? I am trying to connect to that thing over there. So what we've done is we've ended up doing object oriented assembler. Instead of saying, I want to connect to that, we've kind of hidden that and said, I'm going to create a connection rather than our intention. I want to connect to that. I'm going to, but if this doesn't work out, I'm going to throw you an exception. What does the exception indicate? It indicates a connection failure. It does not indicate a connection failure exception. Okay. My name is Kevlin Henney. It is not Kevlin first name, Henney last name. Okay. Of course, it's, of course it's an exception. What else could appear in a throw clause? What else could appear in a catch? What else has a name like connection failure? In fact, it's, it's kind of interesting. If you strip that exception off, you can actually find the good exception names. So in the Java library, there is illegal argument exception. If I strip off the argument or other extra of the exception, illegal argument, that's actually quite meaningful. That's quite a good one. On the other hand, in.NET library, I find argument exception. If I strip off the exception, I just get argument. That tells me that we haven't really expressed ourselves. And likewise, in both cases, there's null pointer exception and null reference exception. So when you receive that, that means that something bad happened. What was, what was bad? A null pointer. No, there's nothing wrong with a null pointer. Tell me what was bad. D-referencing a null pointer. That's bad. So that's the name of the method or the name of the class. So try that out, you know? You probably have stones thrown at you by your colleagues. But, you know, I recognize that's the harder one to do, but at least the intention elsewhere. Try and communicate the intention. Don't always talk about the mechanics. So speaking of that, let's talk about abstraction or lack of it. Under abstraction. So this is a slide that I've used a few times. This is from a blog by Philippe Calçadeau. It's about five years old. Unfortunately, the blog's gone offline, but you can still find it using the Wayback machine. And it's a technique that I've encouraged people to use. And I've actually visited companies, visited a company last year where they had all of their projects, had tag clouds up on the wall. And this idea is very simply, you get your source code, you strip out all of the comments and all of the string literals, and you push through, push this into something like Wordle or some other tag cloud generator, and you find out what the overall map is of your code. It's a very odd way of looking at code, but we've already looked at code oddly in one sense. I replaced all of the code with Xs. And that's the technique I think I picked that one up from Michael Feathers. There's another technique that I use which is zooming out. Look, choose the smallest font size. You possibly can and see what the code looks like. It gives you an unusual perspective. Okay? Code is complex stuff. You need more than one point of view. This one strips out all of the, well, all of the code structure. We're just left with the names. What does that tell you? Well, in this particular case, it tells us that we really like strings. And lists are quite good as well. And we've got a few integers thrown in for good measure. Wow. So that's what your system does. Your system does strings with a few lists and occasional integers. Gosh, that must be really exciting to work on. Because I work on this system. What do you guys do? Oh, we do stuff with pictures and printing devices and products and paper. Oh. You still got any strings? Yeah, but strings are really small, isn't it? This is the point. We're communicating in the language of the domain. The domain is about these things. We've ended up with object-oriented assembler. We have, without thinking about it, the intelligence that goes on up here, we thought, oh, I can use a string for that. I can convey that using a list. Like, rather than what is it, what is the idea? Shall I name the idea? And using a language, you know, most languages allow you to introduce a name for the idea. So we end up with type names. And so therefore, really enriching that. And that idea sort of riffs off a guideline from Dan North, code in the language of the domain. And I think this is a really interesting example. I really like it because it doesn't use any programmer abbreviations. And yet it's not entirely clear what's going on. The only abbreviation in this piece of code is ID. But that's a real world abbreviation. It's not a programming abbreviation. So every single word there makes sense, but the whole thing doesn't make sense. Should we have a comment? Well, no. This is the whole thing. We have not abstracted enough. To abstract is to remove something. In this particular case, we can actually extract the method, not merely abstract it. And we end up with something that's far more meaningful. All of that mechanics goes away. And that's the problem is as it's this kind of balance of skill that we have, we care very much about the mechanics, but we also care about the abstraction. Sometimes we get a little confused between the two. We put the mechanics where the abstraction should be. We mix our levels up. That's the intention. Beneath it is the mechanics. And so there's this idea that in anything other than a hundred line script, you really want to start organizing the mechanics away according to intention. When the system gets large enough, even the intention becomes mechanical. So you have another layer. But this is the idea. We have a choice here. And when it comes to code, when it comes to code, you have only three ways of expressing yourself effectively. Names, spacing, and punctuation. And the language takes care of most of the punctuation. So that's it. That's how you communicate to other people. Of these, the names are the most important. We've also looked at the spacing. These are your only tools. The other thing is to look at things from a different perspective. Let me offer this one. This is one from Gregor Hopper. It's very simple idea. What is the perspective we want to encourage people to look at? Well, look at it, look at a method from the outside, not just from the inside. We often write our code inside the method. And when we see our parameter names, we see them as well named. We hope. We see them as well named. And we can see them and there's no problem. They make sense within the body of the method. But what happens when we look at it from the outside and try and use it? Now, if we look at this, we see, you know, parser, yeah, I can understand what that is, process nodes, yep, that seems to make sense to me. Text, yep, I have no problem understanding that. False. What? I have no idea how that relates to parsers, processing nodes or the text. What does the false mean? Why is it there? What does true do? Okay? And there is this sense that what somebody has done is they've said there are two options. Now, can I think of a data type that only has two options? Oh, yes. Booleans only have two options. Great, I'll use one of those. And the problem is what is true in this case? I have no idea. There's lots of ways of solving this, but the idea is that on the inside of this, it probably looks quite sensible. You know, maybe it says, is formatted. I can't even remember the example. But in the body of the method, it makes sense. From the outside, true and false make no sense. The most extreme example I know of this was a code review I did a few years ago where there were five arguments that were all Booleans. And on the inside, it looked perfectly sensible, if is enabled and can have logging. Oh, it all looked great. From the outside, true, true, false, false, true. What? There's no kind of sense there. You have to look at it from the outside. But that kind of long argument listing. Keep this in mind. We often under abstract. We end up with these kind of long arguments. Okay? Yeah? Now, different people have different tolerances. I used this quote with a team a couple of years ago. Because I was looking at some code. I said, look, all your constructors have 14 or 15 arguments. And then I used this quote. They seemed unmoved by this. And then one guy piped up and he said, oh, I think I understand the problem. He rummaged through the code, pulled up this thing and put it on the projector. He said, this constructor takes more than 70 arguments. I said, ah, I see the problem. As far as you guys are concerned, when you look at 10, you're thinking, wow, we wish we could have that few. You know? I'm saying it's like a lot and they're thinking, no, no, we aspire to have as little as that. But over the years, when I've retold that story, the record now stands at 326. The guy sent me the diff from the point that it was 325 to 326. You know? We had the conversation that it was 325. He emailed me a few weeks later. And here's me adding another one. That's the point. It's statistically, once you hit 10, 10 is as good as 11 is as good as 12. And it will continue on this way. Okay? So, yeah, it's a whole project just to call the method. You know, what are you going to do, the sprint call that method? Okay? Good luck with that. We'll see you on the other side. So, abstraction. Abstraction is related to something else. Not whiskey, but it would be nice if abstraction were related to whiskey. That's distillation. That's slightly different. What are we talking about? Unencapsulated state. Specifically, the relationship between this idea of abstraction and encapsulation, if we look at what the dictionary has to offer us, enclose something in or is it in a capsule? There's a boundary. You're putting, there's an inside and an outside. You're hiding something and revealing something else. But there's something else. Express the essential feature of something simply. This is abstraction, the essence of something to abstract what is it? What is it really about? What is the idea of the thing? And provide an interface for a piece of software to simplify access for the user. Now, this relates to a usability design concept known as an affordance. A quality of an object or an environment which allows an individual to perform an action. So, a knob affords twisting and perhaps pushing while a cord affords pulling. It affords a particular thing. So, a door that has a pulling thing affords pulling. So, if it has a little sign that says push, that's bad design. That's like a comment slash, slash, push. Yeah? We've talked about comments already. This is noise. If you want the user to push, give them a thing that they cannot pull. It's a very, it's a very simple idea. If you want them to pull, give them a pulling thing. It's very simple. If you want people to use objects in a particular way, then offer them the methods that allow them to do that easily. If you say to people, you can default construct this object, but then you have to call this method and you have to call this other method to properly initialize it, then you've actually missed the opportunity of constructing during a constructor. That's its point. Yeah? The idea is if there is one correct way to construct an object, then offer that as the only correct way. You really want to align the affordances, the usage of the thing with your intended usage. So, let's go have a look at our old friend, the recently used list. Let's go back to that one. And here is a very common implementation. I've re-rendered it here. What we've got is a very common implementation is that somebody will say, I'm just going to use a.NET list. I'm going to use a.NET list and then I'm going to have a property, a get, that's going to return that list. And then the bit that does the clever bit, the add method, because that's got to deal with uniqueness and it's got to deal with putting at the front rather than the back, will provide a method for that. But basically anything else that the user wants to do, they can do through this. And so we see how people use. So they initialize it, they go ahead, that's fine, initialize it. They go in there, they add, hello world, that's great. How many items are there in there? Ah! So, first point of call, we have no count property. There is no way to query the size of a recently used list. So we basically have to go in a bit, go to the items and ask for the count. But it gets fun because now what we can do is having got the items, we can sit there and go, oh, I'm going to add a duplicate string. Now, if you remember what a recently used list is, it holds its items uniquely. You cannot add duplicates, they move. When we go and look at the size again, it turns out that the size is now two. So it holds two duplicate items, which is supposed to be impossible. Well, apparently not. And we can also put nulls in if we want, which we're not allowed to do in the original version, a few slides back. So what we've done here is we've effectively, I mean, everything is private, the word private surrounds the list. But the clue that we have a problem is this message chain or sometimes called a train wreck because you get the dots adding up. Something dot something dot something dot something is a very strong clue that you have, you're revealing far too much internal structure. It's a very strong clue. But we knew this already. There is a piece of, we can actually pick up a piece of advice. Going back to the 1980s, the young Kiefer Sutherland, is anybody watching 24 at the moment? New 24? No? Okay, it'll get to Norway eventually. Kiefer Sutherland goes across London and people have been saying, you know, that's amazing. He managed to get from one side of London to the other in under 10 minutes. The mayor of London needs to hire him to redesign the roads because clearly this guy knows something. But this is one of the 80s vampire movies that preceded all the rubbish vampire movies we've had in the last few years. But people, whenever they think about how they're going to protect themselves from vampires, because I know you do, you wake up at three o'clock in the morning thinking, like, what if a vampire came through the door? I mean, I obviously excuse those who are a bit worried about the zombie apocalypse. I live in the city of Bristol and it turns out that Bristol City Council actually has an action plan for the zombie apocalypse. I think it was drawn up by one very bored council employee one day. But that's why I like living there. You know, you've got that opportunity. But I don't know what our vampire strategy is. And people think, oh, what am I going to do? How am I going to protect myself against vampires? And why didn't that build when I left? But no, really, vampires are more important. How do I protect myself? People come up and they say, oh, right, okay, I'm going to need garlic. Yes, we've got garlic bread in the freezer, so we're good. We're safe. Okay. And what else? Maybe I could drive a stake through their heart. Yeah, but you've got to get close and intimate. Holy water. Right. None of that in the house at the moment. Availability issues. You kind of go through all the standard techniques. Sometimes people misremember, they say things, silver bullets. Oh, you're going to be disappointed. That's werewolves. You've got to get your right undead. You know, wrong class of undead. Sunlight. But does it go as far as ultraviolet light? Some models of vampires say yes. Some models say no. It's difficult to say. But the one everybody forgets, the greatest protection, because you are at home. Do not invite them in. Do not invite them in. To quote the film. If you invite them in across the threshold, they can do anything. What has this got to do with encapsulation? Everything. Absolutely everything. Don't invite them in. Here it is. If you want people to be able to count the number of items in there, then give them a count property. If you want them to be able to do stuff, offer it to them. Your fingers will not fall off through the effort of typing. Okay. But you've also enforced an encapsulation that allows you to actually flip the representation round. This one we insert at the front. This one we just transform it and we insert at the back. From the outside, nothing has changed. From the inside, we've actually reversed the internal data structure. Nobody noticed. That is the magic of what we mean by encapsulation. What we're saying is strictly private. It's not just a case of put a private keyword in front of it. It means really, really private. Now, when I held back from, because sometimes people think, oh yeah, we've got classes with all these kinds of getters and things like that. It's such an item, I gave it its own space. So get. Get. Here it is in the Oxford English dictionary. The Oxford English dictionary is a fantastic dictionary if you are a word geek. And at this point, I confess I'm a word geek. Because it's of no use to you whatsoever if you're trying to find out what the meaning of a word is. Because what you will start off with, it will give you the complete history of the word. Okay? So, you know, the OED basically has everything going back for a thousand or so years. And it will give you all of the roots. As you can see, get is quite an old word. And it's cognate with a whole bunch of stuff in Frisian, Old Norse, and so on. Very useful if you happen to be in this kind, into this kind of thing. I think this is the most interesting bit, to be honest. And then there's all those other definitions and usages. It's very boring. But what I want to draw your attention to is two things. One, if you look at the first column over there, you will see that there are multiple entries for get. If you look over to the other side, you will see that the scroll bar is very, very small. That's because it's proportional to the amount of stuff there is on it. If you print out the definition for get, it comes to somewhere between 30 and 40 pages in the printed dictionary. It's one of the reasons I don't have the printed dictionary. You know, you know, it's, it's, sorry, which rainforest would you like to destroy to print it, sir? No, no, I'm, I'm just going to go and destroy electrons. So, it turns out that get is one of the words in the English language. There are two words in the English language that have the most pages of definition. Get is one of them. Yep, you got it. Sets the other. So, if you wanted to use these words because they're unambiguous and clear and they have a simple, concise, well-defined meaning, bad luck. It turns out there's a third word that's not been fully integrated, all the newer definitions have not been fully integrated into the OED. And this one may also be familiar. This third word is now overtaken both get and set. That word is run, which apparently we use quite a lot. Yeah? So, this is, so these are words that have multiple definitions. So, a very simple one is just, is on the naming. I just think get and set are terrible names. But get in particular, get. When you have a getter, does it have a side effect or does it not have a side effect? The one thing the word should tell me is that it should communicate there is a side effect or is there, there is not a side effect. Is it a pure query or not? Let's look at how the word is used in English. I go to a cache point and I get money from the cache point. Is there a side effect? Yes. Disappointingly, my count balance goes down. You get married. Is there a side effect? Yes. Huge side effect. Life changing. So, the point here is the word get means move from one place to another in such a way that it is no longer available at the first place. That's what it means. That's its principal usage. It does not mean I'm asking you a question. But you see get and set, they're three letters long and they look so nice together. They rhyme. If, yeah, if English were different, we probably wouldn't have this problem. And we think, oh, they're kind of opposites. No, they're not. The opposite of set is reset or unset. These are opposites. So, that's one aspect. One is the name. So, simple example. You know, you end up, oh, yeah, let's create an object. It's going to be, it's going to hold money. It's going to hold currency, details. It's going to be units and hundreds. And then we're going to be able to set them because for every get there is always a set. And that's the problem. We even have IDEs that do this for us. That's great because I can do the wrong thing without having to type. I've got a shortcut for doing the wrong thing. I used to have to type lots to do the wrong thing. But now, there it is, enterprise coding at your fingertips. But we sit there and go, do we really need this? Could we not just, you know, get rid of that? Oh, yeah. And actually we could get rid of the brief. Oh, good grief. Do you see what I did there? I just turned it into object oriented code. I turned it from assembler into object oriented code. That's amazing. So, this is actually the other aspect. The other side of get is unset is not simply that there is a false symmetry. It's not simply the naming sucks. It is that there is this idea that we need to be more cautious and actually more challenging. We need to challenge it. Do we actually need to change this? There are so many reasons why you should not be encouraging state change in your code. So, to the final item, uncohesive tests. Because it turns out if I do, given this talk a few years ago, people weren't writing tests. But these days people are writing tests. Everybody's writing tests. And some people have really got the idea. They really understand it. And other people are just kind of getting their feet wet. Just getting into the idea. And again, the advice varies. There are so many different schools of thought. But the one I want to challenge, first of all, is the idea that we're just writing tests to find out that things don't work. So, this lovely blurb from Nat Price and Steve Freeman. They wrote the book, Growing Object Oriented Software Guided by Tests. But a few years ago they ran this session XP Day in London, XP Day 2007. And the blurb for the session, are your tests really driving your development? Really had a very key point. I think people overlook when they think of TDD as just testing. As they said, everybody knows TDD stands for test driven development. But people too often concentrate on the words test and development and don't consider what the word driven really implies. So, for tests to really drive your development, they must do more than just test the code, performs its functionality. They must clearly express that required functionality. They must be specifications. In other words, don't just simply test that it works. Explain to the reader what you mean by it works. So, if we see this from the point of view of our recently used list, just keep the feature set small here, the most instinctive way that people will go about testing this, the most common approach, the most obvious approach is this. We just test each feature. We've got a constructor, we'll test it. We've got a count, we'll test it. We've got an indexer, we'll test it. We've got an app method, we'll test it. One for one. It's an obvious approach. It is the most common approach and it's completely wrong. It took me years to come to terms with why it was wrong because I started splitting my tests up years ago. But I kind of really thought about it. But when we end up with a much more literate style, actually, I'm going to skip that slide. It's good stuff. But I'm going to skip that slide in the interest of time. If we go back to our recently used list, we can structure it. The idea is that you should be looking at your testing frameworks. And perhaps you have some nice custom extensions to your testing framework. Feel free to use those. But if you're just using a raw testing framework, find out how much of it can be used to express a hierarchical structure as if you were trying to explain to a reader what is going on. Don't tell them that you're testing something. Tell them what you're expecting. Tell them what's required. And use the hierarchical structuring within your language, whether it is namespaces, whether it is nested classes, whether you have some other intermediate construct. If you have a language that has lambdas and a decent way of constructing lookup tables, so maps and the like, then this is a really useful technique. Here is the name of my test. You can even use strings. And then here is the following block of code. You can be very, very expressive. Don't think of it as test methods. You kind of end up with a much more literate approach. So we see that a new list is empty. We're not testing the constructor. We're simply offering the people a statement. We see that a non-empty list is unchanged when the head item is re-added. We see that any list rejects addition of null items. And what's nice about this is when the tests pass, the names reflect the functionality that you have. It is a list of what the thing does. And it all comes up green. If something fails, then it comes up red. And it tells you that this thing you thought you had, you don't. Now, this, by the way, this cuts through all the questions of should I also include the word should or must or something in the test name. The answer is no. Because that doesn't make sense. If I look at the first item, it tells me a new list is empty. That is a feature of this class. A new list is empty. It's not a feature that it should be empty. It is. Really, there's no discussion. Otherwise, it's red. Yeah? So we're list, so we actually get a listing of the functionality. So the test names work in two environments. They work for writing and they work for reading, which is, I think, the most reading after execution. But the real core of this is the uncohesion. What is the problem when we actually have a test case that is named to test a method? Even something simple like a Boolean method that can really return one of two values. True or false? Surely you need at least two test cases for that. So here is this observation. I stopped, I noticed that I stopped using the terminology test case for a few years. This is very strongly associated with J unit. It didn't really get used as much with N unit. But I've gone back in the last year or so to using it because it becomes very clear when you say that a test, if you say that a test methods are test cases, then it's very logical. This test case tests a case. If you have any other answer, then you have a problem. So if you ask somebody, how many test cases, how many cases are you testing in this test case? Always test three different cases. Well, that's not a test case, is it? Yeah, it's great. You can use language on your side. Well, that's three test cases. What are they called? And factor it out accordingly. So a test case should be just that. It should be a case. And on that note, I've only run by two minutes. I'm around all afternoon. Feel free to come and disagree with me. Don't throw rotten fruit at me. Fresh fruit is much appreciated. Though, you know, I'm trying to, I'm doing a bit of a health kick because it's summer. Thank you very much for your time. Thank you.
 Right, good afternoon. Is that coming through? Yeah, okay. Thank you to Thomas Eccley for  taking a picture of me and posting it saying if anybody looks like an evil genius, it's  me. Thank you. I like that. That's a good start to the day. I'm going to use that one  with my kids. It's just that, you know, do the right thing or else. Okay, so yeah, I  was, you've had a hard choice. I know you've had a hard choice because I've looked at the  program and this is a hologram of me. The real me is in one of the other talks that's  going on at the moment. There's quite a lot on at the moment. Yeah, we're going to let  us learn about holograms. That's right. We're going to look, no, sorry. That's far too technical.  We can't do that first thing in the afternoon. That's why we're on. That's why there's these  speakers on at this time. So I'm going to give you seven things. I like magic numbers,  seven. We're going to go for seven. Seven ineffective coding habits of many programmers.  Chances are you do at least one of these. That's not necessarily a bad thing. I have  done at least one of these. I'm not going to tell you how many. That's the whole point.  We learn by trying things out, but we need to be a little more empirical, a little more  experimental with some of our habits because we acquire habits. That's the whole point.  We pick habits up because they are low energy. You don't have to think about everything.  If you have a habit, then it makes it easy to do something. This is a good thing, not  a bad thing. The problem is though, we sometimes pick up habits without really thinking about  it. We suffer from a lot of cargo cult programming and borrowed habits, habits that we picked  up years ago from different environments that no longer apply. Or habits that we're doing  because, well, everybody else does them. If you are a parent, you may have already encountered  this one. Why are you doing that? Because so and so at school does it. Oh, okay. If so  and so jumped off a cliff, would you do it? This is a standard parent line. You get a  free pack of parental quotes when you get a kid. I'm working my way with my older boys,  turning into a teenager, so we're finding a whole new chapter. It's fantastic. That's  the point. Do we just do things out of habit? Do we follow habits out of habit? That is  the problem. I want to question some here. You will undoubtedly disagree with me on a  few of them. That's a good thing because it shows you're awake. But please reason through  them. Really think about it because as I said, I've tried some of these I've sleepwalked  into in other cases. I've kind of felt there was something not quite there from the start.  So those things, I can't actually speak Chinese, but these have been conveniently translated  for me. A couple of these things might be relevant as I talk. This is probably more  relevant. I write when I'm not writing code. I write a little bit of short fiction. And  this means that I do really care a lot about readability and reading and style. And Doug  Crockford noticed in the very slim volume, unsurprisingly slim, JavaScript, the good  parts, it turns out that style matters in programming for the same reason it matters  in writing. It makes for better reading. And I want to emphasize that that we, many of  our reading habits are precisely that. They are habits. Reading is not a natural state  for a human being. If you've, again, if you've got children, you realize that reading is  one of the last things they actually get to do, that they actually learn. It's really  not one of those things like eating, walking, talking or anything like that. Reading is  a far more subtle thing. And therefore, it taps on parts of our brain that we're not  expecting. It taps on areas that we would consider now when we talk about visual design.  It taps on areas to do with reasoning. It's not a single place. Reading, it covers a multiple,  a very wide range of brain matter, if you like. And it is a learned practice. So anything  you can learn, you can learn something else. But I want to try and talk about this in terms  of properties. Let's, so let's start off with picking out the signal from the noise. Just  as a general point, if you remember a few years ago, it was very popular for the Earth  to end. This was, this was announced on Friday the 13th, which is, you know, by the world,  I was in New York, it was World Trade Center. If you're going to announce the end of the  world, that's a really good place to do it. And a good date. But this guy was just lost  in the noise. Turns out the world didn't end then. And it didn't end in October that year  either. And it didn't end at the end of 2012. We were supposed to have Ragnarok in February.  That didn't happen either. You know, it's a good excuse for a party. So let's talk about  noise. Let's talk about picking out the signal from the noise. Signal to noise ratio. This  is an engineering term. But we often repurpose it. We talk about it as a measure used in  science and engineering comparing level of a desired signal to level of background noise.  But in everyday conversation, we talk about it as the ratio of useful information to false  or irrelevant data. Okay. So in a conversation or exchange. So let's pick on a fairly famous  piece of English. William Shakespeare apparently wrote other stuff, but here, this is the only  bit that ever gets quoted. This is quite a nice piece of English. It's quite dramatic.  He makes extensive use of short words. And yet, it's very, very deep in meaning. Can  we make it clearer? Could we perhaps translate it into office speak or business speak or  marketing speak? Well, conveniently enough, somebody's already done that. A fellow called  Tom Burton in a book, Long Words Bother Me. Very interesting book on language. And he  translated this into marketing speak. Enough with a to be or not to be. Continuing existence  or cessation of existence. Those are the scenarios. Is it more empowering mentally to work towards  an accommodation of the downsizing and negate? Good grief. I mean, you know, this, you could  put this on a PowerPoint in a standard business meeting nobody would notice. This is, it would  just slip in there. And the problem here is that we've added more words. We've added  longer words. Have we actually added any meaning? No. And this is the problem. We have a lot  of habits. Without realizing it, we add noise to the code. So we can take, so this is one  of those little examples. I kind of recycle a bit. Recently used list, very simple example,  a list that holds your recently opened files. So a list of strings, but it has the property.  Just go in at the head like a stack, but they're also unique. Like a set. When you reopen a  file you have already opened. It doesn't occur twice. It just goes in once. And I use it  as a programming exercise. It's a really good little lab. And so one group, one pair a few  years ago produced this, this C-Shop. And they said, well, we finished the exercise,  but we're really not sure that, well, we're not happy with the code. Because the kind  of model answer is about this long. Now, what's interesting is not simply that it takes up  half the space, but when you actually look at the lines of code that do stuff, it's  about a third. So if we get rid of all the curly brackets and other spacing forms and  declarative noise, then there's a very big difference between the two. You know, five  lines versus actually quite a few more. Imagine this style carried out over a whole code base.  It's not the case that the example on the right is easier to read than the one on the  left. I want you to think, what happens if you use the same kind of thinking over a whole  code base? I've seen those code bases. You're sitting there looking at classes of thousands  of lines long. And you know that in there somewhere there is a small class struggling  to get out. But it has identical functionality. Actually, the one, that one's slower than  that one. So the, so the, so there is this case. There's so much noise. Which one do  you want to work through? It's greater cognitive effort, more cognitive load. One of the most  common sources of noise is comments. Thanks to Oracle for this one. But as I've, so there's  the real, you know, all of that just for Hello World. I love the fact that they listed as  a Hello World app. That makes it sound so grand. But one of the things that I've, I've, I  noticed I used this for a couple of years this slide in different contexts. But I, I  realized after a while when you actually cut through the noise and you look at the one  line that actually does something, it's wrong. There's a missing comma. Oh, it's wrong in  English. I mean, the Java's fine. You can convince a Java compiler to do anything. Yeah.  The English is wrong. It's missing a comma. It should be Hello, comma, World. Okay. This  is really important. It's not just trivia. I'm not just picking, picking minus syntactic  points here. There's this kind of classic saying people say, you know, there's a difference  between let's eat grandma and let's eat grandma. Punctuation saves lives. All of this and  they get the one thing that matters, the real piece of communication to the user and it's  wrong. You're never going to notice that with all that noise. So a long time ago when I  was first learning C, one of the things that was given to me was this article, well, this  paper by Rob Pike. He wrote it in 1989. So I must have read it fairly soon after. Notes  on programming in C. And there's some really good stuff in here. And there's a couple of  things that definitely show its age and its time and its language. But as he says, comments,  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. Now let's turn that around. He's sort of saying clarity  is a consequence. You know, if it does this, then you shouldn't need comments. Now let's  turn it around. Use good type names. Use good names in order that you do not need any auxiliary  mechanisms. You may need some, but the idea is minimize that which the code cannot say.  Just get rid of the noise. You may not be able to eliminate it completely, but the idea  is it should be your goal to rewrite the code. Sometimes a very useful technique is to imagine  that somebody has removed the commenting feature from the language. How would you write your  code then? Okay, for some people, they probably will make the slightest bit of difference.  But for those of you who are here, it will. Think about it. What would you say? Would  you say anything differently? Okay, say it like that. And then allow yourself comments  back. Is there anything left that you would also like to communicate to the reader? And  often it's the stuff that's not obvious. Second comments aren't checked by the compiler.  Actually quite frankly, they're not checked by the programmer either. So I don't know  who the audience is. Yeah? The compiler skips and programmers skip. We even use different  colors in our IDEs. I've even seen people use white on white background in order to  skip that. Some IDEs come with the ability to fold away the comments because that's how  important they are. So we don't read them. And if you read them, then it's ultimately,  it's a bit like reading the instructions. It's a sign of defeat. Yeah? I bought a new  Blu-ray player last week. And I sort of strode into the house proudly with this one. None  of the cheap ones are only good, I said to my wife. Oh. But it's not the most expensive  one in the shop. Great. She knows how much the most expensive one is. But it was quite  good. And she said, you're not going to look at the instructions, are you? No. Yeah? That's  the fact. You can file those away wherever you file them. I'm going to set this up because  I am programmer. And if it doesn't work, then it's the designer's fault. I got lucky. It  worked. So the point is there's no guarantee this stuff is right as we just saw with the  distraction and the code level. But the other thing is the, there's a visual aspect here.  The issue of typography, comments clutter code, I'm going to come back to that visual  aspect again in the next item. But I think my favorite piece in this Rob Pike paper was  this. And as he says, don't laugh now. Wait until you see it in real life. In real life.  I did laugh. And then five years later, I found it in production code. It's just that I was  stopped in there and I was reminded. I said, I've seen, yes, somebody actually wrote about  this a few years ago. Absolutely astonishing. If you are, if you do not know what this is  going to do, you have no business looking at this code. Okay? It's really not in your  place. Yeah? So we have this other issue. So I tweeted this a while back. It seems to  have been retweeted quite a lot. Common fallacies is to assume authors of incomprehensible code  will somehow be able to express themselves lucidly and clearly in comments. If you think  about it, because I've often said to people when we've talked about comments, they say,  oh, well, you know, programmers sometimes, you know, the code can't be, can't be easily  understood. So somebody wrote it. Who's going to comment it? The programmer that wrote it.  So we're going to get the same person to write the comments and they couldn't clearly express  themselves. I mean, some things are genuinely hard, but quite frankly, most code doesn't  fall into that category. And if you can't express yourself fluently in code, it often  means that you're on a learning curve or, so that's the good bit, it's always nice to  be able to say, look back and go, damn, I was such an idiot. That's great. It shows  progress. Either you're on a learning curve or you flatlined. Your learning curve is dead.  That's it. So there is this question. We need to really revisit this stuff. This stuff gets  in the way. Now, this kind of suggests that we want to look at other aspects of the code.  What I want to look at here is the one that people say, you can't touch that. You can't  talk about that, Kevlin. You're going to talk about indentation and spacing. But don't you  know that that's not a reasonable conversation that you can have. You will never have a rational  conversation about spacing with developers. Just leave that one alone. It's a personal  preference. It's untouchable. It's like they're talking about the baby's names or something  like that. You just don't go near it. Yeah, that's why I put it number two, not number  one. I'm going near it. Right. So, remember this? Remember this? How would a programmer  do it? They do it like this. We have a bit of a problem here. We have a bit of a problem.  Let me show you the shape of the problem. So, this is slightly beyond HD. HD is 16 to 9  in terms of its ratios. But there are some 21 to 9 screens coming out. And we fall in  love with our high resolution monitors and our widescreen monitors. You can actually  now project the whole of the Serengeti across your workspace. And it's magnificent. And  it's beautiful. And you need a pair of binoculars to see all of the antelope from one side to  the other. After a hard day's working, your neck is aching because the code has been going  from one end to the other. And this is the problem. This is how many programmers lay  out their code. They say, well, that's great because I've got a big screen. We don't need  to live in the years of 80 columns and 24 rows anymore. Yeah, yeah. Because we've got better  technology. What is this, we? I'm still wearing the same eyes. Actually, they're not, no,  they're worse than they used to be. Okay, you still got, we haven't evolved yet. We have  not kept up with screen resolutions. Come back in 2000 years. Let's see how we're doing  then. Probably need another 10 or 20,000 years before it really takes hold. But that's the  thing is our ability to perceive has not changed. The bit we can focus on, it's a tiny little  bit there. We've got peripheral vision to around there. When you read, if you watch any kind  of eye tracking study, it's very interesting. People don't read the way you think they  read. And if you have to start moving ahead, that's never a good sign. So the problem here  is that that's column 80. We get a lot of stuff out here. And I had some very interesting  episodes. There was a couple of years, actually, I was here in Oslo, doing a code review with  one group. I do strongly recommend doing code reviews on whatever is not your work machine.  Because where do we read code? We read code. We read code on laptops. That's got an HD  resolution. That's fine. Put it on a decent screen, double headed monitor, no problem.  Put it through a projector, though. And there's loads of projects. I saw a projector the other  week that was still at 1024 by 768. Most projectors are sort of 1280 or above. But the point there  is use a projector. And this is exactly what happened. The program, we had two lines of  code following each other. And they were identical up until the right hand side of the screen.  And the program said, oh, yeah, they are actually different. This argument list is quite long.  And the method names are quite long. But they differ somewhere around here. And then I think  the comment that you always have to chuckle at, it worked on my machine. That's not just  about it ran on my machine, but actually does the code look any good? This is another, I  tweeted this a while back and somebody else made the other suggestion. And very good observation.  I hadn't really thought about it. But increasingly, I read a lot of stuff on tablets and phones.  Try doing a code review. Go to the coffee shop. Take your tablet with you. You'll suddenly  say, oh, well, this would be great. Hang on. There it is. The point there is you need to  appreciate how people read. Don't work to one resolution and one idea of how people read.  And actually find out how people do read. Turns out they read a lot more like this. I'll give  you column 80 rather than column 60. See if you can stick to double digits. I tend to  use column 80 like a sort of a soft, soft stop. But if I hit three digits, I know something's  going wrong. And when I pointed this out to this guy, he said, so you mean 160 is too  long? Yeah, I think so. And he looked at this one that was 200. But that's nothing. I visited  the company a few weeks ago. And it was like a graph, the code. If you zoomed out, it was  just sort of, but, but, but, so we went out. We found something at column 352. It was a  line that went out that far. We were kind of disappointed that there weren't an extra  13 characters to make it up. There were one column for each day of the year. But the point  there is that that's difficult for people to read. Why is this difficult for people  to read? How do people lay stuff out? How do people really lay stuff out? Go and pick  up a newspaper. Go and look at a website. And you will discover that people do not actually  try to use up the whole horizontal space. In fact, they actively seek to not use it.  This relates to a point that we need to embrace. It's a thing called clean design, or it's  visual design basically. Now normally when people think of clean and the word code, they're  sort of thinking Uncle Bob and his recommendations. That's great. That's the functional side of  it. That's the syntactic, the semantic. But I want to talk about the visual aspect. To  answer the question, what is clean design most succinctly? A clean design is one that  supports visual thinking. So this idea of visual thinking, the idea of arrangement so  that people can see what's going on. If you look at the way that posters are laid out.  If you look at the way that ordinary web pages are laid out. And look at the pages that you  think are good. Look at the pages that you don't think are good. See how they structure  it. It's the same human visual perception system that's responsible for code. So therefore  you need to think how somebody is going to read this. So this is the idea. People can  meet their informational needs with a minimum of conscious effort and also physical effort.  You don't really want to be doing that a lot. You convey information by the way you arrange  a design's elements in relation to each other. When you put things above each other, it signifies  one thing. When you put things apart from each other, it signifies something else. And  this is something important because what you're doing is you're actually showing the reader  how to think about something. They're not just looking at the words and the parentheses.  You are showing them these ideas are together. These ideas are separate. These ideas follow  this idea. That's what you're doing when you lay things out. Now you may not be aware you're  doing it, which is where we end up with a slight problem. There's a bit of a gap sometimes.  And there is this idea of a term I came across just last month. Structural honesty. Does the  structure of your layout, is it honest? Does it convey what you actually are trying to show  with the syntax? That's a very interesting idea. So, you know, if the visual relationships  are obviously accurate, this is fine. But if they're not, your audience is going to get  confused. They will have to examine your work carefully. Now, you may be so proud of your  work that you think this is a good thing. I put so much effort into it. Of course, I  want people to examine it carefully. Or alternatively, there is, it was hard to write, it's going  to be hard to read. Yeah? You've got different ways of coming at this. But I want to talk  about this from another point of view. So, the first thing is structural honesty. That's  the first requirement. Because people normally assume, as I said before, that spacing is  somehow a personal or just arbitrary cultural preference. Java programmers do it one way.  C sharp programmers do it another. C programs have half a dozen different ways of doing  it. Python programmers have one way of doing it and there is no other. There's lots of  different variations. And we assume that these are somehow given and are not open to question.  I'm going to question that. I don't think they are a given. So, let's look at some things  in terms of visual honesty and visual structuring. So, how not to lay out a method header? I  see this so often. It's so common in code. I'm going to blame most of the, am I going  to blame the Java guys? Yeah, I'm going to blame the Java guys. They do this most. Followed  rapidly, hot on their heels by the C sharp folks. I tend to find this less in other languages.  I'm not going to say they, I don't find it. But in terms of cultural tendencies, the problem  with this is this is about as structurally dishonest as you can get. Because where is  the argument list? You're only allowed to use one finger. Ah, see the problem? We have  a phrase, an argument list. Okay, where are the parameters? They're in two places, but  it's one parameter list. It's on two different sides of the screen. Much more exciting if  you've got really long names because it could be off the screen. So, are you calling that  single argument method? Which single argument method? I'm calling the two argument one.  No, there's no two argument ones here. Well, yeah, there is. Just keep scrolling. Keep  scrolling. There it is. The point here is that this is about as dishonest as you can  get. It's kind of like, ha ha, full juice. There's one over here and one over here. So,  if I had to pick the worst style, this is probably going to come close to it. I'm not  going to tell you what the right style is. I'm going to tell you what the right properties  are. We need to approach any convention that we adopt in terms of requirements, not end  user requirements or customer requirements, but requirements. What do we want from a layout?  The first thing I want is this idea of visual reasoning and structural honesty. So, if you  got that, that's a good start. So, that suggests you can do it like this because the arguments  are grouped. They are vertically grouped. There is one consistent reading order. Alternatively  horizontally, there is one consistent reading order. I don't care which one you do. You  can even try and mix them about a bit. I don't care, but the idea is they both have this  property. But there is one to not do. This one is very common. Now, we may say, well,  that's fine. I don't see the problem with that because it's structurally honest. It  is structurally honest. Everything is in the right place. The argument list is in one place.  It is vertically organized. It has a simple structuring principle. But the problem with  this is nothing to do with that. It's to do with the second requirement, which is sustainability.  What do I mean by sustainability? Well, let's look at a couple of method calls. Same principle.  We have that there. We align it with the opening parenthesis. I'm going to say, do it either  like that or like that. There's a couple of other variations. I don't really care because  the one thing that we know happens in code is change. Change is the most common thing.  The minute you do a rename, boom, it's wrong. It becomes structurally dishonest. In other  words, the reason I don't favor that style is that unless everybody is working with an  editor that naturally aligns this, you would more likely to find this in the list space  than you are in the enterprise language space, then this first style is doomed to failure.  It will never work. That's a very, very grand statement to make. It will never work. Okay,  let me put it another way. It will only ever work if nobody ever touches the code. Again,  never. In other words, it's one of those techniques, one of those ones that comes out and it looks  right the first time you write it. But from that point on, it's doomed because the minute  that anybody does anything that causes a shuffle, it is unstable. It's unsustainable. I'll leave  aside the fact that you end up with this kind of alignment problem that it bounces around  the page as you scroll through a file. It's completely arbitrary alignment. It's like  rolling dice to figure out which column should I put something in. But that's a personal  preference. I want to attack it on the fact that it's just not a workable style. This  is the one that upsets people most, I've noticed, whenever I say this. I actually had somebody  come up to me after saying this, say, well, I disagree with you. Well, of course you would.  You know, get over it. So every time I do this, I make sure I go around, or every time  I do a rename, I go through the whole code base to check that everything is still aligned.  This is what we call a high maintenance approach. It takes a lot of work. Why do you choose  an approach that's difficult to maintain? Do your colleagues also do what you do? And  then a dark cloud appeared over his head. No, they don't. And I said, there is the floor  in your otherwise, well, heavy, heavy working plan. So the point here is, yeah, it kind  of looks pretty the first time you do it, but, you know, we can read anything. Choose  something that's easy and sustainable over time. Which means I'm now going to talk about  something else to do with spacing. Which is this point about arbitrary alignment positions.  So this is a, this is a formatted according to kind of orthodox Java style. And if we  look, we see that there are a number of points of alignment where the eye is drawn. It's  drawn to that line. It's drawn to that line. It's drawn to this line. We've got three lines  whose only meaning is we just happen to be here. And then we've got three lines over  here that actually represent logical indentations. So we've got six points of alignment and not  very many lines of code. It's quite busy. Okay? Your eye is having to do an awful lot  of work. So reduce the number of points of alignment. Stop pushing people out to the  right-hand side. Okay? If something's important, it should be on the left. Is the parameter  list of a method important? You betcha. It should be somewhere people can read it. It  should be either a natural follow on or immediately to the left. People read from the left. Okay?  Okay? There are alphabets that don't, but we're talking code here. Pretty much all languages  that we're dealing with go from the left. So therefore adjust to what people are doing.  Don't maintain a fantasy. Putting your argument lists, putting your arguments over to the  right. It's a stupid place to put them if it's off the screen. But we've also got this  arbitrary alignment thing. So let's realign it. Well, this is better in one sense because  we've now got three points of alignment or three lines of alignment, which is great.  There's only one problem. Visually, what does this look like? Well, if you kind of squinted  it, actually, I'm not going to, don't worry, don't squint. We'll just replace them all  with X's. Let's just get rid of all the punctuation and see what you're actually seeing. Now,  I can't tell the difference between the argument list and the first declaration. This style,  there's a technical description of it, does not work. Okay? It does not work because visually  there is no distinction between two fundamentally different ideas. Here are the parameters to  your method and here are your local variables. That's kind of important. Call me a bit old-fashioned.  I think that's quite important. So we have a couple of choices. Again, I don't, well,  there's more, but again, I don't care which one you choose. You can either sit there and  go, whoa, double indentation. Okay? Put them somewhere else. That kind of looks okay. It's  visually distinct. Alternatively, stop putting your Kelly brackets in the wrong place. Yes,  there is such a thing as a wrong place. It took me 25 years to discover it. I've used  all the styles, even some of the crazy ones. I've tried everything and it's just that actually  there are reasons. I can read all of them, but it turns out there are some that actually  make more sense and it's this idea of sustainability and visual design that actually makes, tips  the balance. So that's some food for thought. Let's deal with something slightly less contentious  now. Oh, yeah. And of course, that obviously has visual distinction. Let's talk about Lego  because Lego is good. Any excuse to talk about Lego is a good excuse. Except that we have  a bit of a problem here. Lego naming. What's Lego naming? Well, Lego naming is where you  take sort of parts of Lego. I'll have a kind of a red 2 by 4 and I'll stick that with a  kind of like a white 2 by 2 and I'll put this together and I will create a name. This is  kind of like what my kids used to create in terms of those towers that you're sitting  there going like that's going to fall, that's going to fall, and there will be tears. This  is how we name things. What's the process? It's called a glutination. Linguistic morphology  is where you derive complex words by gluing together other words. Some languages do this  more than others. Okay? So here's the longest word in the English language. I think it's  kind of ironic because it was invented to be the longest word. Nobody actually uses  this and it's basically made up of Greek and Latin rather than English. So, yeah, not interesting.  Here's something closer to home. This is a bit of Norwegian. Yeah, you bet. I'm not  going to pronounce it. However, I'm afraid, yeah, you know which language is going to  win. Of course, it's German. Although technically this word was, it's no longer a word because  it was retired last year. It's about 64, 65 characters. It refers to an EU regulation  that is no longer an EU regulation. The abbreviation is 12 letters long. But it turns out that  even if you can read Norwegian and German, this is not a very natural way of dealing  with words. This is too long. You can't grasp it in one go. You have to kind of pause. You  will eventually abbreviate it. So what's the problem with our words? Yeah, identify names.  There's even sites that make fun of this kind of whole approach of stacking standard terminology  together. There's method name and class name. You can just go there and refresh the screen  and it will give you new class names and method names. Just made up of standard parts. What  are the standard parts look like? Well, they kind of look like this, you know. It's one  of those things. Oh, it's a proxy service manager controller. Factory. Factory. Just remember  for every factory, factory you ever create, somewhere on the internet, a kitten dies.  Okay? That death is on you. We just take these names. We add them together. We say, oh, look,  I'm creating meaning. It's now really meaningful. I refer you back to the Shakespeare example.  I've made the name even longer. I've poured more meaning into it. No. What you've done  is this is like homeopathy. What you've done is you've diluted the meaning till it's all  gone. There is no medicine there. There's only sugar. That's it. It does nothing for  you. But does it really take a long name? I mean, sometimes we end up with these names  and you're sitting there going, well, I can read all of the parts, but I have no idea  what the whole thing means. Yeah, but surely you know what a manager control proxy is.  Funny enough, not today. But we've got a factory for one of those. Don't even begin on the  name. It tells us something about our coding style as well. It tells us perhaps that we  are failing to find the right abstractions, the ideas that name things directly. We often  find this as well. There are these naming habits. It doesn't even have to be long names.  So here's one from a piece of client's code that I counted a few months ago. It was about  three months ago. And even at this short length, condition checker, not a long name. Check  condition, not a long name. But I was looking at this thing. It's like condition checker.  We've got validators and checkers and all kinds of stuff. And I said, what's the condition  checker do? Well, we call it to evaluate a condition. You mean it is a condition? Yeah.  And what do you check it for, whether it's true or not? You mean this. Yeah. Oh, that's  what it means. That's what it is. It's not a condition checker. There's not some kind  of condition sitting out there in sort of a platonic space somewhere. There's not some  kind of abstract condition that we somehow have to reach. Is there a fire? Not something  that we actually have to go out and check for. There is this idea very, very direct. It's  a condition. Is it true or is it not? And it's a very simple statement. Now, when you  start applying that, it also takes you other places. So here's something. I was going to  do this in C sharp. I decided, no, I'm going to put this up in Java because it allows me  to use the throw signature, which is not something I'm a big fan of, but it allows me to cover  two things at once. We have a very standard vocabulary. And sometimes people say, oh,  it's okay because it's standard. That means I know how to read it. Yes, the problem is  you may not be communicating meaning. So create connection. That doesn't seem particularly  harmful. But how many things do we have that are called create that return something? Do  we need the word create on everything that creates a new object? Is that helpful information?  Remember you have a fairly limited bandwidth. There is a reader out there and you have a  few characters in which you can say, this is what I want you to notice. And you might  not otherwise pick up. If you try to tell them absolutely everything, here is a method  that uses objects. Well, they probably already know that. So don't tell them that bit. Here  is a method that's going to return you something that has been created. Okay. But give me a  better sense of it. And then we have a habit that I, you know, I was completely blind to  this from till about 18, 20 months ago. Completely blind to it. We put exception on the end  of exception in so many cases. This is a very common.net and Java habit. And I noticed I  was going back to some C++ code and I suddenly thought, why am I not putting the word exception  on the end of all the exceptions? And I suddenly realized, because I don't need to. Think about  it. So first of all, what are you really doing? You are creating connection. This is a mechanical  description. What are you, what is your intention? I am trying to connect to that thing over  there. So what we've done is we've ended up doing object oriented assembler. Instead  of saying, I want to connect to that, we've kind of hidden that and said, I'm going to  create a connection rather than our intention. I want to connect to that. I'm going to, but  if this doesn't work out, I'm going to throw you an exception. What does the exception  indicate? It indicates a connection failure. It does not indicate a connection failure  exception. Okay. My name is Kevlin Henney. It is not Kevlin first name, Henney last  name. Okay. Of course, it's, of course it's an exception. What else could appear in a  throw clause? What else could appear in a catch? What else has a name like connection  failure? In fact, it's, it's kind of interesting. If you strip that exception off, you can  actually find the good exception names. So in the Java library, there is illegal argument  exception. If I strip off the argument or other extra of the exception, illegal argument,  that's actually quite meaningful. That's quite a good one. On the other hand, in.NET library,  I find argument exception. If I strip off the exception, I just get argument. That  tells me that we haven't really expressed ourselves. And likewise, in both cases, there's  null pointer exception and null reference exception. So when you receive that, that  means that something bad happened. What was, what was bad? A null pointer. No, there's  nothing wrong with a null pointer. Tell me what was bad. D-referencing a null pointer.  That's bad. So that's the name of the method or the name of the class. So try that out,  you know? You probably have stones thrown at you by your colleagues. But, you know,  I recognize that's the harder one to do, but at least the intention elsewhere. Try and  communicate the intention. Don't always talk about the mechanics. So speaking of that,  let's talk about abstraction or lack of it. Under abstraction. So this is a slide that  I've used a few times. This is from a blog by Philippe Calçadeau. It's about five years  old. Unfortunately, the blog's gone offline, but you can still find it using the Wayback  machine. And it's a technique that I've encouraged people to use. And I've actually visited companies,  visited a company last year where they had all of their projects, had tag clouds up on  the wall. And this idea is very simply, you get your source code, you strip out all of  the comments and all of the string literals, and you push through, push this into something  like Wordle or some other tag cloud generator, and you find out what the overall map is of  your code. It's a very odd way of looking at code, but we've already looked at code  oddly in one sense. I replaced all of the code with Xs. And that's the technique I think  I picked that one up from Michael Feathers. There's another technique that I use which  is zooming out. Look, choose the smallest font size. You possibly can and see what the  code looks like. It gives you an unusual perspective. Okay? Code is complex stuff. You need more  than one point of view. This one strips out all of the, well, all of the code structure.  We're just left with the names. What does that tell you? Well, in this particular case,  it tells us that we really like strings. And lists are quite good as well. And we've got  a few integers thrown in for good measure. Wow. So that's what your system does. Your  system does strings with a few lists and occasional integers. Gosh, that must be really exciting  to work on. Because I work on this system. What do you guys do? Oh, we do stuff with  pictures and printing devices and products and paper. Oh. You still got any strings?  Yeah, but strings are really small, isn't it? This is the point. We're communicating  in the language of the domain. The domain is about these things. We've ended up with  object-oriented assembler. We have, without thinking about it, the intelligence that goes  on up here, we thought, oh, I can use a string for that. I can convey that using a list.  Like, rather than what is it, what is the idea? Shall I name the idea? And using a language,  you know, most languages allow you to introduce a name for the idea. So we end up with type  names. And so therefore, really enriching that. And that idea sort of riffs off a guideline  from Dan North, code in the language of the domain. And I think this is a really interesting  example. I really like it because it doesn't use any programmer abbreviations. And yet  it's not entirely clear what's going on. The only abbreviation in this piece of code is  ID. But that's a real world abbreviation. It's not a programming abbreviation. So every  single word there makes sense, but the whole thing doesn't make sense. Should we have a  comment? Well, no. This is the whole thing. We have not abstracted enough. To abstract  is to remove something. In this particular case, we can actually extract the method,  not merely abstract it. And we end up with something that's far more meaningful. All  of that mechanics goes away. And that's the problem is as it's this kind of balance of  skill that we have, we care very much about the mechanics, but we also care about the  abstraction. Sometimes we get a little confused between the two. We put the mechanics where  the abstraction should be. We mix our levels up. That's the intention. Beneath it is the  mechanics. And so there's this idea that in anything other than a hundred line script,  you really want to start organizing the mechanics away according to intention. When the system  gets large enough, even the intention becomes mechanical. So you have another layer. But  this is the idea. We have a choice here. And when it comes to code, when it comes to code,  you have only three ways of expressing yourself effectively. Names, spacing, and punctuation.  And the language takes care of most of the punctuation. So that's it. That's how you  communicate to other people. Of these, the names are the most important. We've also looked  at the spacing. These are your only tools. The other thing is to look at things from  a different perspective. Let me offer this one. This is one from Gregor Hopper. It's  very simple idea. What is the perspective we want to encourage people to look at? Well,  look at it, look at a method from the outside, not just from the inside. We often write our  code inside the method. And when we see our parameter names, we see them as well named.  We hope. We see them as well named. And we can see them and there's no problem. They  make sense within the body of the method. But what happens when we look at it from the outside  and try and use it? Now, if we look at this, we see, you know, parser, yeah, I can understand  what that is, process nodes, yep, that seems to make sense to me. Text, yep, I have no  problem understanding that. False. What? I have no idea how that relates to parsers,  processing nodes or the text. What does the false mean? Why is it there? What does true  do? Okay? And there is this sense that what somebody has done is they've said there are  two options. Now, can I think of a data type that only has two options? Oh, yes. Booleans  only have two options. Great, I'll use one of those. And the problem is what is true  in this case? I have no idea. There's lots of ways of solving this, but the idea is  that on the inside of this, it probably looks quite sensible. You know, maybe it says,  is formatted. I can't even remember the example. But in the body of the method, it makes sense.  From the outside, true and false make no sense. The most extreme example I know of this was  a code review I did a few years ago where there were five arguments that were all Booleans.  And on the inside, it looked perfectly sensible, if is enabled and can have logging. Oh, it  all looked great. From the outside, true, true, false, false, true. What? There's no  kind of sense there. You have to look at it from the outside. But that kind of long argument  listing. Keep this in mind. We often under abstract. We end up with these kind of long  arguments. Okay? Yeah? Now, different people have different tolerances. I used this quote  with a team a couple of years ago. Because I was looking at some code. I said, look,  all your constructors have 14 or 15 arguments. And then I used this quote. They seemed unmoved  by this. And then one guy piped up and he said, oh, I think I understand the problem.  He rummaged through the code, pulled up this thing and put it on the projector. He said,  this constructor takes more than 70 arguments. I said, ah, I see the problem. As far as you  guys are concerned, when you look at 10, you're thinking, wow, we wish we could have that few.  You know? I'm saying it's like a lot and they're thinking, no, no, we aspire to have as little  as that. But over the years, when I've retold that story, the record now stands at 326.  The guy sent me the diff from the point that it was 325 to 326. You know? We had the conversation  that it was 325. He emailed me a few weeks later. And here's me adding another one. That's  the point. It's statistically, once you hit 10, 10 is as good as 11 is as good as 12.  And it will continue on this way. Okay? So, yeah, it's a whole project just to call the  method. You know, what are you going to do, the sprint call that method? Okay? Good luck  with that. We'll see you on the other side. So, abstraction. Abstraction is related to  something else. Not whiskey, but it would be nice if abstraction were related to whiskey.  That's distillation. That's slightly different. What are we talking about? Unencapsulated  state. Specifically, the relationship between this idea of abstraction and encapsulation,  if we look at what the dictionary has to offer us, enclose something in or is it in a capsule?  There's a boundary. You're putting, there's an inside and an outside. You're hiding something  and revealing something else. But there's something else. Express the essential feature  of something simply. This is abstraction, the essence of something to abstract what  is it? What is it really about? What is the idea of the thing? And provide an interface  for a piece of software to simplify access for the user. Now, this relates to a usability  design concept known as an affordance. A quality of an object or an environment which allows  an individual to perform an action. So, a knob affords twisting and perhaps pushing while  a cord affords pulling. It affords a particular thing. So, a door that has a pulling thing  affords pulling. So, if it has a little sign that says push, that's bad design. That's  like a comment slash, slash, push. Yeah? We've talked about comments already. This is noise.  If you want the user to push, give them a thing that they cannot pull. It's a very,  it's a very simple idea. If you want them to pull, give them a pulling thing. It's very  simple. If you want people to use objects in a particular way, then offer them the methods  that allow them to do that easily. If you say to people, you can default construct this  object, but then you have to call this method and you have to call this other method to  properly initialize it, then you've actually missed the opportunity of constructing during  a constructor. That's its point. Yeah? The idea is if there is one correct way to construct  an object, then offer that as the only correct way. You really want to align the affordances,  the usage of the thing with your intended usage. So, let's go have a look at our old friend,  the recently used list. Let's go back to that one. And here is a very common implementation.  I've re-rendered it here. What we've got is a very common implementation is that somebody  will say, I'm just going to use a.NET list. I'm going to use a.NET list and then I'm  going to have a property, a get, that's going to return that list. And then the bit that  does the clever bit, the add method, because that's got to deal with uniqueness and it's  got to deal with putting at the front rather than the back, will provide a method for that.  But basically anything else that the user wants to do, they can do through this. And  so we see how people use. So they initialize it, they go ahead, that's fine, initialize  it. They go in there, they add, hello world, that's great. How many items are there in  there? Ah! So, first point of call, we have no count property. There is no way to query  the size of a recently used list. So we basically have to go in a bit, go to the items and ask  for the count. But it gets fun because now what we can do is having got the items, we  can sit there and go, oh, I'm going to add a duplicate string. Now, if you remember what  a recently used list is, it holds its items uniquely. You cannot add duplicates, they  move. When we go and look at the size again, it turns out that the size is now two. So  it holds two duplicate items, which is supposed to be impossible. Well, apparently not. And  we can also put nulls in if we want, which we're not allowed to do in the original version,  a few slides back. So what we've done here is we've effectively, I mean, everything is  private, the word private surrounds the list. But the clue that we have a problem is this  message chain or sometimes called a train wreck because you get the dots adding up. Something  dot something dot something dot something is a very strong clue that you have, you're  revealing far too much internal structure. It's a very strong clue. But we knew this  already. There is a piece of, we can actually pick up a piece of advice. Going back to the  1980s, the young Kiefer Sutherland, is anybody watching 24 at the moment? New 24? No? Okay,  it'll get to Norway eventually. Kiefer Sutherland goes across London and people have been saying,  you know, that's amazing. He managed to get from one side of London to the other in under  10 minutes. The mayor of London needs to hire him to redesign the roads because clearly  this guy knows something. But this is one of the 80s vampire movies that preceded all  the rubbish vampire movies we've had in the last few years. But people, whenever they  think about how they're going to protect themselves from vampires, because I know you do, you  wake up at three o'clock in the morning thinking, like, what if a vampire came through the door?  I mean, I obviously excuse those who are a bit worried about the zombie apocalypse. I  live in the city of Bristol and it turns out that Bristol City Council actually has an  action plan for the zombie apocalypse. I think it was drawn up by one very bored council  employee one day. But that's why I like living there. You know, you've got that opportunity.  But I don't know what our vampire strategy is. And people think, oh, what am I going  to do? How am I going to protect myself against vampires? And why didn't that build when I  left? But no, really, vampires are more important. How do I protect myself? People come up and  they say, oh, right, okay, I'm going to need garlic. Yes, we've got garlic bread in the  freezer, so we're good. We're safe. Okay. And what else? Maybe I could drive a stake  through their heart. Yeah, but you've got to get close and intimate. Holy water. Right.  None of that in the house at the moment. Availability issues. You kind of go through all the standard  techniques. Sometimes people misremember, they say things, silver bullets. Oh, you're  going to be disappointed. That's werewolves. You've got to get your right undead. You know,  wrong class of undead. Sunlight. But does it go as far as ultraviolet light? Some models  of vampires say yes. Some models say no. It's difficult to say. But the one everybody forgets,  the greatest protection, because you are at home. Do not invite them in. Do not invite  them in. To quote the film. If you invite them in across the threshold, they can do anything.  What has this got to do with encapsulation? Everything. Absolutely everything. Don't invite  them in. Here it is. If you want people to be able to count the number of items in there,  then give them a count property. If you want them to be able to do stuff, offer it to them.  Your fingers will not fall off through the effort of typing. Okay. But you've also enforced  an encapsulation that allows you to actually flip the representation round. This one we  insert at the front. This one we just transform it and we insert at the back. From the outside,  nothing has changed. From the inside, we've actually reversed the internal data structure.  Nobody noticed. That is the magic of what we mean by encapsulation. What we're saying  is strictly private. It's not just a case of put a private keyword in front of it. It  means really, really private. Now, when I held back from, because sometimes people  think, oh yeah, we've got classes with all these kinds of getters and things like that.  It's such an item, I gave it its own space. So get. Get. Here it is in the Oxford English  dictionary. The Oxford English dictionary is a fantastic dictionary if you are a word  geek. And at this point, I confess I'm a word geek. Because it's of no use to you whatsoever  if you're trying to find out what the meaning of a word is. Because what you will start  off with, it will give you the complete history of the word. Okay? So, you know, the OED basically  has everything going back for a thousand or so years. And it will give you all of the  roots. As you can see, get is quite an old word. And it's cognate with a whole bunch  of stuff in Frisian, Old Norse, and so on. Very useful if you happen to be in this kind,  into this kind of thing. I think this is the most interesting bit, to be honest. And then  there's all those other definitions and usages. It's very boring. But what I want to draw your  attention to is two things. One, if you look at the first column over there, you will see  that there are multiple entries for get. If you look over to the other side, you will  see that the scroll bar is very, very small. That's because it's proportional to the amount  of stuff there is on it. If you print out the definition for get, it comes to somewhere  between 30 and 40 pages in the printed dictionary. It's one of the reasons I don't have the printed  dictionary. You know, you know, it's, it's, sorry, which rainforest would you like to  destroy to print it, sir? No, no, I'm, I'm just going to go and destroy electrons. So,  it turns out that get is one of the words in the English language. There are two words  in the English language that have the most pages of definition. Get is one of them. Yep,  you got it. Sets the other. So, if you wanted to use these words because they're unambiguous  and clear and they have a simple, concise, well-defined meaning, bad luck. It turns out  there's a third word that's not been fully integrated, all the newer definitions have  not been fully integrated into the OED. And this one may also be familiar. This third  word is now overtaken both get and set. That word is run, which apparently we use quite  a lot. Yeah? So, this is, so these are words that have multiple definitions. So, a very  simple one is just, is on the naming. I just think get and set are terrible names. But  get in particular, get. When you have a getter, does it have a side effect or does it not  have a side effect? The one thing the word should tell me is that it should communicate  there is a side effect or is there, there is not a side effect. Is it a pure query or  not? Let's look at how the word is used in English. I go to a cache point and I get money  from the cache point. Is there a side effect? Yes. Disappointingly, my count balance goes  down. You get married. Is there a side effect? Yes. Huge side effect. Life changing. So,  the point here is the word get means move from one place to another in such a way that  it is no longer available at the first place. That's what it means. That's its principal  usage. It does not mean I'm asking you a question. But you see get and set, they're three letters  long and they look so nice together. They rhyme. If, yeah, if English were different,  we probably wouldn't have this problem. And we think, oh, they're kind of opposites. No,  they're not. The opposite of set is reset or unset. These are opposites. So, that's one  aspect. One is the name. So, simple example. You know, you end up, oh, yeah, let's create  an object. It's going to be, it's going to hold money. It's going to hold currency, details.  It's going to be units and hundreds. And then we're going to be able to set them because  for every get there is always a set. And that's the problem. We even have IDEs that do this  for us. That's great because I can do the wrong thing without having to type. I've got a shortcut  for doing the wrong thing. I used to have to type lots to do the wrong thing. But now,  there it is, enterprise coding at your fingertips. But we sit there and go, do we really need  this? Could we not just, you know, get rid of that? Oh, yeah. And actually we could get  rid of the brief. Oh, good grief. Do you see what I did there? I just turned it into object  oriented code. I turned it from assembler into object oriented code. That's amazing.  So, this is actually the other aspect. The other side of get is unset is not simply that  there is a false symmetry. It's not simply the naming sucks. It is that there is this  idea that we need to be more cautious and actually more challenging. We need to challenge  it. Do we actually need to change this? There are so many reasons why you should not be  encouraging state change in your code. So, to the final item, uncohesive tests. Because  it turns out if I do, given this talk a few years ago, people weren't writing tests. But  these days people are writing tests. Everybody's writing tests. And some people have really  got the idea. They really understand it. And other people are just kind of getting their  feet wet. Just getting into the idea. And again, the advice varies. There are so many different  schools of thought. But the one I want to challenge, first of all, is the idea that  we're just writing tests to find out that things don't work. So, this lovely blurb from  Nat Price and Steve Freeman. They wrote the book, Growing Object Oriented Software Guided  by Tests. But a few years ago they ran this session XP Day in London, XP Day 2007. And  the blurb for the session, are your tests really driving your development? Really had  a very key point. I think people overlook when they think of TDD as just testing. As  they said, everybody knows TDD stands for test driven development. But people too often  concentrate on the words test and development and don't consider what the word driven really  implies. So, for tests to really drive your development, they must do more than just test  the code, performs its functionality. They must clearly express that required functionality.  They must be specifications. In other words, don't just simply test that it works. Explain  to the reader what you mean by it works. So, if we see this from the point of view of our  recently used list, just keep the feature set small here, the most instinctive way that  people will go about testing this, the most common approach, the most obvious approach  is this. We just test each feature. We've got a constructor, we'll test it. We've got  a count, we'll test it. We've got an indexer, we'll test it. We've got an app method, we'll  test it. One for one. It's an obvious approach. It is the most common approach and it's completely  wrong. It took me years to come to terms with why it was wrong because I started splitting  my tests up years ago. But I kind of really thought about it. But when we end up with  a much more literate style, actually, I'm going to skip that slide. It's good stuff.  But I'm going to skip that slide in the interest of time. If we go back to our recently used  list, we can structure it. The idea is that you should be looking at your testing frameworks.  And perhaps you have some nice custom extensions to your testing framework. Feel free to use  those. But if you're just using a raw testing framework, find out how much of it can be  used to express a hierarchical structure as if you were trying to explain to a reader  what is going on. Don't tell them that you're testing something. Tell them what you're  expecting. Tell them what's required. And use the hierarchical structuring within your  language, whether it is namespaces, whether it is nested classes, whether you have some  other intermediate construct. If you have a language that has lambdas and a decent way  of constructing lookup tables, so maps and the like, then this is a really useful technique.  Here is the name of my test. You can even use strings. And then here is the following  block of code. You can be very, very expressive. Don't think of it as test methods. You kind  of end up with a much more literate approach. So we see that a new list is empty. We're  not testing the constructor. We're simply offering the people a statement. We see that a non-empty  list is unchanged when the head item is re-added. We see that any list rejects addition of null  items. And what's nice about this is when the tests pass, the names reflect the functionality  that you have. It is a list of what the thing does. And it all comes up green. If something  fails, then it comes up red. And it tells you that this thing you thought you had, you  don't. Now, this, by the way, this cuts through all the questions of should I also include  the word should or must or something in the test name. The answer is no. Because that  doesn't make sense. If I look at the first item, it tells me a new list is empty. That  is a feature of this class. A new list is empty. It's not a feature that it should be  empty. It is. Really, there's no discussion. Otherwise, it's red. Yeah? So we're list,  so we actually get a listing of the functionality. So the test names work in two environments.  They work for writing and they work for reading, which is, I think, the most reading after  execution. But the real core of this is the uncohesion. What is the problem when we actually  have a test case that is named to test a method? Even something simple like a Boolean method  that can really return one of two values. True or false? Surely you need at least two  test cases for that. So here is this observation. I stopped, I noticed that I stopped using  the terminology test case for a few years. This is very strongly associated with J unit.  It didn't really get used as much with N unit. But I've gone back in the last year or so  to using it because it becomes very clear when you say that a test, if you say that  a test methods are test cases, then it's very logical. This test case tests a case. If you  have any other answer, then you have a problem. So if you ask somebody, how many test cases,  how many cases are you testing in this test case? Always test three different cases. Well,  that's not a test case, is it? Yeah, it's great. You can use language on your side.  Well, that's three test cases. What are they called? And factor it out accordingly. So  a test case should be just that. It should be a case. And on that note, I've only run  by two minutes. I'm around all afternoon. Feel free to come and disagree with me. Don't  throw rotten fruit at me. Fresh fruit is much appreciated. Though, you know, I'm trying  to, I'm doing a bit of a health kick because it's summer. Thank you very much for your  time.  Thank you.
Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_0_4547.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_4548_4895.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_4896_6587.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_6588_7607.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_7608_7919.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_7920_8183.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_8184_8927.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_8928_9995.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_9996_11099.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_11100_12719.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_12720_14615.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_14616_19283.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_19284_20159.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_20160_21863.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_21864_22727.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_22728_22823.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_22824_22895.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_22896_23195.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_23196_23327.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_23328_25523.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_25524_28271.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_28272_29903.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_29904_31355.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_31356_32687.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_32688_34223.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_34224_36755.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_36756_36803.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_36804_37943.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_37944_38003.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_38004_38135.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_38136_41279.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_41280_43199.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_43200_44615.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_44616_45383.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_45384_46199.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_46200_46487.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_46488_46619.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_46620_46703.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_46704_46751.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_46752_46799.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_46800_46871.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_46872_46979.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_46980_47027.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_47028_47075.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_47076_47171.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_47172_47375.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_47376_47771.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_47772_47819.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_47820_47975.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_47976_48407.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_48408_48491.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_48492_48539.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_48540_50375.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_50376_51191.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_51192_51947.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_51948_57251.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_57252_57311.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_57312_57467.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_57468_59807.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_59808_60767.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_60768_61823.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_61824_63407.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_63408_66047.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_66048_68399.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_68400_68735.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_68736_69551.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_69552_71447.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_71448_71723.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_71724_72371.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_72372_74267.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_74268_77339.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_77340_77651.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_77652_77699.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_77700_78563.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_78564_78875.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_78876_79031.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_79032_83867.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_83868_84059.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_84060_84791.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_84792_84875.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_84876_85127.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_85128_85679.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_85680_86459.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_86460_87803.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_87804_88127.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_88128_88463.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_88464_88691.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_88692_92279.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_92280_93839.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_93840_94199.png Kevlin_Henney_-_Seven_Ineffective_Coding_Habits_of_Many_Programmers_94200_94293.png