00:00:11.960
So my talk's title is 'Sometimes a Controller is Just a Controller.' It's a deep dive into Action Pack, according to everyone who stopped me in the hallway this week.
00:00:18.320
It's actually not just that, but rather about fancy code versus boring code—the epic battle. Here’s some boring code taken from one of my gems; just randomly, it's boring, don't read it. Let’s make it fancy.
00:00:25.519
So this is it, fancy code. And that looks much more impressive! But you know, boring code is so much easier to read. I realized, while coming up with examples like this, that a talk solely about how obvious code is better than clever code would be really boring.
00:00:38.399
So, I refactored the abstract a bit. I hope you don't all feel hoodwinked, but I'm going to start with a digression. I'm going to talk about slides.
00:00:51.440
My name is Justin. I do a lot of talks, and I always invest a lot of time into my slides, trying to make them artful and illustrate my points well. But I am not an artist by any stretch. I don't know if there's an accent over that or which way it goes.
00:01:08.520
Artists like to tell me at the end of my talk, 'Oh, I loved your slides.' I am overwhelmed with joy when I hear this. Then they follow up and say, 'You just clearly put so much time into your slides.' Those are the actual alt texts, by the way, of Apple's Emoji that are going to recur throughout the talk.
00:01:20.119
Fundamentally, though, slides are about time. For anyone watching a recording of this after today, this is what a wristwatch used to look like. I used a clock there. In fact, Apple already ruined that joke because they've updated the Emoji to match their products. Speaking of the Apple Watch, if I get a package notification during this talk, I'm out of here. No offense.
00:01:42.600
I did my own horological study and calculated that if you take all of my free time and subtract away the time I spend doing slides, it equals zero. So I sat down and thought, why do I spend time on this? I want to win people over to a certain way of thinking or invoke interesting conversations on topics I think are important.
00:02:01.520
I realized that if I don't spend any time, I'm not going to win many people over. But as I spend more time, I'll win more and more people over. Even then, I understand I’m never going to win over 100% of people; it's just not possible. I'd die before I got to that point.
00:02:24.080
Luckily, because I manage a business now, I know a lot of project management tricks, like the 80/20 rule. If you're not familiar, the 80/20 rule says to do a job until it's 80% done and then quit.
00:02:37.360
I figured I’d stop at around 80%. I found that I spent about 60 to 80 hours per slide deck, which is a huge investment of time. I didn’t think I’d have quite that much time to prepare for this talk, so I hope you'll forgive me if my art isn't quite up to spec here, with 18 fonts per slide.
00:02:54.560
Sometimes a slide is just a slide. The reason I care about all this is that I want to do a good job and write talks that mean something to people. But the thing is, I can’t know if it’s a good talk until I've conveyed it to you and tested whether or not I've gotten my points across.
00:03:11.959
And whether it worked depends on you. There's really no such thing as universally good talks. But anyway, this is a talk about good code.
00:03:24.120
I’m going to talk about good code. I'm going to lay it down right now: first of all, this is going to be really hard to read. I'll read it for you: good code consists of tiny units—like hilariously tiny, like one public method. I tend to extract the private methods from complex code, but not for the sake of abstraction. I think units should either hold and describe a value or perform some useful behavior, but never both.
00:03:56.079
Those behavior units can contain logic or depend on other units, but never both. I try to eliminate local variables to an absurd degree. I typically start with functional chains; my favorite refactoring tool is composition. I refactor via functional composition. I use tap and each a lot as if to scream 'side effect' in those chains so that I know to refactor that later.
00:04:12.840
I try to minimize third-party dependencies and write wrappers around them. I try to pull side effects near the entry point, like Gary's imperative shell, functional core. I also disagree with whatever my pair does every ten minutes. Finally, I try to overwhelm people with information so that I get my way.
00:04:26.120
So anyway, that's my talk. My name is Justin. I'd love if you followed me on Twitter at my last name, Searls, or if you have any long-form feedback and want to reach me, you can email [email protected]. Don’t worry, I’m in on it.
00:04:51.960
That's not really the end of my talk; that’s just my favorite way to write code. I'm sure that you have your favorite way to write code. When we get together as teams, we collectively normalize and develop consensus about our favorite way to write code.
00:05:03.600
We all have our framework favorite ways; we have conventions that set forth how we want to write code. We are negotiating all these things all the time. The only one in the room who is actually consistent on this is our bosses.
00:05:14.680
Why? Because they know that they want it on target, on time, and on budget. So kudos to them. But when I sit in an iteration planning meeting and we talk about how we're going to approach the next feature, it often devolves into an argument of us all defending our favorite way.
00:05:34.560
Lis K talked about this phenomenon in one of his stand-up routines. Most people don't give a darn what happens as long as they get to do their favorite thing. People don't even want to back off from their favorite thing; they won’t even do their second favorite thing.
00:05:41.680
Have you ever seen someone in a TR at an intersection, and they want to make a left but are in the right lane? So now he wants to make that left. What does he do? He shoves his car through everybody, and everyone’s beeping and outraged. You always see the guy saying, 'I have to; there’s no other possible thing I could do.' What else could he do except go up one more block and make a left in four seconds? But that’s not his favorite way!
00:06:07.280
That met only 99% of his criteria. So I don’t know if you've been in that planning room before, but maybe it's just the case that if we combine everybody's favorite way to write code, then maybe that’s what good code is. But I suspect that intuition suggests that’s not true.
00:06:16.000
In fact, my thesis today is there’s no such thing as good code. I have some inputs in my life that made me think that. First of all, snake oil still sells out as fast as Hacker News can stock it. We all have this void in our souls, chewing up new frameworks and JavaScript.
00:06:38.240
Exhibit B: projects rarely succeed or fail because of their code quality. As a consultant, I’ve been on lots of projects, and code quality is rarely the reason they win or fail. Exhibit C: the industry doesn’t seem to produce better code over time.
00:06:55.760
So, if evolution, if natural selection applies to software, whatever it’s optimizing for is not code quality. I feel like we're just this oscillating fan going back and forth between one meme, maybe capability, and suitability.
00:07:07.360
So if I had to define good code, here’s what I’d come up with: Good code performs a function, and good code communicates intent. Now, when we talk about performing a function, it’s really straightforward. We can look at it, see what it does, measure it, and benchmark it.
00:07:22.400
Then we can always change it. What it does today may be different from what it does tomorrow, and we can always alter it and go back if we need to. Functionality is very objective, and as engineers, we're all really comfortable with that.
00:07:41.920
But what about communicating intent? We look at it like writing. It’s like literary criticism. Our egos get all wrapped up in our favorite way to do things. It’s like a crystal ball; we have to guess what the person reading it will think, what they’ll understand, and what they’ll try to accomplish.
00:08:00.000
We won’t ever really know. Communication is totally subjectively evaluated, and that makes a lot of us as engineers really uncomfortable. So on one hand, we tend to conflate those objective and subjective goals of code, which makes evaluation really hard. This gives rise to the saying 'code is art,' right? It becomes impossible to gauge.
00:08:16.800
So on one end of the spectrum, we have no idea how to evaluate, but on the other hand, we tend to emphasize function because measurement is easier, like burn-up charts. The fundamental crux is that we are evaluating only half of what's going on. This causes a pit in all of our stomachs and has a snowball effect, first on how we practice code as individuals.
00:08:39.920
It rolls down into teams, community, and the industry. We’re going to talk about all the side effects of that fundamental error that we make. First, as individuals, I really wish we could just have an app that could tell us whether our code was good.
00:08:59.960
If only this existed! Well, I wrote it for you. It’s called ismycodegood.com, and it launches right now! It’s a real thing. I really made this. I don’t know why. Here’s a demo of it working up on a website: you type in your GitHub username, it does some calculations, and then it gives you a report card of your code quality.
00:09:15.410
You can go back and type in your boss or your friend and see if you’re better than them. So check that out. Finally, we have some way to evaluate our code—just don’t view the source. In fact, in the last 30 seconds since it launched, it’s front-page news on Hacker News.
00:09:30.400
It's gone so viral that I’m ready to announce version 2’s headline feature: it’s a 10x developer conversion that tells you what kind of developer you are. That’s a paid upgrade because you’re going to be able to argue for higher salaries when you say you’re an 8.6x developer.
00:09:57.280
But really, there are a lot of sites like this. And why do those scoring, ranking, and achievement sites comfort us so much? Why do they always go viral? Because any quantified measurement can really soothe our self-doubt as developers.
00:10:23.760
There’s this secret fear that I think most programmers share: what if my code sucks? I don’t really know. What if, you know, we walk around, and everyone else seems to have everything figured out? Maybe they know something I don’t. You know, maybe if I use enough big words, I’ll fool them into thinking I belong here.
00:10:38.720
We all cope with this in our way. Some put up big fronts; some hide behind others. If you recognize this, you’ll know what you do to compensate. But the amount of fear, insecurity, and doubt varies from person to person. There’s what we might arrive at as a healthy amount.
00:11:03.440
Some people suffer a lot of anxiety about how they fit in, and some people seem to have no care in the world about what other people think of their code. On one hand, people might be very introspective, empathetic, persuadable. On the other end of the spectrum, there are those who are very self-assured, indifferent to what others think, and unflinching in their convictions.
00:11:21.600
So how would you rate yourself on these scales? Let’s start by practicing on me. Last week I came back from France. Who's ever filled out one of those forms when entering the country—a customs declaration form? I hate this form. The first time I filled it out, I was freaked out because I was convinced I was going to get arrested.
00:11:36.639
Every time I do it, I find a new ambiguous wording in this form. One of my favorites says, 'I am bringing fruits, vegetables, plants, seeds, food, or insects.' I know what they're asking for here; the intent is that they don’t want biocontaminants from farms and stuff coming into the country.
00:12:02.000
But I’m a total technocrat. I'm buddies with Aaron Patterson, who really likes avant-garde junk food. I found this in France: it's a Dairy Milk bar with Oreo in the middle, and I bought it for him. So that was in my backpack. I’m filling out this form, and I start by writing 'no.' Then I'm like, well, no—I feel guilty; it’s like technically yes.
00:12:25.200
But I’m like, ‘But it’s not really, guys! It's just candy chocolate!’ I underlined 'candy' and thought, oh no, they’re going to think I crossed out 'food.' That’s the thing that it is! So where do I fall on this spectrum? It’s pretty obvious; I’m a really high-anxiety individual.
00:12:37.160
So if you think of those left-right spectrums, when we hold people to subjective, especially flawed evaluation standards, people who are introspective tend to feel paralyzed into inaction by their self-doubt. People on the other end typically rate themselves favorably, no matter what the popular way to evaluate themselves is.
00:12:54.560
This is a really important point and, oh, there's a passing Dunning-Kruger reference—never mind that. Another interesting aspect to this is that I think people on the left tend to be more effective communicators because they can empathize with the listener.
00:13:12.560
However, on the other side of the spectrum, people tend to be clearer communicators, which means they’re effective communicators but only to like-minded people, who are already like them.
00:13:30.360
It starts off with us evaluating code poorly. The cycle of the industry reveals conscientious coders; they tend to doubt themselves. Because of the self-doubt, this allows the more callous, indifferent coders to outperform everybody else around them. They don’t have the same inhibitions.
00:13:48.720
Eventually, conscientious coders feel marginalized, they quit, and they wash out, which just results in us reinforcing our poor code evaluation. So if we start with these people in the room, eventually, the more feel-y touchy people will leave. What are we left with? Guess which group does better at whiteboard interviews where you’re writing code?
00:14:07.760
Nope, not me. I would still fail all of your whiteboard interviews because I’m so nervous all the time. So if you groaned when you realized that this was a soft talk, this talk's for you.
00:14:29.920
This talk was rated F for feels, by whoever rates talks. Don’t worry, we're in this together. It’s all about good code along with good talks.
00:14:43.480
We like to ask: what’s the right way to do this? We write code the right way. If we consider that communication aspect, we can only really know that communication is ever correct in a given set of contexts.
00:15:01.520
One of my favorites, because Kent Beck is here, is XP’s concept of system metaphors. This is a tool where, if you have a complicated business domain, you can simplify it by saying, 'Well, this is actually like a boat.' All of our variables could use a nautical theme or something as an analogy.
00:15:18.720
But sometimes it can go awry because it requires that we understand the metaphor. One time, one of our test double agents, Kevin Barabo, was on a project where everything was based on 'Mystery Men.' He talked to the team and they were very productive in this codebase, but he had no idea what was going on.
00:15:40.360
They handed him a VHS tape of this movie that’s really bad that we’ve all forgotten about, and the entire codebase was based on memes and references to that movie. They were really productive, and that’s great, but they were getting paid to write code that literally had a pop culture expiration date.
00:15:56.480
That's a huge business risk that they didn’t see coming. Not to mention, who are they pushing away—people who don’t like 'Mystery Men'? Maybe people not like them. So know your audience. It's important when you use metaphors.
00:16:14.240
Consider correctness in your code. Understand that it is a crystal ball, but if your team is on board, that’s great. If you’re writing for the public, consider what you’re saying with the metaphors we use in our code and how we communicate in and about our code.
00:16:33.440
Even just believing there is a right way to solve any given problem in code can cause problems. I feel like being a Rails developer is a bit like playing Mad Libs. As a programmer, I want to convert to PDF and then send it via fax using Rails so that I can remain employed.
00:16:58.560
The first step to do this in Rails is to find the best PDF gem. The second step is the best fax gem. God forbid if it says 'no results found' because we're so used to knowing the right way that we end up looking over our shoulder, thinking, 'What if I just missed it and did this the wrong way?' That can cause a lot of stress.
00:17:16.000
My Ruby friends often say, 'Why would anyone prefer writing JavaScript? It's so gross; it’s such a nasty language, and the tooling is terrible.' And they're right! Here's why: because if I ask in JavaScript, 'What's the right way to build a snowman?' somebody's going to say, 'Does your code work? Because if so, then that's the right way.'
00:17:36.680
A wild west can be really liberating! Seriously, if you suffer from anxiety, being in an ecosystem where there’s not a right way to do things is really kind of cool—like really liberating! Like David Cross riding a pizza in outer space—liberating!
00:17:56.560
Aaron had this quote that I really liked: 'It’s fun to complain about bad code, but I have to remember that perfect is the enemy of shipped.' Sometimes just getting stuff out there means we have to overcome that inhibition.
00:18:09.400
Let’s talk about how that error goes from being just about individuals to being about our teams and how that snowballs a little bit. Have you ever tried out some new approach to your code that you were really excited about, but your team member shot you down?
00:18:23.320
On a team, have you ever had another team member shoehorn some weird code thing that they learned on a screencast or whatever into your project? Yeah, it sucks! These two sides of the exact same coin, the exact same situation—just a different perspective.
00:18:38.240
The difference is fundamental attribution error, which is just a fancy way to say we tend to justify our own actions as good, but we tend to not give other people the same amount of slack. The way we overcome that is typically empathy.
00:18:53.680
If I can empathize with the other person on my team and why they might be doing things their way, then I'll likely be able to get along and justify instead of assuming it's bad.
00:19:12.160
But the problem is that if we’re all spending a lot of emotional energy masking our personal insecurities about whether our code is good, we don’t have nearly as much willpower remaining to be empathetic to our teammates.
00:19:28.000
One of the core tensions on teams that I think is really interesting to discuss is people who are more comfortable with familiar approaches to solving problems versus people who seek out novel approaches to solving each problem.
00:19:44.400
If you’re on the familiar end of the spectrum, you might see your end of the spectrum as the proven approach, while the other side may seem like hacker news-driven development. However, if you're on the other side, you don’t think of things that way. You see your practices as modern development, and all those Java architects are stubborn and outmoded.
00:20:03.570
We can bridge these divides, but having personal insecurity and being unwilling to speak up and make ourselves vulnerable means we typically don’t bridge those divides.
00:20:24.920
Speaking about bridging divides, I want to talk about culture fit. But, you know, I want to add some scare quotes around 'culture fit.' If you go on Twitter, you’ll see a lot of good criticism about what has been called culture fit.
00:20:39.240
Most dev interviews are like a long-ass secret handshake to make sure you belong in the club. It’s ritualistic as much as it is evaluative. I think they are separate.
00:20:55.520
Now, let's talk a little bit about monocultures. First of all, teams' dirty secret number one is that monocultures actually work faster! You might not want to admit it, but it's totally true. If you stack the deck with developers who all agree about the right way to do everything, they don’t have to waste time deliberating or finding consensus.
00:21:14.760
They’re just going to crank out a bunch of code. But a truth bomb here is that a lot of people who call themselves meritocracies are incidentally reinforcing monocultures.
00:21:29.200
There’s no universally ubiquitous way to evaluate our code. What this means is they can say well, 'This person does our favorite way of coding really well,' and it reinforces finding people who are just like you. This is one reason why I think meritocracies have gotten a bad name over the years.
00:21:48.640
Of course, the problem with meritocracies is if you have everyone over on the one side, any environmental change about the market they're in or the users that are using their system means they have these tremendously huge blind spots.
00:22:04.680
If there’s a fire over here, it could burn down everything and then they’re all shocked. Dirty secret number two is that faster monocultures don’t necessarily mean better outcomes. The world teaches us that slow equals stupid.
00:22:19.360
In fact, in the English language, calling someone slow is tantamount to calling them stupid. In general, teams that have to overcome different perspectives, deliberate, and argue are slower but they build more robust systems because they cover those blind spots.
00:22:35.12
If you had a few people from each side of the spectrum, you would probably have to engage in a lot of arguments to arrive at a solution. You’d likely see many fewer blind spots.
00:22:49.280
Tangent: please everyone stop claiming that practices like TDD or Agile or Turbo links are going to make us faster in the long run. That subsumes the whole bias. When we say, 'Well, eventually this is going to be faster,' it’s like no; it might just be better. It might not even be faster.
00:23:07.360
Dirty secret number three is that most dichotomies are false. What I’ve shown you here are two ends of a spectrum, but there’s a whole continuum of people along in the middle that are also really valuable. It’s not just about the extremes.
00:23:29.040
So when I think about culture fit, I think about these pieces of the puzzle that we have connected so far: what are we missing? We don’t need identical pieces again, but where are we now, and what do we need next? Is this person a good fit for augmenting and expanding what we’re covering, one of our blind spots?
00:23:49.160
To digress a bit about code functionality: on one end communication is for humans, while functionality is about communication for computers. If you’ve ever seen a highly optimized function, it might be very dense; it might have a lot of compiler or interpreter awareness in there. It’s good at communicating to the computer but very bad at communicating to other humans.
00:24:16.160
It needs lots of documentation to understand it. On the other end of the spectrum, part of the reason Ruby got popular is because it communicates so well to humans; the code is very readable and easy to use.
00:24:31.680
However, the problem is that all these DSLs we invented turn out to be really slow. All of that metaprogramming makes it difficult for the computer to understand how to make it go fast and how to inspect it.
00:24:47.440
This is just another spectrum. There’s something in the middle that’s probably a healthy balance between those two extremes. If we talk about this as a blended topic—not just communication to humans, but also communication to computers—it’s worth asking how our code communicates.
00:25:05.240
I feel like we don’t have a good vocabulary for this yet. I’ve tried a bunch of different ideas, and this is the one I'm going to share with you today: I’m calling it indirection analysis.
00:25:20.640
In your system, every library or file or method represents this kind of indirection. A new thing to open, look at, or understand. Every macro, reflection, or metaprogram is like a super indirection because it can affect everything that comes before it. I’d be curious to see someone invest time to find a way to score indirection in your system.
00:25:45.880
For a given code path, how many names, i.e., concepts are encountered? How many source files contribute code? How many tests redundantly cover that code? What percentage of the code is handled by third-party dependencies? All this stuff is useful to both humans and computers to understand how our code is communicating.
00:26:11.720
The spectrum can also be conveyed in terms of DRY, or 'Don't Repeat Yourself.' The opposite is WET—perhaps for some reason, it doesn't stand for anything. On one end of the spectrum, DRY means 'duplicate nothing.' WET says 'couple nothing.'