-
DAVID HEINEMEIER HANSSON: That any better?
-
Oh, there we go. Woo.
-
Software's hard, as you can see. Hardware,
too.
-
So last year I had the personal pleasure of
-
celebrating ten years of working with Ruby
and ten
-
years of working with Rails. But this year,
I
-
have a much more interesting anniversary,
which is ten
-
years of sharing Ruby on Rails with all of
-
you and everyone who's been using it over
the
-
past decade.
-
The picture in the background is actually
from almost
-
exactly this time, where I gave the very first
-
presentation on Ruby on Rails at a Danish
university
-
ten years ago.
-
Ten years ago, I had to talk a lot
-
about what is MVC, for example. Today, not
so
-
much. There's a lot of things that over the
-
past ten years, things we were worried about
in
-
the beginning, sort of leveling up as a community
-
and as, as programmers, that just aren't relevant
anymore.
-
We're just taking all that stuff for granted.
-
Which is awesome. We get to care about a
-
lot of other stuff.
-
But as I look back over the past ten
-
years, which is pretty much the majority of
my
-
adult life, I've been working on Ruby on Rails.
-
It's fun to look back even further. I think
-
there's a common misconception that anybody
who ends up
-
creating something like Rails or
-
doing something else within
-
software development or computer science,
-
well, they must have
-
been programming since they were five years
old, right.
-
The whole notion of a hacker is somebody who,
-
who sort of got their first computer twenty
years
-
ago and was just programming the entire time.
Well.
-
That wasn't me.
-
I did not learn to program when I was
-
five years old. I didn't learn to program
until
-
I was closer to twenty. I'd been interested
in
-
computers for a long time, but it wasn't really
-
until the late '90s, early 2000 that I dove
-
into computer programming as something that
I was going
-
to do.
-
I had a lot of friends who were doing
-
it. I knew a lot of programmers. But somehow
-
it, it sort of never, never caught on. Before
-
I started writing software that I needed for
myself,
-
and before I found sort of a place in
-
the software world for that to happen.
-
And the reason I, I say that is, is
-
I've seen a number of essays of like, what
-
is a true hacker, and, and as a true
-
hacker, one of the things that keeps being
thrown
-
out is those ten years, right. You should
have
-
been programming for ten years already,
-
otherwise you're way behind.
-
Well, I learned to program about three years
before
-
I released Ruby on Rails. Turned out fine.
-
And I don't say that as, like, it was
-
because I grew up on a farm and didn't
-
know what a computer was. This is me in,
-
in the center there with the stick, and the
-
blue shirt in 1985. These are the kids that
-
were living in my neighborhood.
-
In 1985 I got introduced to my, my first
-
computer. And I was about five years old.
And
-
I got introduced to computers through gaming.
Sort of,
-
we were playing ninjas in the streets around
our
-
houses, and then we'd play ninjas on the box.
-
And I found it fascinating right from the
get
-
go, right. Computers were really
-
fascinating and games really
-
captured my imagination early on. I remember,
at, at
-
that time, there were certain, lots of parents
were
-
like, well make sure you get out and play
-
a lot. Because you don't want to spend your,
-
or wasting your time, that was the, that was
-
the word, wasting your time in front of computers
-
inside, right.
-
Well, I really did want to waste my time
-
in front of computers. And this was the computer
-
to have in 1985, in our neighborhood. But
we
-
couldn't afford a computer like that. There
was only
-
one guy in the whole neighborhood that had
a
-
computer like that. So we all shared it and
-
we all played Yeah, Kung Fu, in turn.
-
But then the next year, so, I, I couldn't
-
afford this computer, but my dad somehow,
he was
-
fixing TVs and stereos, he traded a stereo
with
-
this guy for this other weird computer, which
was
-
an Abstraught 646.
-
And I was really excited. It didn't actually
play
-
Yeah, Kung Fu. I was a little disappointed
by
-
that, but it had some other crappier games.
Anyway,
-
it was a computer. And that was sort of
-
my first introduction to, to computers, six
years old.
-
And, and I tried to learn programming.
-
I, I got a magazine and, at the back
-
of these magazines back then, there were programs
you
-
could type in. And I was like, wow, this
-
is, this is amazing. I can control this computer.
-
So I built my first information technology
system.
-
It was messages to my mom of where I
-
went, where, I had this clever system that
would
-
really optimize the fact that writing a message
of
-
where I went and, and when I was going
-
to be home, it was too complicated. It would
-
be much easier if I just wrote a little
-
note where I gave her the location on the
-
tape that she had to fast forward to, and
-
then she could read where I was.
-
I thought, man this is so clever. I just
-
have to write down two twenty-eight, and then
I
-
could preprogram that note, and she'll never
know I
-
was over at Peter's house playing Yeah, Kung
Fu.
-
That really wasn't programming, right. I just
typed some
-
stuff in. I didn't know what the hell I
-
was doing. I just somehow figured out print,
OK,
-
that puts stuff up on the screen. That was,
-
that was the extent of it, right. But it
-
was my first stab at programming. And I, and
-
I, it kind of failed.
-
That was the extent of my programming, that
I
-
knew how to fast-forward to a pre-recorded
message.
-
Not that great.
-
So a couple years later, late 80s, I saw
-
this game for the first time. Battle Squadrant.
And
-
I remember thinking, holy shit, these graphics
are amazing.
-
How can they make this? This looks so good,
-
when you were used to a Commodore 64, the
-
graphics of the Amiga 500, which is mind blowing,
-
right. And once again, I felt this, like,
wow,
-
wouldn't it be amazing to be part of that?
-
To be able to create something like that?
-
I'd love to make games.
-
So I sort of started looking around, and,
and
-
I found this thing called Amus. I don't know,
-
has anybody here ever programmed in Amus?
Not a
-
single hand. OK. Must have been a very European
-
thing.
-
But it was sort of a real programming environment,
-
and, and I got the box, and sort of
-
my English was a little, not that great, so
-
I was sort of just reading through it and
-
trying to find the code. And it was all
-
about sprites and vectors and ifs and variables,
and
-
it, it didn't make any sense to me at
-
all.
-
So I thought, eh this is a little bit
-
too hard. Thankfully, there was something
called Easy Amos,
-
right. Oh, wow, that's gonna be great. This
other
-
one was too hard. Now I just have to
-
do the easy one.
-
Unfortunately, in Easy Amos, it was still
programming, and
-
it still had conditionals and variables and
all these
-
other things I just did not understand. I,
it's
-
so funny, because, once you learn something,
it can
-
sometimes be hard to go back and think, like,
-
how was it before I knew how to do
-
this? But I distinctly remember, why would
you have
-
a variable?
-
Like, if you just assign something once, why
would
-
you ever sort of want to change that? Why
-
does it have to be a space. Why can't
-
it just be the thing. Like, I did not
-
get the concept of variables.
-
And this is at, I don't know, age ten
-
or whatever. So, still not getting programming.
It's still
-
not making any sense to me. So I gave
-
up on that, too.
-
Then, in 1993, I went to something called
the
-
Gathering. The Gathering three, which was
a big demo
-
party in Denmark, where people from all over
Europe,
-
maybe some from the U.S. as well, would gather
-
to, to show off their skills of creating these
-
demos.
-
And demos were basically just, like, little
music videos
-
with computer graphics. And I thought that
was really
-
awesome. And, again, I got this sensation
of, wow,
-
that's amazing. People are creating these
sequences, they look
-
really good. This is, this is awesome. I'd
love
-
to be a part of that.
-
This is '93, so I'm, I'm fourteen. And this
-
demo party, and then I met pretty much everybody
-
I knew for the next ten years in, in
-
computer software, including Allen of TextMate
fame. I was
-
fourteen and he was part of one of these
-
demo groups, and we got talking, and then
ten
-
years later, I'd help him release Textmate,
and this
-
is now twenty years ago.
-
Anyway.
-
I still didn't get the concept, right. Like,
it
-
was all, it was Assembler. So it was even
-
harder and weirder to figure out than Amos
was.
-
It was vectors, it was math, it was, it
-
was just really hard. So once again, this
is
-
the third time I tried to sort of figure
-
out programming, because I want to build stuff.
-
And the third time, it failed.
-
So I ended up building another information
system. At
-
that time, there's something called BBS's.
So pre-internet, you
-
dialed up to basically every web site individually
through
-
a modem, and I ran one of those things.
-
At that time, it was, it was called a
-
Where's BBS, which is where we traded all
the
-
illegal software that we couldn't afford,
and games, and
-
demos.
-
And I had a lot of fun doing that.
-
I was fifteen and I was, I was working
-
at a grocery store, and I spent all my
-
money buying modems and phone lines.
-
But sort of the long and the short of
-
that is that I failed to identify with programming
-
under the computer-science paradigm.
-
Computer science, in itself, just didn't really
appeal to
-
me. Like, it didn't make sense to me. Learning
-
programming through sort of the lens, the
prism of,
-
of hard science just, it didn't really, it
just
-
didn't click. And I was actually pretty disappointed
for
-
awhile. I had tried to learn programming three
or
-
four times over the past ten years of my,
-
my life, and it just, it wasn't clicking.
-
No surprise to sort of my teachers. This is
-
my high school diploma, part of it, and it
-
says math, final exam, F. And, and English,
I
-
got an A. But math was just never my
-
thing. Physics never, was never my thing.
-
Any of the hard sciences were just never my
-
thing. And you say, oh, well that explains
a
-
lot. That's why Rails is so fucking slow.
-
But it, it's true. It just never appealed
to
-
me. But, I think it also inoculated me with
-
something really early on, which was, it disabused
me
-
of the thinking that I was a computer scientist.
-
That I was ever going to come up with
-
an algorithm. That I was ever going to make
-
any ground-breaking discoveries at the low-level
of, of computer
-
science.
-
And that was actually really a relief. Because
when
-
I finally got into programming, I knew that
was
-
just not what I was going to do with
-
it. That was never, it wasn't my idol, it
-
was not what I was chasing. I wanted to
-
build information systems. Like all these
attempts I had
-
over the years, they were all about information
systems.
-
They were about using the computer to build
something
-
else that really didn't have much to do with
-
the underlying things. That there were people,
smart people,
-
who had come up with algorithms underneath
to, to
-
make it all work, wonderful. I'm not one of
-
them.
-
And that's fine.
-
I think as an industry, very few people have
-
gotten to that realization. Even if it is,
that
-
they, on a daily basis, build information
systems. Even
-
if it is that they're working on yet another
-
social network for sock puppets, or horror,
in my
-
case, yet another fucking to-do list. The
aspiration of
-
the whole industry, everyone in it, is that
we're
-
all programmers.
-
Right?
-
No we're not. I am nothing like Linus, right.
-
He's actually a real computer scientist. To
figure out
-
how to, I don't know, fucking improve the
scheduler
-
in the kernel. Shew. No clue. No interest.
All
-
good.
-
I am ever in debt that there are people
-
like that out there who can do this stuff.
-
So I don't have to do it. So I
-
can focus on something else. But I think most
-
programmers think that, oh yeah, that, that's
what I
-
do. Yeah, I work information systems, but,
we're kind
-
of colleagues, right? Me and Linus here.
-
I'm pretty sure that he would tell you, fuck
-
you. We're nothing alike. We are not colleagues.
What
-
you do is making another fucking to do list.
-
I'm improving the fucking kernel of Linux.
Far more
-
important work. He would disabuse you of your
delusions
-
of grandeur real quick.
-
And I think that's a real shame. I think
-
it's a real shame that if you sort of
-
pick your heroes in such a impossible fashion,
that
-
they're actually nothing like you and you
will be
-
nothing like them, you're gonna set yourself
up for
-
a bad time for the whole ride.
-
The truth of the matter is that most information
-
system development has very little to do with
science.
-
Yes, it's all built on top of computer science.
-
Yes, computer science is what makes it possible
for
-
us to do what it is that we do.
-
But it doesn't define what we do.
-
And I think in many ways that prism of
-
computer science is harmful to the development
of information
-
systems. It's actually not a good view on
the
-
world to have. Just because you can make,
you're
-
Steingraeber and Sohne, and you can make the
best
-
piano in the world, that doesn't make you
a
-
great pianist. It doesn't mean you can play
wonderful
-
tunes. Just because you can create the foundations
of
-
which other people can build upon, just because
you're
-
a great computer scientist, doesn't mean you're
a great
-
software writer.
-
Doesn't mean you're a great programmer of
information systems.
-
And most of all, if you are committed to
-
building information systems, and I am wholly
committed to
-
building information systems, I've given up
the notion, long
-
ago, that I was going to get into games
-
programming or vector programming or anything
else that sounds
-
like hard science and is hard.
-
I think you're gonna be much better off. But
-
I think it's also really tough, because I
think
-
most of the paths, the celebrated paths into
programming
-
go through courses called computer science.
So you're sort
-
of taught right from the get go that computer
-
science, like that is the ultimate ideal,
and what
-
you're doing here is just sort of piddling
along
-
until you can get to this top of the
-
mountain.
-
Even worse, if you actually have a degree
in
-
computer science, right, and now you're slumming
it, with
-
yet another social network, or, yet another
fucking to-do
-
list. I mean, that's a recipe for self-loathing
if
-
I ever knew one.
-
But, as I say, this is mostly about the
-
prism of how you're looking at programming,
what is
-
programming, what is writing software. What
is that we
-
do every day when we create information systems?
-
And if you look at it from this prism
-
of the hard sciences, you think, well, Law
of
-
Thermodynamics. Physics. This is, this is
the real serious
-
hard stuff, right. You will laugh at French
poetry.
-
Ha, ha, ha, ha! They're all just, what, analyzing
-
what some schmuck in the 1700s did, and there's
-
a thousand different interpretations of, of
what that person
-
actually wrote and what does that actually
mean? Like,
-
that's pathetic, right. You can't arrive at
any ultimate,
-
clear, universal truths.
-
Math! There's a truth. There's a final result.
Physics.
-
There's a truth. We're knowing more about
the natural
-
world in a way where we can be completely
-
confident. Mostly. In what we know. Certainly
in math,
-
right.
-
If you carry that over into programming, you
end
-
up with shit like this. Law of Demeter. Practices
-
and principles who sort of project that they're
universal
-
truths about the natural world, that this
is how
-
good programs are made, and this is not really
-
an argument. The only argument is whether
you're professional
-
and following the laws, or you're an amateur
and
-
you're breaking them.
-
When I look at computer programming, and when
I
-
reach most, read most programs, I'm not reading
hard
-
sciences. It is much more like studying 17th
century
-
French poetry. What the fuck did this guy
mean?
-
Like, I can't follow this at all. Like, is
-
this some weird reference to some play somewhere?
What's
-
going on here?
-
It's actually more like forensics. It's more
like analysis.
-
It's much more subjective. Like, what is actually
going
-
on? What were they trying to communicate?
What's just
-
going on here, right?
-
So, I find it so funny that, that programmers
-
who work in programming, and they laugh at
all
-
these subjective fields of endeavor, when
that is what
-
they do every day. They just, no, what I'm
-
doing is computer science. This is empirical
truth, blah,
-
blah, blah, we have laws, blah, blah, blah.
-
I think the, the bottom line is that is
-
when you go in with that notion, when you
-
go in with the notion that we can actually
-
discover laws of programming, like, Law of
Demeter, of
-
how we should be creating our programs, you
lull
-
yourself into this belief that there are some
practices
-
that are just true. They're not up for debate.
-
They're not up for discussion.
-
They're science. That what we do is science.
Well,
-
I think there's another word for, sort of,
those
-
delusions. Pseudoscience. When people think
they're doing science and
-
they're not actually doing science. That's
pseudoscience. I think
-
a lot of what's going on in software, methodology,
-
practices, is pseudoscience.
-
Which would be fine if people would accept
that
-
and say, yes, what I'm doing is pseudo science.
-
Like, I'm not finding any grand truths here,
but
-
they're not, right. They're ex-pouting that
this is, this
-
is the truth.
-
Well, here's another pseudoscience. Diet schemes.
I think diets
-
are actually incredibly similar to most software
methodology approaches.
-
They all sort of espouse that I have the
-
truth, what you need to get slim and healthy
-
is the ten-day green smoothie cleanse.
-
That is the truth. That's how you get it,
-
right. And then you, shit, that, that's, OK,
smoothies.
-
Sounds good. But what about this super shred
diet?
-
Like, I lose twenty pounds in four weeks?
That's
-
certainly better than ten pounds in, I don't
know,
-
ten weeks, or whatever that hungry diet girl
is
-
promising. I'll go with that super shred guy,
like
-
he's got to have the truth, right.
-
And it's so funny, if you read any diet
-
books, and diet books are incredibly popular.
If you
-
look at the most popular book on Amazon, the
-
top one hundred list, a lot of them are
-
diet books. People want to be told how they
-
can cheat the basics. I think software development
is
-
exactly like that.
-
I think software developers are exactly like
people trying
-
to lose ten pounds and thinking, you know
what,
-
all this exercising, just eating healthier,
that's a little
-
too hard. Let's, let's listen to this super
shred
-
guy.
-
He's got to have the answer. An answer that's
-
less painful, less simple and basic. There's
got to
-
be some grand secret I just don't know yet.
-
If I can just learn the secret then everything's
-
gonna be great, right. But it's pseudoscience.
Those diets
-
are based on anecdotes. They're based on one
guy
-
trying something, or, or looking at a few
people,
-
a tiny sample size, it's just pure, poor,
pure
-
poor science.
-
External variables, uncontrolled experiments
that run for too long.
-
You can't derive any absolute truths from
it. But
-
people keep arriving at absolute truths.
-
And just like feeling a little overweight,
and most
-
people do at some point in their life. Everybody
-
wants to lose whatever it is. They want to
-
feel healthier even if they are at the correct
-
weight. They want to be in better shape. All
-
our code bases are exactly like that.
-
Everyone has like, oh I'd love that this part
-
of the code base, it's not that clean, right.
-
So we have that same feeling of being a
-
little insecure about our quote code quality,
just like
-
most people are a little insecure, at least
at
-
certain times in their life, about their body,
right.
-
So we're ripe for somebody to come in and
-
tell us what's wrong. To fix it for us
-
by just saying, oh, no, no, no, you don't
-
have to do any of the hard stuff. Writing
-
good code, do you know what that's about?
It's
-
about this one practice. This one secret that
they
-
don't want you to know.
-
If I teach you that, then all your code
-
is going to be wonderful. But right now, you're
-
not a professional. You're an amateur. You're
writing dirty
-
code. You should feel really bad about that.
You
-
have sinned.
-
But, I will give you absolution. I have the
-
pathway to clean code.
-
And it hits a lot of people right in
-
the impostor plexus. Like, ugh, you're saying
my code
-
is dirty? Yeah, I guess it is a little
-
dirty. There's this one part that's, like,
shit, maybe
-
I'm not really a computer scientist. Maybe
it doesn't
-
really, I don't really belong here amongst
the programmers.
-
Can you please tell me, how do I get
-
to be a computer scientist?
-
How can I get to belong amongst the esteemed
-
professional programmers? Can you tell me
how? And there
-
are lots of people willing to tell you how.
-
That the salvation will come through these
patterns and
-
practices, and as long as you follow these
ten
-
commandments of good code, all shall be well.
-
OK.
-
I think the most popular commandment, I'm
gonna spend
-
some time on that, the most popular practice,
the
-
most popular pattern for making people feel
shitty about
-
their code and shitty about themselves and
shitty about
-
their path through programming, is TDD.
-
TDD is the most successful software diet of
all
-
times. It's so alluring, it has such an appeal
-
in its basic principles, that everyone gets
wrapped up
-
in it. I got wrapped up in it for
-
quite awhile. I got wrapped up in the storytelling
-
that all software before TDD was shit and
unprofessional.
-
And that the only way to arrive at clean
-
code was to follow the principles of TDD.
-
And the principles of TDD, mind you, are not
-
about the tests. It's about test first. It's
about
-
test-driven design, right. That we have tests
afterwards, that's
-
just an accidental side-effect. A benefit,
if you will,
-
after the fact. And it's the perfect diet.
-
I tried multiple times, which is usually how
it
-
goes with diets, we try one and it doesn't
-
really work and we fall off the wagon and
-
then a few months later you try again and
-
you feel bad about it the whole time and
-
that's how I felt about TDD for a long
-
time.
-
I felt like TDD was what I was supposed
-
to do. I was supposed to write all my
-
tests first, and then I would be allowed to
-
write my code. And it just didn't work. I
-
kept just feeling like, this is not, I'm not
-
arriving at something better here. When I'm
driving my
-
design by writing my tests first, the code
I
-
look at afterwards, it's not better. It's
not cleaner.
-
The dirty code I wrote without being test-driven
first,
-
it actually looks better.
-
But, so successful has TDD been, that for
the
-
longest time, until actually fairly recently,
I just thought,
-
well, I'm the wrong-doer. I'm the one doing
it
-
wrong. TDD is not at fault, right. Just because
-
everybody's doing TDD wrong, doesn't mean
that there's anything
-
wrong with TDD. There's just something wrong
with all
-
of you. That's the problem.
-
If you would just be more faithful to the
-
practices, then everything would be great.
-
And that's what makes it such a great diet.
-
That it keeps people in the perpetual state
of
-
feeling inadequate. So, you keep having to
buy more
-
books, and attend more conference talks, and
attend more
-
workshops, and hire more consultants, to teach
you to
-
be truer to the religion of TDD. Hogwash.
-
Let's look at some code. So here's a very
-
simple piece of code. Person has an age method,
-
that calculates how old somebody is. And we
have
-
a test for it. This piece of code depends
-
on the world.
-
It directly refers to date today. It's a explicit
-
dependency. You cannot change it in there.
Well, in
-
a lot of languages, that's a problem. Like,
how
-
are you actually going to test this if you
-
can't somehow figure out how to change the
date
-
of today. Like, every time you run your test
-
it might be a different day and it might
-
be broken.
-
Well, in Ruby it's really easy. We just stop
-
that constant and make it work. That's what
the
-
travel-to method is about, right.
-
Proponents of TDD will look at that code and
-
say, dirty, dirty code. Explicit dependencies
hidden inside. You're
-
mocking a global object? What the fuck?
-
You need to shape up. Here's the shaped up
-
version. We inject our dependency, so we have
a
-
default of date.today, but we can put in our
-
own, in the test, we can put in our
-
own date, right. This is much cleaner. Right.
No.
-
Great. We improved our code base.
-
Did we? Is this a better code base? Is
-
this method better than what we just had there?
-
Is it simpler? Is it clearer? No. It's easier
-
to test. And that's the important point, right.
That's
-
the important point in all of these debates,
is
-
just, is it easier to test?
-
That's the measure of success. I think that's
a
-
shitty measure of success. I think there are
much
-
higher ideals than just whether something
is easy to
-
test. But it gets worse.
-
Here's another example. If you actually have
a method
-
that depends on another method, we have to
inject
-
the dependency all the way down, now you're
really
-
muddying things up and now the code is really
-
starting to get nasty. And this is such a
-
simple example. I've actually posted this
example online before
-
and had arguments with TDD proponents about
that.
-
And, yes, this is, I'm like, well, what does
-
it matter? You're just injecting one dependency,
what does
-
it matter? It's not that big of a deal,
-
right? Yes it is.
-
Because this is exactly the type of thinking
that
-
leads you down a really nasty path. Let's
look
-
at another example.
-
Here's a standard Rails controller. It has
reliance on
-
the world. It relies on a before action that
-
ensures permissions. It sets up a new object
and
-
sends out an email and then it responds to
-
something, right. The whole purpose of the
controller in
-
Rails is to sort of direct the world. It's
-
to interact with the world.
-
But how do you unit test that, right? That's
-
really hard. It's relying on the entire world.
If
-
we're following this scientific approach of
unit testing where
-
we're isolating all the variables, holding
everything else constant
-
except for these two things, what goes in,
what
-
goes out. This is bad, right.
-
If we instead put in something like a person
-
creation command and hide away all the actual
doing
-
of the control and then we inject all the
-
stuff that it depends on we can test person
-
creation command really well.
-
Is that code better? Is that code simpler?
Is
-
it clearer? Would you rather look at this
and
-
then understand what the system does or would
you
-
rather look at this and try to figure out
-
where does this thing go?
-
And that's the consequence of this chase of
test-first.
-
It leads you down a path where the gospel
-
of test-driven design is that anything that's
easier to
-
test is better. That's it. That's the measure
of
-
quality. If you can test it easily it's better.
-
If you can't test it easily, it's worse.
-
Boo. Exactly right. Boo.
-
It's not better. We're losing sight of what
we're
-
actually trying to do. Tests were supposed
to support
-
us. They weren't supposed to be the main thing.
-
And I think this is leading to a lot
-
of Zombie astronautic architectures. Things
that I thought we
-
moved past long ago. If you look at, at
-
this person create command, that reminds me
very much
-
about Struts 1 point 2, and how they had
-
every action as their own object. And that
it
-
was great because it was easy to test, and
-
it was shit when you were trying to put
-
a whole architecture together, because you
had all these
-
create commands and all of the sudden you
had
-
a million objects. Yes, they were easier to
test,
-
but the system was much harder to reason about.
-
You see the same thing around ActiveRecord,
for example.
-
You see, well ActiveRecord should just be
data access
-
objects. They shouldn't actually have any
logic. They should
-
just be about interfacing with the database,
because then
-
we can split out everything else. Our domain
logic,
-
it's just that it doesn't have to touch the
-
database, so that our tests can be simple,
so
-
that our tests can be fast, right?
-
Again. Order of priority. Test, test fast,
oh, your
-
architecture. That'll just fall from that,
right?
-
I recently read James Coplien, has a great
paper
-
out called "Why Most Unit Testing is Waste."
And
-
for me, this is the money quote. Splitting
up
-
functions to support the testing process,
destroys your system
-
architecture and code comprehension along
with it. Test at
-
a coarser level of granularity.
-
TDD is focused on the unit. The unit is
-
the sacred piece, because that's the science
piece. That's
-
what we can control all of the variables.
We're
-
just looking at these few pieces, right.
-
What James is saying, maybe that's not the
right
-
level. Maybe testing, the role it should have,
shouldn't
-
be about the unit most of the time. And,
-
I sort of alluded to this awhile back, I
-
wrote a post called Testing Like the TSA,
and
-
the main thing about that was about over-testing
and
-
sort of this testing theater that goes on.
But
-
I hadn't really made the switch that it, the
-
problem is that we're trying to test at the
-
wrong level.
-
It's not testing itself. Testing is great.
I'm not
-
advocating that we shouldn't have tests. I'm
advocating that
-
driving your design from unit tests is actually
not
-
a good idea. That you actually end up destroying
-
your system architecture and your code comprehension
along with
-
it.
-
So if unit tests aren't the thing, what could
-
we do instead?
-
Well, I think there are higher levels of testing.
-
We've already sort of moved to that in Rails.
-
It's no longer called test unit, where you
place
-
your tests, it's called test models. That's
already one
-
step up. That sort of frees you from feeling
-
bad about the fact that your, your model tests
-
actually touch the database. That's not a
bad thing.
-
Yes. They run slower. But they also test more
-
things.
-
You can make anything fast if it doesn't have
-
to work.
-
And I think that's the problem with testing
in
-
a lot of cases. We recently had a really
-
bad bug on base kim where we actually lost
-
some data for real customers. And it was incredibly
-
well-tested at the unit level. And all the
tests
-
passed. And still we lost data. How the fuck
-
did that happen?
-
It happened because we were so focused on
driving
-
our design from the unit test level, we didn't
-
have any system tests for that particular
thing. And
-
it was a really simple thing. It was like,
-
if you were editing an object and you were
-
editing the attachments, you could lose an
attachment. And
-
we lost some attachments and it was a terrible
-
thing.
-
And after that, sort of thought, wait a minute.
-
All these unit tests are just focusing on
these
-
core objects in the system. These individual
unit pieces.
-
It doesn't say anything about whether the
whole system
-
works.
-
Most TDD proponents, I find, are much more
focused
-
on the unit level, because that's where they're
driving
-
their design. And they're not very much focused
on
-
the system level at all, which is what people
-
actually give a shit about.
-
Does the system work? I don't care about whether
-
your units work. Does the whole thing work?
That's
-
what matters.
-
So that kind of freed my mind up a
-
little bit. That if we give up this need
-
for hard science experience, where we have
to control
-
all the variables and boil everything down
to a
-
single unit that can be tested, we can float
-
freely with the world.
-
Awesome.
-
This realization, I came to realize, was why
people
-
hate fixtures. So fixtures in, in Rails is
about
-
spinning up a world, it's about setting up,
sort
-
of, small size version of the whole world.
Where
-
most approaches, they focus on just one unit.
-
I don't want to have an account in here
-
and a project in here if I'm just testing
-
my message. I just want to test this one
-
single thing, right. And if you're doing that,
yeah,
-
fixtures are probably not a good thing. It
doesn't
-
really work for that.
-
It works really well when you're not concerned
about
-
the hard science focus on unit tests. It works
-
really well when you're focused on a larger
level.
-
When you're focused on models, when you're
focused on
-
controllers, and most importantly when you're
focused on systems.
-
But all that is sort of usually swept away
-
by the holy trinity of test metrics. Coverage,
ratio,
-
and speed.
-
I've been in a lot of internet arguments lately.
-
In such esteemed establishments as Hacker
News, and, and
-
elsewhere, and I find it really interesting,
because each
-
individual argument will make me rage, but
then the
-
larger set of all arguments, like a meta study,
-
actually reveals really interesting things
about what people care
-
about. What they value.
-
And what I find is, in most discussions about
-
design, especially around Rails, what people
care about these
-
things, and these things only. It's about
the test
-
coverage. It's about the test ratio. And it's
about
-
how fast your tests run.
-
Like, that's the pedestal. That's the holy
grail. What
-
actually happens underneath, the design of
the rest of
-
the application is, eh. Doesn't really matter.
-
And thus, a lot of people come to celebrate,
-
oh, I have a one to four test ratio.
-
For every line of production code, I have
four
-
lines of test. Oh yeah.
-
And they say that with pride. And I'm like,
-
what? So you're saying for every line of production
-
code you write, you have to write four lines
-
of code? And that somehow makes you a hero?
-
How, how does that work?
-
So your system is now five times as large,
-
reasoning about the whole system is now five
times
-
as complex, and you're proud of this, why?
Well,
-
of course, because I have a hundred percent
coverage.
-
My five thousand tests run incredibly fast
because they
-
never actually test very much.
-
They certainly do not test the system. They
test
-
all these little slices of unit. Wonderful.
-
It's not wonderful. You have anemic fucking
tests. They
-
don't prove shit. You're gonna have the same
bug
-
that we have on base camp, and the system
-
is not going to work even though you've proudly
-
proclaimed, oh, well, your units are working.
-
Well, whoopity-doo. This decoupling is now
free. People think
-
that, oh, this is like that saying, like,
quality's
-
free. Right. Testing is free. Not when you're
doing
-
it like this. It's not free.
-
And most importantly, it's not free, not so
much
-
in time, but in conceptual overhead. Understanding
a system
-
that has been test-driven designed from the
unit perspective
-
is really hard. Because you have all these
levels
-
of indirection. You have all these levels
of intermediation.
-
To separate the tests from slow things, like
HTML
-
or the database or, any of the other parts
-
of the system that actually makes up your
system.
-
And they focus just on that one thing. So
-
they can be very fast, if they don't have
-
to work. They don't actually have to test
your
-
system.
-
So that's sort of two charges in one. It's
-
a charge first that your design is not going
-
to improve. Your design is going to deteriorate
by
-
doing test first programming, because you're
going to construct
-
your units of testing, your methods, in a
different
-
way, like we say with the age example. You're
-
going to inject all your dependencies in a
way
-
that does not prove things.
-
And second of all, you're not gonna get the
-
benefit of great coverage. You might have
a lot
-
of tests, but they don't test your system.
It
-
doesn't improve your confidence in actually
the whole thing
-
working, and then what good is it?
-
Well, I thought about this for a long time
-
and thought, like, this is not really, it
doesn't
-
seem like that great of a revelation. Why,
why
-
do I keep having these arguments over and
over
-
again? Why are people focused so hard and
so
-
intensely on this trinity of test metrics?
How did
-
that come to be the main thing that people
-
are arguing about?
-
How did that come to be the main decider
-
of what's good design and what's bad design?
Really,
-
couldn't really figure it out. Until I started
thinking
-
back of like, what is this prism we're looking
-
through? We're looking through computer science.
Engineering. Professionalism.
-
James Harrington wrote a bunch of books on
quality
-
of engineering, and he has a great quote here.
-
If you can't measure something, you can't
understand it.
-
If you can't understand it, you can't control
it.
-
If you can't control it, you can't improve
it.
-
That makes a lot of sense. Cause like, yeah,
-
yeah, that makes sense. That's gotta be why.
And
-
then I got another great quote. Just because
you
-
can, just because something is easy to measure
doesn't
-
mean it's important.
-
This, I think, is exactly what's going on
here.
-
Programming of information systems is a lot
more like
-
French poetry than it is like physics. But
programmers
-
grow up thinking that they're computer scientists,
so they
-
want it really badly to be like physics. They
-
want it really badly to be a hard, professional
-
science.
-
And coverage, ratio, and speed. You can get
that
-
fucking thing down to six decimals. Like,
that, I
-
can be so precise about how fast my test
-
runs, eighty-four point seven percent coverage,
boom. Got it.
-
Doesn't say anything about whether or not
that's actually
-
important. Doesn't say anything about whether
that's actually producing
-
a good system. Doesn't say anything about
whether the
-
person after you, or you yourself, three months
from
-
now, can understand what the hell is going
on
-
in this code base.
-
You haven't necessarily made anything any
clearer. You've made
-
it very easy to produce metrics. And if there's
-
one thing we love with, with science, it's
clear
-
concise objective truths and coverage and
ratio and speed
-
fit that bill. So we adopted them with open
-
arms, even though they were not that important.
-
Second part of it. Cost is not value. A
-
lot of people have invested so much in building
-
up their expertise, their time, their four-to-one
ratio in
-
tests. The investment is massive. Well, of
course they're
-
gonna be defensive about it. Like, you've
invested so
-
much of your ego and your time and your
-
resources on this project, into testing. So
of course
-
it must be valuable. Of course it must be
-
important.
-
That's not how it works. Just because something
is
-
really expensive, just because something takes
a lot of
-
your time doesn't mean it's valuable. Doesn't
mean it's
-
important.
-
So I was sort of giving a brief description
-
of this talk yesterday at dinner with Aaron
Patterson,
-
and he trolled me right back and said, TL;DR,
-
just don't test, right. Like, that's what
I'm supposed
-
to get out of this.
-
No. No. Testing absolutely has value. Regression
testing absolutely
-
has value. Driving your design through test
first? In
-
my mind, rarely has value. Not never. There
are
-
times where I'll write my tests first, usually
when
-
it's something like a translator of some kind,
where
-
I know exactly what's going in and I know
-
exactly what I want out.
-
That could be a good case to start with
-
test first. Most information system design
is not like
-
that. I'm trying to figure out and sell what
-
the system is supposed to do. What I'm going
-
to arrive at is the test, is this set
-
of tests, it's a set of regression tests,
that
-
make me feel good about that after the fact,
-
that I can still change my system and not
-
break it, right.
-
So TDD. Kent Beck. Main proponent behind TDD
has
-
a very sensible quote that goes exactly along
these
-
lines. I get paid for code that works, not
-
for tests, so my philosophy is to test as
-
little as possible to reach a given level
of
-
confidence.
-
Immensely sensible. I find that that's actually
often the
-
case with these things that get taken too
far.
-
TDD started out as a pretty sensible thing.
Kent
-
has an even more sensible perception of it
now,
-
I think, than when he wrote the test-driven
book
-
originally. But that's not what most people
take away.
-
That's not what most people run with if they
-
want to build a career on making people feel
-
shitty about their code bases and their dirty,
dirty
-
code.
-
They take a much more extremist approach,
that unless
-
you're doing test-first, you're not a professional.
Certainly not
-
what Kent's saying.
-
OK. So for me, this really boils down to,
-
we're, we're trying to wear the wrong hat
the
-
majority of the time. Thinking of yourself
as a
-
software engineer will lead you down the path
of
-
coverage, speed, metrics, hard sciences - all
these things
-
we can measure and it leave you laughing at
-
shit like interpretation of French poetry.
Of subjective evaluations
-
of a design in the system, even though these
-
are the only tools that we have.
-
So this has taken me awhile to arrive at
-
this conclusion. I've hated the word software
engineer for
-
quite awhile. Cause I never felt it fit me.
-
I never thought of myself as a software engineer.
-
I kind of tried to be one, a few
-
times, and I failed all the time. And by
-
the time I finally arrived at programming
as something
-
that I wanted to do, it sure as shit
-
wasn't software engineering.
-
Yes. It's a hard hat that I wear occasionally,
-
when I do performance optimization. That's
hard science. You
-
make a change. You measure it. Was it an
-
improvement? If not, revert. If yes, deploy.
Very scientific.
-
Very good.
-
Great to wear the hard hat when that fits.
-
Is what, that what I do the majority of
-
the time? Is that how I think of myself
-
when I write most of the things that I
-
write? When I add a new feature to base
-
camp or do forensics to figure out how a
-
bug came about, or what somebody meant when
they
-
wrote a bug in or something? No. That's not
-
what I do.
-
So I don't try to think of myself as
-
a software engineer.
-
OK. If we're not software engineers, most
of the
-
time when we make information systems, what
are we
-
then? What other hat should we try to wear?
-
What other identity should we try to aspire
to?
-
I think we had it all along. I think
-
we had it in the language all along. We're
-
software writers. Writing is a much more apt
metaphor
-
for what we do most of the time, than
-
engineering is. Writing is about clarity.
It's about presenting
-
information and motivations in a clear-to-follow
manner so that
-
anybody can understand it.
-
There are not bonus points for making something
convoluted,
-
as there often is with engineering and with
test-first
-
design. Making things more convoluted gives
you the benefits
-
of, perhaps, easier to test. They don't give
you
-
clarity. So those things are often in opposition.
-
Clarity is all about being succinct without
being terse.
-
WE can write things using as small words as
-
we know how, using as little complication
as we
-
know how, using as little conceptual overhead
as we
-
know how to get the job done.
-
That's a much better approach. And I think
it
-
comes very easy if you think of software development
-
as writing. If you look at a piece of
-
writing that somebody has written and it's
kind of
-
convoluted, can't really follow the argument,
and paragraphs are
-
not broken up neatly, is the first thing you're
-
gonna say, you know what the problem with
this
-
is? You're not using big enough words.
-
If we just shoved some bigger words into this
-
text, it's gonna be there. That's good. Oh.
The
-
problem here is like, like your sentences
are too
-
clear. If you just insert a sentence in the
-
middle, that'd be great. Oh, do you know what?
-
This needs more semicolons. That's what this
needs. If
-
this has more semicolons, boom. You got clarity.
-
No. More indirection. More third-person. These
are not the
-
things that make for great, clear writing.
And that's
-
obvious when we talk about things like writing.
SO
-
if we talk about software development as writing,
I
-
think it'll be obvious too. I think if we
-
supplant the high ideal of what matters for
design
-
is how easy it is to test, how easy
-
it is to make engineering driven, and put
clarity
-
of the code base above all else, we're gonna
-
be much better off. And arguments are gonna
be
-
settled much easier. And it's gonna be much
easier
-
to read the fucking code you wrote three months
-
ago, because you had that in mind.
-
That was your motivation. That was what you
were
-
going for.
-
So what is clarity? How do you figure that
-
out, right? That's real easy to say, oh it's
-
just clarity. Boom. It's open to interpretation,
right. It's
-
not as clear as just saying, oh if you
-
can just get your code coverage above 85%
then
-
you're gold, right.
-
Clarity doesn't work like that. There's not
a metric
-
we can just apply, because, again, it's not
hard
-
science. Clarity of writing is not hard science.
-
So the easy answer is, I know when I
-
see it. Right? There's not just gonna be a
-
list of principles and practices that somebody
can be
-
taught and then they will automatically produce
clear writing
-
every time. Right? If you want to be a
-
good writer, is it enough just to sit and
-
memorize the dictionary? No. Just knowing
the words available
-
to you, knowing the patterns of development
is not
-
gonna make you a good developer.
-
You have to develop an eye. You have to
-
develop an eye for clarity, which means first
of
-
all, you have to decide that that's important
to
-
you. So that's the first step. If you're still
-
stuck in, the most important thing about my
system
-
is how fast my tests run, and how many
-
of them I have, well. Forget about it. You're
-
not gonna get to this point.
-
You have to decide that the most important
thing
-
for your system is clarity. When you do decide
-
that, you can start developing an eye. I started
-
getting into photography maybe six years ago.
When I
-
first got into photography, like, I would
look at
-
a picture and it was like, well, looks like
-
a good picture.
-
Now, I've been looking at thousands of pictures.
I've
-
been taking thousands of pictures. And I've
developed an
-
eye. I can see when the white balance is
-
off. I can see, oh, this has a blue
-
tint. Oh, this actually, if we crop it just
-
a little bit more, only the subjects we want
-
to have in focus are in focus. Oh, this
-
would actually be better in black and white.
-
That eye just came from doing it. A lot.
-
It didn't come from just sitting down and
reading
-
a lot of photography books. And I think it's
-
the same thing with code. I think a lot
-
of programmers, coming at it from a software
engineering
-
angle, thing that just all they have to do
-
is learn the practices, learn the patterns,
memorize them
-
all, and then they will be good programmers.
-
No, they won't. The only way to become a
-
good programmer, where, by definition, I define
good programmers
-
as somebody who programs, who writes software
with clarity,
-
is to read a lot of software, write a
-
lot of software.
-
Just like how do you become a good photographer?
-
You take a lot of pictures. And you look
-
at them. And you practice. And you practice.
And
-
you practice.
-
I think it's quite similar to the problem
with
-
diets, right. The fundamental truth with diets
is to
-
be healthy you should probably exercise regularly,
you should
-
probably eat a reasonable amount and it should
be
-
good stuff. Like, that's three things. Incredibly
hard to
-
do. Most people do not do that, right. Figuring
-
out how to write good software: read a lot
-
of software, write a lot of software, aim
for
-
clarity. It sounds too simple.
-
Why is it simple? Because there's not just
a
-
secret. There's not just one answer somebody
can give
-
you. The only way you can get there is
-
by doing it. So when I first started developing
-
Rails, I read a ton of software. I read
-
the entire Ruby standard library. Partly because
documentation of
-
Ruby at that time was pretty poor, and the
-
only way to figure out how it worked was
-
to actually look at the code. But that was
-
also where I learned so much.
-
Today, we have it so much easier. Bundle open
-
name of any gem, and it'll open, boom, right
-
up in your text editor. You can look at
-
any code.
-
How many of you have read through a complete
-
gem recently. Something you did not write.
Awesome. That's
-
actually really encouraging. I thought it
would be much
-
less.
-
I think that is exactly the path you need
-
to take. You need to read a shit ton
-
of code. And it's not so much just because
-
you read this code and then, oh that's all
-
great stuff. Just as important as it is to,
-
to develop your sense of writing by reading
a
-
lot of shit writing, so is it with code.
-
And I think you will find that that is
-
actually very easy. Because a lot of things
you'll
-
do bundle open on will follow Sturgeon's Revelation.
90%
-
of everything is crap.
-
Well, at least you know you have company if
-
you write crap software and I certainly do
from
-
time to time. And that's a great way to
-
learn. I actually find that I learn the most
-
about software and learn the most about what
matters
-
to me, I learn the most about what clarity
-
is when I read poor software.
-
Because what I do is, I take a piece
-
of software, I take a class or method, and
-
then I look at it, how could this be
-
clearer? Like this is, I think this is poorly
-
written. I think this smells. How can I rewrite
-
it?
-
So by just sitting down and going through
that
-
exercise and rewriting it, I find I learn
a
-
whole lot about what I care about. So that's
-
what I've been doing lately. Engaging in a
lot
-
of these internet arguments. Somebody will
submit a piece
-
of code, and usually the submission will come
along
-
with the proposed solution, too, right.
-
I have this shitty piece of code. Then I
-
learned about these three patterns. And now
it's wonderful.
-
And what I have found every single time, and
-
I've only done this maybe a handful of times,
-
maybe a little more, is that every single
time,
-
you just took the shitty code and you stuck
-
it into some different boxes.
-
Like, it didn't actually improve. Applying
the pattern to
-
it did not improve the underlying clarity
of the
-
code, because you just wrote it poorly. Like,
the
-
problem with the code was not that it was
-
missing patterns. The problem with the code
was that
-
it was crap. That it just had to be
-
rewritten.
-
Now, that leads us to sort of a mission,
-
in some ways, from Rails is and what Ruby
-
is, and it leads also to clarify some of
-
the arguments we've had in the Rails community
for
-
awhile. Readability is incredibly important
to Ruby. We have
-
a lot of duplicated methods that do exactly
the
-
same thing, just so we can improve readability.
-
I remember the first time I saw unless, when
-
I was learning about Ruby. That was one of
-
those light bulb moments. It's like, wait
a minute.
-
Unless is exactly the same as if not, but
-
it's a different keyword. Huh.
-
Right? It was not just about making the most
-
efficient, compact language. It was about
readability. Poof!
-
Mind blown.
-
And decade-long love-affair with Ruby established.
And I think
-
that this is what we're trying to achieve
constantly
-
in Rails as well. A lot of people will
-
gripe about, oh, ActiveRecord is too big or
something
-
is too big, or have too many methods. The
-
surface area is too big or there's, whatever
it
-
is, right.
-
Like, who gives a shit? Is it more readable?
-
Is it more clear? That's the only thing that
-
matters. What do I care whether the surface
area
-
of a method is a hundred methods or it's
-
two hundred methods? I don't give a shit about
-
that. The only thing I give a shit about
-
is whether, is the code I'm actually reading,
is
-
the system I'm trying to understand, is that
more
-
clear. When you put clarity as your number
one
-
mission, a lot of concerns just fall by the
-
wayside.
-
It just doesn't matter anymore. And it's liberating.
-
So, I think this actually comes from sort
of
-
the same rope. I didn't have time to write
-
a short letter, so I wrote a long one
-
instead. I think that describes about eighty
percent of
-
all that ninety percent of shitty code.
-
Most people did not take the time to write
-
a short piece of code, so they wrote a
-
long one instead. And then they wrote that
long
-
one, piece of code, and they like, pulled
out
-
their suspenders and like, oh yeah, I'm done.
My
-
tests pass.
-
Boom. Right? Or they look at it and decide,
-
oh shit, this is too long. I must be
-
missing some patterns. I just sprinkle some
patterns over
-
this. Wonders, right? No. What you wrote was
a
-
draft.
-
This was just a first draft, right. Any piece
-
of code you write down is just a draft.
-
Mark Twain actually had the hard job, right.
He
-
wrote in ink. If you actually had to change
-
that, well that was kind of hard, right. So
-
his drafts were a lot more complicated. Ours?
We
-
have it so easy. A text editor? You just
-
delete stuff. And you don't need any of the
-
little stuff that you, you fill over the page
-
and you spill it everywhere and so forth.
An
-
eraser.
-
You can just delete stuff. Like that's my
favorite
-
key. The delete key. It's the number one tool
-
for improving code. Delete key.
-
So when I was in high school, I submitted
-
a bunch of first drafts as essays, and they
-
were really shitty. And of course they were.
They
-
were the first draft. And my teacher at the
-
time said, oh, all right, all right, this
is
-
actually not bad. You just told me the step
-
one. If you have something on your mind, you
-
should write it down.
-
That's what I did. I, I wrote it down.
-
And then I handed it in. Oh, if you've
-
written something down, you should rewrite
it.
-
Oh. That was the step I missed. And I
-
think that's the step most people miss when
they
-
write down code. Cause they're focused on
all these
-
other things. They're not focused on the clarity,
because
-
when you are focused on the clarity, you will
-
realize that all your first drafts are terrible.
-
All my first drafts are terrible. All my first
-
attempts at writing a good class are poor.
They're
-
too long. They're not at the same level of
-
abstraction. They're not clear. And that's
OK. I wrote
-
something down. I was trying to figure out
what
-
the system was supposed to do.
-
That's hard work. And often times you don't
get
-
perfect code out of that when you're still
trying
-
to figure out what it is that you're writing.
-
But once you've written it down, you should
rewrite
-
it.
-
And I think the key part of rewriting is
-
omitting needless words when it comes to regular
writing.
-
When it comes to programming, it's omitting
needless concepts.
-
It's omitting needless patterns. It's omitting
needless practices. It's
-
omitting needless classes. It's omitting all
these extra things
-
that aren't getting you closer to clarity,
right.
-
How do you know? You develop an eye for
-
it. How do you develop an eye? You read
-
a lot of code. You write a lot of
-
code. You rewrite a lot of code. And you
-
forget about fucking patterns for awhile.
You forget about
-
fucking TDD for awhile. And you focus on just
-
what's in front of you. The piece of code.
-
How can I write it simpler?
-
Write software well. Thank you very much.