We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback

Sometimes a Controller is Just a Controller

00:00

Formal Metadata

Title
Sometimes a Controller is Just a Controller
Title of Series
Part Number
75
Number of Parts
94
Author
License
CC Attribution - 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
Identifiers
Publisher
Release Date
Language

Content Metadata

Subject Area
Genre
Abstract
You grok SOLID. You practice TDD. You've read Sandi's book…twice. You rewatch Destroy All Software monthly. You can pronounce GOOS. You know your stuff! But some of your coworkers say your code is too complex or confusing for them. You might rush to conclude that must be a them problem. But doubt lingers: what if they're right? After all, the more thought we put into a bit of code, the more information that code carries. Others must extract that embedded meaning, either by careful reading or shared experience. Sometimes boring code is better. Let's figure out when to be dull.
Game controllerCodeGroup actionProcess (computing)Computer animationLecture/Conference
CodeData miningSlide ruleMultiplication signPoint (geometry)Computer animationLecture/Conference
Multiplication signSlide ruleProjective planeRule of inferenceData managementRow (database)Data conversionProcess (computing)Speech synthesisObservational studyMatching (graph theory)Product (business)Point (geometry)Phase transitionFood energyComputer animation
Slide ruleComputer fontUniverse (mathematics)Multiplication signExecution unitBoss CorporationWritingAbstractionSoftware frameworkDegree (graph theory)IterationMathematicsPlanningVariable (mathematics)NeuroinformatikFactory (trading post)Bookmark (World Wide Web)Lattice (order)Code refactoringCodeInformationPower (physics)Sound effectMaxima and minimaFunctional (mathematics)TouchscreenWordPoint (geometry)Imperative programmingRight angleProcess (computing)Wrapper (data mining)Goodness of fitReading (process)Core dumpComa BerenicesGastropod shellMultilaterationComplex (psychology)Parameter (computer programming)TwitterLecture/ConferenceComputer animation
Bookmark (World Wide Web)Sinc functionProteinShape (magazine)PlastikkarteVideo gameCoroutine6 (number)Right angleBlock (periodic table)BEEPMeeting/Interview
PlanningCodeBookmark (World Wide Web)Hacker (term)Active contour modelGoodness of fitSoftware frameworkHypothesisOvalMultiplication signVideo gameProjective planeoutputCASE <Informatik>Information technology consultingEvoluteConnectivity (graph theory)Lecture/ConferenceMeeting/InterviewComputer animation
Hand fanFunctional (mathematics)Goodness of fitSpectrum (functional analysis)MathematicsRight angleCodeReading (process)Performance appraisalTelecommunicationWritingComputer animation
Performance appraisalFunctional (mathematics)MeasurementCodeMobile appDemo (music)Sound effectRadio-frequency identificationSource codeView (database)Error messagePlastikkarteTraffic reportingCalculationType theoryBoss CorporationRight angleCausality2 (number)Rule of inferenceComputer animation
Data conversionSoftware developer2 (number)Hacker (term)Web pageRevision controlWebsiteSpectrum (functional analysis)WordScaling (geometry)RankingCodeProgrammer (hardware)MeasurementShared memoryComputer animation
WordMultiplication signForm (programming)Declarative programmingGodBookmark (World Wide Web)Computer animation
Form (programming)Sampling (statistics)Bit rateMultiplication signWordTelecommunicationWhiteboardStandard deviationSpectrum (functional analysis)Point (geometry)CodeCycle (graph theory)Expected valueGroup actionWater vaporTouch typingPerformance appraisalResultantComputer animation
Set (mathematics)AnalogyTelecommunicationParametrisierungDoubling the cubeCodeContext awarenessSoftware testingVariable (mathematics)Goodness of fitPhysical systemBit rateMultiplication signProjective planeMetropolitan area networkDomain nameRight angleComputer animation
Arithmetic meanEntire functionCodeTape driveSoftware developerBitResultantStress (mechanics)Probability density functionFormal languageWritingProgrammer (hardware)Real numberComputer animation
Interior (topology)SpacetimeOpen sourceAreaBlind spot (vehicle)Food energyGroup actionCodeMathematicsFitness functionIntegrated development environmentCore dumpGoodness of fitInstance (computer science)Auditory maskingNumberError messageTouchscreenShift operatorHacker (term)Perspective (visual)Spectrum (functional analysis)Different (Kate Ryan album)Software developerBitParameter (computer programming)Physical systemDichotomyVulnerability (computing)Java appletAttribute grammarBridging (networking)Multiplication signArithmetic meanExtreme programmingDependent and independent variablesSlide rulePoint (geometry)Projective planeQuicksortTurbo-CodeTangentRight angleLink (knot theory)Fundamental theorem of algebraInformation securityMachine codeProcess (computing)Computer architectureVideoconferencingSquare numberSpeech synthesisPerformance appraisalBookmark (World Wide Web)Computer animation
Context awarenessCodeInterpreter (computing)Branch (computer science)CompilerMoving averageNeuroinformatikMereologySpectrum (functional analysis)Group actionWater vaporQuicksortMetropolitan area networkComputer programmingTelecommunicationPhysical systemChemical equationDifferent (Kate Ryan album)Shared memoryTerm (mathematics)Library (computing)Mathematical analysisSoftware frameworkReflection (mathematics)Macro (computer science)Computer fileDichotomyAbstractionMetaprogrammierungSpacetimeNegative numberMultiplication signSource codeBusiness objectSoftware testingFreewareBitMachine codeFunctional (mathematics)Sound effectRight angleInteractive televisionGraph coloringDirection (geometry)NavigationProcess (computing)HorizonForcing (mathematics)Extreme programmingSoftware developerComputer animation
CodeBitMultiplication signAreaWordReading (process)MereologyLevel (video gaming)Computer programmingTotal S.A.Computer animation
Domain nameView (database)CodeSpeech synthesisOrder (biology)Channel capacityGame theoryPresentation of a groupHexagonVideo gameDoubling the cubeSoftware testingWhiteboardCycle (graph theory)Software developerBlogPerformance appraisalBitSymbol tableRight angleComponent-based software engineeringTelecommunicationData transmissionArithmetic meanGame controller1 (number)Data miningSource codeComputer animation
Constructor (object-oriented programming)Touch typingExistential quantificationAverageFeedbackSoftware testingDoubling the cubeMultilaterationComputer-assisted translationMultiplication signData conversionProjective planeGoodness of fitGroup actionSurgerySoftwareDifferent (Kate Ryan album)Endliche ModelltheorieCodeSpectrum (functional analysis)Right angleBitMereology1 (number)EstimatorSoftware developerType theoryView (database)Domain nameComputer programmingPublic key certificateContext awarenessDecision theoryWeightJava appletModule (mathematics)Interface (computing)NumberBuildingTotal S.A.Cartesian coordinate systemBit rateExpert systemDependent and independent variablesPhysicistPhysicalismMessage passingImplementationExistencePoint (geometry)WordVapor barrierBookmark (World Wide Web)Natural numberCurveReal numberPhysical systemAnalogyCollaborationismLevel (video gaming)InternetworkingResultantParameter (computer programming)PressureBusiness objectFigurate numberPrime idealForcing (mathematics)Power (physics)Software frameworkProduct (business)Task (computing)Exception handlingOperator (mathematics)Sign (mathematics)Computer animationLecture/Conference
Transcript: English(auto-generated)
So my talk's title, 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. It's actually not, but it's 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. So this isn't fancy. And that looks much more impressive. But you know, boring code is so much easier to read.
And you know, I realized in coming up with a bunch of examples like this that that would have been a really boring talk to be like, look at this obvious code, and it's better than this clever code. So I refactored the abstract a bit, so I hope you don't all feel hoodwinked, but I'm going to start with a digression. I'm going to talk about slides. So my name is Justin.
I do a lot of talks, and I always invest a lot of time into my slides and try to make them artful and illustrate my point well. But I'm not an artist by any stretch. I don't know, artiste? I don't know if there's an accent over that or which way it goes. But artists like to say at the end of my talk, like, oh, I loved your slides,
and then I'm overwhelmed with joy to hear this. Then they follow up, and they say, you just clearly put so much time into your slides. Loudly crying face. Those are the actual alt text, by the way, of Apple's emoji. You're going to recur through the talk. So 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'll use a clock there. In fact, actually, 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. So I did my own horological study, and I calculated that if you take all of my free time and you subtract away the time I spend doing slides, it equals zero. And so I sat down, and I thought, why do I spend time on this? And it's because I want to win people over to a certain way of thinking, or I want to invoke
some interesting conversations on topics I think are important. And I realized 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, but even then I can understand I'm never going to win over a hundred percent of people. It's just not possible. I'd die before I got to that point, but luckily, because I helped 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 do a job until it's 80% done and then quit. I figured I'd stop at around 80%. I found that spent about 60 to 80 hours per slide deck, which is a huge investment of time. So I didn't have quite that much time, or 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. Sometimes a slide is just a slide, so we'll just have to take it as is. The reason I care about all this is I want to do a good job. I want to write good 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 see and to test whether or not I got my points across and you agree or disagree and whether it worked. It's contextual. It depends on you, and there's really no such thing as universally good talks. But anyway, this is a talk about good code, and 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, tiny units, like hilariously tiny, like as in one public method. I tend to extract the private methods from complex code, but for the name, not for the abstraction.
I think units should either hold and describe a value or perform some useful behavior, but never both. Those behavior units, they can contain logic, or they can depend on other units, but never both. I try to eliminate local variables to an absurd degree. I usually start with functional chains, but then 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 go back and refactor that later. 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. And then I also disagree with whatever my pair does every 10 minutes. And finally, I try to overwhelm people with information so that I get my way.
So anyway, that's my talk. My name is Justin. I'd love if you follow me on Twitter. So that's my last name, Searls, or if you've got any long-form feedback and want to go hold me, hello at testdouble.com. Don't worry. I'm in on it. That's not really the end of my talk. That's just my favorite way to write code, and I'm sure that you have your favorite way to write code.
And when we get together as teams, we all collectively, we normalize, and we develop consensus about our collective favorite way to write code. You know, we all have our frameworks favorite way, like it's conventions that set forth how it wants us to write code. We're negotiating all these things all the time. The only one in the room who's actually consistent on this is our bosses, right?
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 like how we're going to approach the next feature, it's often just an argument of us all getting our favorite way. Louis C.K. talked about this phenomena
in one of his stand-up routines. Most people don't give a shit 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. Like you ever seen somebody in trouble, like they're at an intersection, and they want to make a left, but they're in the right, all the way right lane. Because they
messed up. So now they're, okay, here's the guy, he's in the right lane, and there's a whole lot of cars, like 6th Avenue, like a lot of cars, and he wants to make that left. So what does he do? He just does it anyway. He just goes ahead, and he just shoves his car
through everybody's life without any... and everybody's beep honking and outraged, and you always see the guy go, I have to, I have to. There's no other possible thing I could do. Could I do, except go up one more block and then go left and take four seconds.
That's not my thing. 99% of my criteria. So I don't know if you've been in that planning room before, but I feel like I have, and I've been that guy.
So 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, you know, intuition suggests that that's not true. In fact, my thesis today is that there's no such thing as good code. I've got some just like some, 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 clear, like this void in our souls chewing up new frameworks and JavaScripts. Exhibit B, projects rarely succeed or fail because of their code quality. I've been, as a consultant, been on lots of projects and code quality is rarely the reason they win or fail.
And Exhibit C, the industry sure doesn't seem to produce better code over time. You know, so like if it's a, like 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 it's like capability suitability on one end to the other. So, so if I had to define good code though, here's what I'd come up with. I'd say one, good code performs a function and two, it communicates intent. Now when we talk about performing a function, it's really straightforward, right? We can look at it, see what it does. We can measure it and do benchmarks and optimize it and then we can always change it. Like what it does today is going
to be what it does tomorrow and we can always alter it and go back if we need to. So functionality is very objective. We can evaluate that objectively and as engineers, we're all really comfortable with that. But what about communicates intent? We look at it like writing. It's like literary criticism. Our egos get all wrapped up in our favorite way to do stuff and then it's like a crystal ball.
We just have to guess, you know, the person reading it. What are they going to be thinking? What are they going to understand? What are they going to be trying to accomplish? We won't ever really know. So communication, that's totally subjectively evaluated. And you know, 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 and which makes evaluation really hard.
This is where you hear people like, code is art, right? Like it's just impossible. So on one end of the spectrum, we have no idea how to evaluate. But otherwise, we tend to emphasize function because the measurement is easier, like burn up charts. And so on the other hand, we just have the wrong idea. We only really evaluate half of what's going on.
I think that this is the fundamental crux. Like this causes a little pit in all of our stomachs and it has a snowball effect. First on how we practice code as individuals and it rolls down into teams and community and industry. And we're going to talk about all the side effects of that fundamental error that we make.
So first of all, as individuals, I really wish that we could just have an app that could tell us whether our code was good, right? 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. We load it. You type in your GitHub username. It does some calculations. Then it gives you a report card of your code quality. And you can go back and you can type in your boss or your friend and see if you're better than them. And so check. Done. 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 of Hacker News. It's gone so viral that I'm ready to announce version 2's headline feature. It's a 10x developer conversion. It'll tell you what x developer you are. That's a paid upgrade because you're going to be able to argue for such higher salaries
when you say you're an 8.6x developer. But really, there are a lot of sites like this, right? And why do those scoring and ranking and achievement sites comfort us so much? Why do they always go viral? It's because any quantified measurement can really soothe our self-doubt as developers. There's this secret fear that I think most programmers share
and that's, what if my code sucks? I don't really know. What if, you know, walk around, everyone else seems to have everything figured out. Maybe they know something I don't. Maybe if I use enough big words, I'll fool them into thinking I belong here. And we all cope with this in our own way. Some of us put up big fronts. Some of us hide behind other people. If you recognize this, you'll know what you do to try to
compensate. But that amount of fear and insecurity and doubt, it varies from person to person. There's what we might arrive at as a healthy amount. 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. And so on one hand, people might be very introspective,
empathetic, persuadable. And on the other end of the spectrum, very self-assured, indifferent to what other people think, and unflinching in their convictions. So how would you rate yourself on these scales? So let's start by practicing on me. So last week, I came back from France. And who's ever filled out one of these
farms entering the country, like a customs declaration farm? I hate this farm. The first time I filled it out, I was freaked out because I was convinced I was going to get arrested because I don't know what I'm doing. And every time I do it, I find a new ambiguous wording in this form. And one of my favorites is this one. I am, we are bringing fruits, vegetables, plants, seeds, food, or insects. And now 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. But I'm a total technocrat. And so I'm buddies with Aaron Patterson. And Aaron really likes avant-garde junk food. So I found this in France. It's like a dairy milk bar with Oreo in the middle. And I bought it for him. So that was in my backpack. So I'm filling out
this farm. And I start by writing no. And then I'm like, well, no, I feel guilty. No, it's technically yes. But I'm like, but it's not really, guys. It's just candy, chocolate. And I underlined the candy. I was like, oh, no, they're going to think I crossed out food, but that's the thing that it is. So where do I rate on this spectrum? It's pretty
obvious I'm a really high anxiety individual, clearly. So if you think of those left-right spectrums, when we hold people to subjective, especially flawed, evaluation standards, people who are really introspective, they tend to feel paralyzed into inaction by their self-doubt. People on the other end of the spectrum tend to rate themselves favorably, no matter what the popular way to evaluate themselves is. And it's a really important
point. In fact, oh, there's a passing Dunning-Kruger reference. Never mind that. Another interesting aspect of that, though, is I think that the people on the left tend to be more effective communicators, because they can empathize with the listener. Whereas on the other side of the spectrum, people tend to be clearer communicators, which means that they're
effective communicators, but only to like-minded people, people who are already like them. So it starts off with us evaluating code poorly, like the cycle of the industry. And then I find that conscientious coders, they tend to doubt themselves, right, because of the self-doubt, which allows those more callous and indifferent coders to kind of
outperform everybody else around them, because they don't have the same inhibitions. So then eventually, conscientious coders, they feel marginalized, and they quit, and they wash out, which just results in us reinforcing. We evaluate code even more poorly. So if we start with these people in the room, you know, eventually those more feely, touchy people will leave. And what are we left with?
Guess which group does better at whiteboard interviews, where you're writing code? 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.
You're who I'm talking to. This talk was rated F for feels. Uh, by whoever writes talks. So don't worry, we're in this together. So it's all about, like, a good code, along with good code talks about, we're like,
what's the right way to do this? We write code the right way. And obviously, if you consider that communication aspect, we can only really know that communication is ever correct in a given set of contexts. So 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 really complicated business domain, you can simplify it by being like, well, this is actually like a boat,
and all of our variables are just a nautical theme or something, as an analogy for something that's very abstract. It's a useful tool. But sometimes it can go awry, because it requires that we understand the metaphor. So one time, one of our test double agents, Kevin Barabough, was on a project, and he came to a code base where everything was based on mystery men.
And he talked to the team, and they all were very, very productive in this code base, but he had no idea what was going on, so they hand him a VHS tape of this movie that's really bad and that we've all forgotten about. And the entire code base was based on memes and references to this movie. Yeah. So they were really productive, and that's great, but there was like,
they were getting paid to write code that literally had a pop culture expiry date on it. And that's a huge business risk that they didn't see coming. Not to mention, who are they pushing away who don't like mystery men? Maybe people not like them. So know your audience. It's important when you use metaphors and you consider the correctness of your code. Understand that it is a crystal ball, but if your team is on board, then that's great.
But if you're writing for the public, you have to consider what are you saying by the metaphors that we use in our code and how we communicate in and about our code. Separately, even just believing that there is a right way to solve any given problem in code can really cause problems.
I feel like being a Rails developer is a little bit like playing Mad Libs. So as a programmer, I want to convert to PDF and then send it via fax using Rails so that I can remain employed. And the first step to anything like this in Rails and plugging things together is best PDF gem Rails. And the second step is best fax gem Rails.
And God forbid if it's no results found, because we're so used to knowing the right way that we have looking over our shoulder like, what if I just missed it and I do this the wrong way? It can cause a lot of stress. So when I talk to my Rubyist friends, a lot of them will often say like, 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 is going to say, does your code work? Because if so, then that's the right way. So a wild west can be really liberating. I'm serious. If you suffer from anxiety, being in an ecosystem where there's not a right way to do things is really kind of cool.
Really liberating, like David Cross riding a pizza in outer space liberating. So 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 shift. So sometimes just getting stuff out there means that we have to overcome that inhibition. So yeah, let's talk how that error goes from being just about individuals to being
about our teams and how that snowballs a little bit. So as teams, if you've been on a team, have you ever tried out some new approach to your code that you're really excited about, but your team members shot you down? Or on a team, have you ever had another team member shoehorn some weird code thing that he learned on a screencast or whatever into your project?
Yeah, sucks. Of course, there's two sides of the exact same coin. It's the exact same situation. All that changes is our perspective. The difference is fundamental attribution error, which is just a fancy way to say, we tend to be more than willing to justify our own actions as good, but we tend not to give other people the same amount of slack.
The way we overcome that typically is empathy. If I can empathize with the other person on my team and why they might be doing things the way that they're doing, then I'll probably be able to get along and justify instead of assuming that it's bad. But the problem is that if we're all expending a lot of emotional energy to mask over our personal insecurity about whether our code's good or not, then we don't have nearly as much willpower remaining to be empathetic to our teammates.
One of the core tensions on teams that I think is a really interesting one to discuss is people who are more comfortable with familiar approaches to solving problems versus people who seek out more novel approaches to solving each problem. Now, if you're on the familiar end of the spectrum,
you might see your end of the spectrum as being the proven approach and the other side as being hacker news-driven development. But if you're on the other side of the spectrum, you don't see things that way. What you see is you're practicing modern development and all those Java architects are stubborn and outmoded. We can bridge these divides, but having personal insecurity and being unwilling to speak up
and make ourselves a little bit vulnerable means that we typically don't bridge those divides. Speaking about bridging divides, I want to talk about culture fit, because I need to add some scare quotes to culture fit. If you go on Twitter, there's a lot of good criticism
about what has been called culture fit. I love the screen from Marco. Most dev interviews are like a long-ass secret handshake to make sure you belong in the club. It's ritual as much as it is evaluation. So that's really like more talking about monoculture fit than culture fit. I think they are separate things, and so let's talk a little bit about monocultures.
First of all, about teams, dirty secret number one is that monocultures actually work faster. You might not want to admit it, but it's totally true that if you stack the deck with developers who all agree about the right way to do everything, they don't have to waste any time deliberating or finding consensus. 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
like meritocracies are incidentally reinforcing monocultures. Because there's no universally ubiquitous way to evaluate our code, what it really means is that they can really just say, well, this person does our favorite way of doing code really, really well, and it reinforces for finding people who are just like you. That's one reason why I think meritocracies
have gotten a bad name in the last few years. And of course, the problem with meritocracies is if you have everyone over in this one side, any environmental thing changes about the market that they're in or the users that are using their system, they've got these tremendously huge blind spots. So if there's a fire over here, it could burn down everything, and then they're all shocked and it all goes to hell immediately.
So dirty secret number two is that faster, the fact that monocultures go faster in this instance doesn't necessarily mean better. The world teaches us that slow equals stupid, calling someone slow is a tantamount to calling them stupid. But in general, teams that have to overcome different perspectives
and deliberate and argue, yeah, sure, they're slower, but really they build more robust systems because they cover those blind spots. So if you had a few people from each side of this spectrum, they'd probably have to get in a lot of arguments to arrive at a solution, but you can see much fewer blind spots. So tangent, tangent, please, please, everyone,
stop claiming this. Like, trust us, you know, some practice, like TDD or Agile or Turbolinks, it's gonna make us faster in the long run. That subsumes this whole bias, right? When we say like, well, eventually this is gonna be faster. It's like, no, it might just be better, might not be faster.
Dirty secret number three, of course, is most dichotomies are false. So what I just showed you here is like two ends of a spectrum, but there's a whole cacophony of like people along in the middle that are also really valuable. It's not just about the extremes. So when I think about culture fit, what I think about is like, these are the pieces of the puzzle that we have connected so far. What are we missing?
We don't need the identical piece again, but like, where are we now and what do we need next? And is this person, you know, a good fit for augmenting and expanding what we, covering one of our blind spots? So a little digression about code. What does this say about code? Functionality, you know, on one end, communication on the other side.
I'm making up this false dichotomy, right? Well, wrong. Because fundamentally, if all dichotomies are false, then like we kind of have to emphasize everything as a spectrum. So on one end, I want to talk about communication, like as communication to humans, and the functionality side is really communication to computers. So if you've ever seen a highly optimized function,
like what might be very dense, it might have a lot of compiler or interpreter awareness in there. It's probably very, very good at communicating to the computer, but very bad at communicating to other humans. It needs a lot of documentation to understand it. On the other end of the spectrum, part of the reason Ruby got popular was it's very good at communicating to humans, because the code is very readable and easy to use.
But the problem is that all those DSLs that we invented turn out. They're really slow, and all that metaprogramming makes it very difficult for the computer to understand how to make it go fast and how to introspect it. So clearly, this is just yet another spectrum, and there's something in the middle that's probably on the market as a healthy balance between those two extremes. So if we talk about this as sort of like one blended topic about not just communication to humans,
but also communication to computers, it's worth asking, how is our code communicating? So 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 gonna share with you today, but this rife with opportunity for coming up with your own. I'm gonna call it indirection analysis. So in your system,
every library or file or method or name represents a kind of an indirection, you know, a new thing to open or look at or understand. And every macro or reflection or metaprogram is like a super indirection because it can affect everything that came before it. And I'd be curious to see somebody invest the time to like find a way to automatically score
indirection in your system. So 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, it's useful to both humans and to computers to understand how our code's communicating.
And this spectrum is really like, could be conveyed in terms of dry, right? Like dry is don't repeat yourself and the opposite of course is wet for some reason. I don't think it stands for anything. But on the one end of the spectrum, dry is really saying duplicate nothing. And wet isn't saying duplicate everything, it's saying couple nothing. So we take those as a spectrum and we look at both the extremes,
both of them are really costly. On the one hand, if you couple nothing, then it's really cheap to change one thing because you know that it's only referenced in that one place. But changing many things mean you have to change it in all these different places and that's why dry got popular. So if you duplicate nothing, then changing many things all at once because it's all in one place is really easy. But if only one of those usages diverges
from the rest of the pack, then that's when we get into the dreaded bad abstraction because then you have to like, have an if-else branch in your code. Similarly, it's really easy to learn one piece if you don't couple anything. But learning an entire system is really hard. But if you duplicate nothing, learning one piece means you have to basically learn the entire system. But then once you do, you're just flying
because you know how everything in the program works. So yay, nuance. Dry is not good, dry is not bad. It's just yet another spectrum. Another aspect of indirection I think is interesting in this regard is explicit versus implicit indirection. So explicit indirection, I like to think of like in test-driven development, domain-driven design where in your system
you have a lot of custom domain objects. So your system is a special snowflake and everyone who has to come to it has to go and understand everything in the system. Whereas with implicit indirection, maybe something like Rails or Ember, you have to study up on what the community does, what the framework does, so that you can just have all of this sort of magical negative space in your systems that does stuff for free.
They're both indirection and they're both wildly different. And we kind of talk about one versus the other a lot, but we don't really understand that like the net effect of both is lots and lots of indirection in the systems that we build. So I would just like us all to get in the habit of practicing how we communicate about our code's communication, like having more of these meta discussions. So yes, this is a great opportunity
if you want to be the next thought leader, think on this. I'd like to see more people discussing this kind of stuff because I think it's really interesting. Speaking of thought leaders, let's roll down to our community. So as a community, we have this like fantastic group of people who are prolific. They speak at conferences and they publish
and they're really like our team's sixth man or woman, people like Gary or Sandy or Erin who contribute to us as thought leaders new ideas that shake up how we do things. They give us opinions on like this is a good approach, this is a bad approach, this is sort of a short circuit and help us navigate the gigantic waters of what's going on. And then they can also provide us a little bit of CYA.
Somebody pokes at my code and says, oh, I don't like that. I can at least be like, well, that's how Gary does it and now it's totally cool. But when we're writing code for our jobs, who is our code really talking to? Who's gonna read that? So if I'm here programming one day and I'm thinking about that question, the honest answer is I'm usually coding as if Gary's watching,
which means I'm writing all this highfalutin stuff and I'm really sweating the details and it's really, really stressful and not just for me, but for the person reading it. But in reality when I'm programming, it's probably just that somebody who's more like me than different from me is gonna be the one reading it. If anything, they're gonna be a little bit more novice. And so, you know, I'm disappointed that a famous person is not reading my code,
but at least I'm relieved that I'm not on stage, except for right now when I'm on stage. So really if we write code to other people who are just like us, we're gonna favor more obvious and clear solutions, which makes me happier and it certainly makes them happier that they don't have to read all this fancy, clever gobbledygook. Another aspect and part of the reason for this
is I think that we all suffer from a little bit of hero worship in the times that we live in. Gary actually tweeted this and I really liked it. He said, you know, speakers were so mysterious, but now he gave his first keynote last year. And now that I know that we're mostly just regular ding-dongs. And you know, I gave my first keynote last year too, so I was able to check in,
total ding-dong, and Aaron confirmed he's also a ding-dong. So really there's nothing fancy. We're just like, we just got lucky and here we are, hi. So now that I'm a certified keynote speaker, I'm gonna turn in my speaker card, even though this makes me really uncomfortable, just to make this one claim, which is that your clever code does not impress me.
Your clever code makes me feel stupid. It really does. In fact, the more I think about this, I realize that clever code is simply a symptom of poor understanding. I'd be much more impressed if everyone went to the subreddit, explained like I'm five, and tried like practicing all the business domain stuff that they're doing there, because that's fundamentally,
like that's a lot harder to do. In fact, obvious is much more impressive than clever. I'd love to read more obvious code in my life. Um, speaking of the way that thought leaders share stuff, we have all these design approaches, and they're really memes, like MVC, BDD, DSLs, view presenters, like we had a whole bunch in our society, right?
Fast specs, hexagonal rails, DCI, fat models, skin controllers, these are just memes, and by this definition of meme, like the formal one, memes are ideas that compete for our attention. They feed off our attention and they reproduce via transmission, via our communication, as if by natural selection. So what's like a meme's life cycle look like in our community?
Well first, it starts when somebody has an idea, and then they experiment with that idea, eventually they start sharing it with early adopters of that idea, and it spreads, it becomes popular eventually, like if they're successful, they become ubiquitous, and then finally, that idea is finally worth using. What? Like, how does it get from the beginning to the end?
Well, the reason the end game is what it is, is because memes are most valuable once our audience knows them, and if they don't know them, it might cost more for us to use that particular design approach than to have just done things the obvious way. So why is it that design memes ever become ubiquitous? And I think that the reason is that there's a symbiotic relationship between those early adopters who tend to oversell the intrinsic benefits,
because we're all looking for a panacea, we're all looking for a magical thing that's going to fix all those fundamental problems in our code, and so we're eager to pull in new ideas. So if you look at this chart, you know, the people who share the idea initially with others as early adopters, I call them evangelists, or meme salespeople, they will try to convince others that,
like, this is really good, and it's going to fix all your problems, and that convinces the next rung up, you know, the aspirational adopters who think it's going to fix things, and as it gets bigger, like, they realize that it'll be more useful if it's ubiquitous, so they kind of, like, present this puff out their chest a little bit, like it's actually being more used than it really is in order to get it towards ubiquity.
So keep that in mind whenever you hear about a new design meme or read an interesting blog post, is that everyone wants their meme to be successful, and that means they might even pressure you to adopt it. They might not even realize that they are. But again, know your audience. If you're just writing code for yourself and you want to try out DCI, great. If you're on a team and you're all on board with a given meme, then that's fantastic. Just remember that it might mean
people outside your team won't understand it and you might push them away. Let's talk a little bit about industry. So this is what the industry looks like, except some of us work from home now. So if you think that our inability to evaluate code as developers makes us uncomfortable, try talking to a business person. I'm doing like a lot of business sales stuff now
in my capacity at Test Double. And so we're going to talk about business, living the life. How can a non-technical business person be sure that they're hiring good developers, without knowing how to choose? It's really apples and oranges. If a company goes to DevMind
and they also go to Test Double and they're trying to evaluate how we're different from each other, I'm an expert because I own one of the two companies and I don't know how I would convey that because we're very similar. So how would we expect some total novice to understand the nuanced difference between us as developers and us as agencies? The answer is that a lot of businesses will put out what's called
requests for proposals or RFPs. I don't know how many people in the room have ever been part of responding to an RFP but we're going to break it down. Remember back in that initial spectrum of different types of people, the more conscientious folks versus the people who are a little bit more self-assured. On one hand, when you get a request for proposals
to give an estimate or an approach for a given system, the more conscientious people tend to identify a lot of risks and assumptions, whereas the other ones will rationalize away risk. These folks on the left will emphasize collaboration, whereas the more self-assured might emphasize their own competence. On the left, they estimate pessimistically, tend to, whereas on the right, they estimate optimistically.
It's all going to go well because they're great. On the left, they tend to, as a result, come in with higher bids and so they rarely win the work, but on the right, they come in at lower bids, they often win the work. And whether we're talking about the bid or the project itself, on the left, they tend to blame failures on themselves, at least partially, whereas on the right, they blame failures on others. So the left self-selects to get out of there and the right keeps winning and growing
and winning more work. So businesses, if I'm giving a pitch to a business and then at the very end of the conversation, they're like, we think we're going to put this out to bid, they don't realize that just simply asking for proposals drastically biases their decision towards bad software agencies. And that's terrible, but that's just exactly how it is.
I don't know how to fix that. But I do think that the fact that we as developers really enjoy these comforting myths that our code is tangible and quantifiable and fungible and easy to evaluate, it just perpetuates this bias. And that's the reason we've educated business people that code is this concrete thing. And so it's totally fair of them to have this flawed metaphor in their minds.
So instead, I'd really love it if us as developers were much more vulnerable and willing to admit and educate others that software is full of uncertainty. It's defined as some net total amount of uncertainty. And when you talk about metaphors, the predominant metaphor for software development and business is construction. We're building stuff, we're makers, we're craftspeople.
And that can be useful to a point, but it only goes so far. Another metaphor that I like a lot is surgery in that our software is here to solve a problem and we can either rush in and rip out your appendix and then you're in the hospital for three months because of how invasive that was,
or we could plan very carefully and make it outpatient to take care of you so that it's not so painful or not so risky. I got that metaphor from Dan North. Look out for a book or something where he's gonna use that. I like that metaphor simply because it teed me up to talk about my very favorite thing, estimates.
On the left, the construction metaphor really brings us to say, well, how much time will it take to build this thing with good code? Whereas the surgery metaphor leads us to ask a different question, which is how much uncertainty and or risk does this project pose, does this feature pose? How much net uncertainty is there here to deal with? Now, neither of these questions are wrong
in and of themselves. The problem is with their follow-up. The natural follow-up to the construction metaphor when you're trying to figure out how long something's gonna take is really what you wanna ask but you're not willing to ask is, how bad of my good code are you willing to accept? But on the right, and on the left,
these are business people. They're not code experts, so how are they supposed to know? They don't wanna buy something shoddy. Bravado will win here every time, but whereas on the right, the surgery metaphor will force us to ask, so how much uncertainty and risk are you willing to tolerate? Why do these people go to MBA school? It's all about risk tolerance. This is a question they're really good at answering,
so we should try to pull more of the conversation to the right. So under this model, a way to work on your backlog would be to start by picking the most uncertain feature, identify all the risks and unknowns, executing agile spikes to reduce the uncertainty till everyone's comfortable, and then finally, if there's no uncertainty left, it's really easy to implement it with boring code. We don't need clever code anymore
because there's nothing interesting there. And then finally, you can pick the next most uncertain feature and continue and work against your backlog, paying down all that uncertainty. I gave a name for this. I called this the boring code discovery model. There's a certification program coming soon, so just email us at testdouble if you're interested in paying for a certification,
but when we talk about boring code, how will we know it when we see it? How will we evaluate it from project to project? What even is boring code? And I think that fundamentally, it's about having enough shared context that we don't have to reinvent all the wheels, minimizing the number of novel technical concepts in our code base so that our application just does what it needs to do,
clearly named domain concepts, but not necessarily to the point of being really artsy, and then finally, lots and lots of empathy for each other on our team and for whoever's going to adopt the code later. So if you take those four things and you just kind of view them like audio sliders, audio mixers, it would be interesting as an experiment
to go back in your own project experience and rate all of those different categories and see how that project went for you. Like, an average Omakase Rails project has a good amount of shared context, and it really, especially in 2005, got us really thinking about domain concepts in a way that we hadn't before and how we model stuff. A Prime Rails project, where you're using stuff like more DSLs,
like maybe RSpec and Cucumber and Draper and stuff, the shared context is higher. We have to learn more up front, but the empathy might also be higher because it's more focused on communicating with others and business. Node.js projects tend to be anti-framework, and so the shared context is lower, but it's more social. Like, the module interface and stuff
is pretty consistent across node projects. Java projects typically have this, you know, cacophony of custom domain objects, but maybe have very else little in common. You know, an Ember.js project, one of the reasons I've been following Ember closely, I really love Ember, is because of this tremendously high barrier of entry. I, that sounds negative, sorry.
It's a very steep learning curve, but once you reach the top of that mountain, you can do almost anything you want really, really fast, and that public API, once you learn it, look at what they're doing with Glimmer and all this stuff. They're building all these really, really advanced stuff at the implementation level, and so you learn it once, but once you do, it's a very high empathy community. They're all really great and friendly.
So that's just one idea. Your mileage may vary, but that's like one way that I'm trying to think about thinking about boring code. So what can we start doing tomorrow? Gotta wrap up. So we're gonna drop some truth bombs on our way out. First of all, we obviously should all relax our conception that there is such a thing as universally good code, that how we evaluate code is subjective and flawed,
and therefore, fearing that your code sucks is both totally natural and totally pointless, so acknowledge it and let it go. Claiming a right way exists. That might pull some people for you. It might be a good shortcut, but it might just as well push other people who aren't like you away, and people who aren't like you are very useful,
so we should be seeking opportunities to deliberate kindly and respectfully with people who think differently. If your team never disagrees, or if you never have to find consensus in your approach on your team, probably means you need new types of people, new blood in your team to check your corners. Also, upon exercise, whenever you see the word clever, just replace it with the word self-indulgent.
It's taken from Don Norman's book. Metaphors and memes are powerful, but again, they limit your audience to whoever already understands them, and finally, when someone doesn't understand your code, assume some of the responsibility. Don't assume it's their fault for not understanding your code. Kip Thorne, he's a famous physicist. He was the guy who came up with the idea
for the movie Interstellar. He had this quote from his book about the science in the movie. Some segments of this book may be rough going, though that's the nature of real science. It requires thought, sometimes deep thought, but thinking can be rewarding, spoiler alert. You can just skip the rough parts, or you can struggle to understand, and he concludes, if your struggle is fruitless,
then that's my fault, not yours, and I apologize. This is the guy who discovered wormholes, and he's apologizing to me for not understanding the physics in his book, and maybe that means that at least I could like, you know, apologize to the next person when they don't understand my JavaScript, maybe. So my message is really just simply,
be courageous, and write more boring code. That's the end, again. My name is Justin. Love if you got in touch with me, followed me, gave me some feedback. I come from Test Double. We're a software agency. We build code with companies, and if your team needs extra engineers or extra help, please let us know. If you'd like to join us, if you think that we might be a good group of people
to work with, we're always hiring, we're always interviewing, join at Test Double. And I have stickers. They are not of Aaron's cats. They're a little bit more abstract, but if you'd like a sticker of our logo, I'd be happy to give you one and chat with you today at lunch. So everyone, thank you so much for your time. I really appreciate it.