
Ask HN: How to make fewer mistakes? - bmomb
I&#x27;m a developer for almost three years, i (like) to think that i&#x27;m good, i have deep knowledge of my stack and i can design and implement almost any feature that the seniors at my team can implement, but i have i problem with the final quality of my code.<p>My code is clean and follow the guide-lines, but i feel that i make to much mistakes, there is always a corner case that i don&#x27;t think about or some test that is trivial to the QA team but i didn&#x27;t do, and my code end up being broke.<p>This &#x27;behavior&#x27; also happen with maths, i know the theorems and the content that i need to know to solve questions but i always miss calculate something and end up with the wrong result, one clear example of this was my last &quot;calculus 2&quot; exam, all the steps were right, but all the results were wrong;<p>TL, DR: I know my stack and the tools but i make silly mistakes that end up breaking my code; how can one get better at this?
======
0xfaded
When I was getting my pilot's license, multiple times I started up without
unchaining the tail. I joked about it with another instructor, and he
basically said that it had literally never happened to him and that I should
be doing a final walk around. I'd done even more embarrassing things, sitting
at the runway ready to go and the tower tells me my baggage door is open.

Since making that final walk around a habit, nothing. I started doing final
everythings, one last check of the radios, one last check of the instruments,
etc, etc. It's amazing how many times you pick up on something so obvious that
is wrong.

The key is to change your mindset before doing the final check. Acknowledge
you are done, go get a tea, and go through the motions.

Somethings I do related to code.

Use `git add -p` to go through changes one by one. Remove stuff that shouldn't
be there.

Do a self code review before submitting the code for others to review.

Obvious one, but always run tests.

For what it's worth, I find the same things with maths. I've been working on
SLAM systems, so lots of differential geometry and matrix calculus. I'll spend
a morning with my notebook trying to figure something out, go to lunch, then
come back and go over what I've done.

In university I was horrible at maths exams, because like you I knew
everything but made so many stupid mistakes. I think the problem was that
during an exam, I could never dial down my mindset from OMG I need to triple
check everything right now!

~~~
Haul4ss
I was hoping someone would mention being a pilot in this discussion.

If you learn to fly, you will learn to follow checklists. Many, many
checklists.

A good instructor will tell you that while you do need to follow the
checklists, it never hurts to do one last check. One final walk-around before
getting in the cockpit, one last check of radios/transponder, one final scan
across your engine instruments before takeoff, etc.

If you do these things enough times, you'll find the occasional instance where
you forgot something obvious, or accidentally skipped a checklist item.

To OP, as you miss each edge case or QA thing you should have found, you add
it to your checklist. Before you check in a new piece of functionality, run it
through your checklist. Also, do one last walk-around of the code. How will
the user interact with it, what are the API dependencies, etc.

You're not second-guessing yourself, but you always verify even your own work
before calling it done. Over time, you'll learn to follow both the best
practices, and your own intuition built from years of learning from your
mistakes.

~~~
lj3
I came here to say basically this. Checklists are unreasonably effective. And
if you can automate them with some form of metaprogramming, even better!

~~~
newbear
Example?

~~~
lj3
Here's a good one: A few years back, I had a quick stint as a wordpress PHP
magician. The php community has a tool called php code sniffer. The wordpress
community has a collection of "sniffs" (rules) to enforce coding
conventions[0]. One folder of rules is called "Security"[1]. Set up a git
precommit hook to run phpcs with whatever set of rules you like and it will
give you a list of things you need to fix before your code can be committed.
Automatically.

In the JS/webpack/react world, there's eslint. You can write custom rules to
automatically check for and enforce whatever you have on your checklist.

[0]: [https://github.com/WordPress-Coding-Standards/WordPress-
Codi...](https://github.com/WordPress-Coding-Standards/WordPress-Coding-
Standards)

[1]: [https://github.com/WordPress-Coding-Standards/WordPress-
Codi...](https://github.com/WordPress-Coding-Standards/WordPress-Coding-
Standards/tree/develop/WordPress/Sniffs/Security)

------
itamarst
Gary Klein wrote a great book about how to learn from experience, based on
research in naturalistic decision making, kinda stuff firefighters and NICU
nurses do, but also e.g. design engineers for many decisions
([https://www.amazon.com/Power-Intuition-Feelings-Better-
Decis...](https://www.amazon.com/Power-Intuition-Feelings-Better-
Decisions/dp/0385502893)).

His advice for learning from mistakes is basically to look for the cues or
patterns you missed that caused your mistake. That way you find the hints that
would've helped you catch it in time.

I've been doing this myself, and writing up results in a weekly email
([https://codewithoutrules.com/softwareclown/](https://codewithoutrules.com/softwareclown/))
and it really improves how much I learn from mistakes. As in, I go from "well
that was stupid of me" to "ohhhhh, I should've noticed _that_."

Example: early in career I submitted code with bad variable names (foo, bar)
to customer who requested I write a library. She pointed that out as bad
practice, I was super embarrassed over my bad code. My takeaway in one of
initial emails was obvious one of "write readable code."

But later I revisited using the cues/patterns approach, and realized deeper
mistake was not listening to what she wanted—in this case, source code. If
deliverable wasn't source code then variable names wouldn't have mattered and
it would've been fine.

~~~
hutzlibu
"write readable code."

I think it doesn't matter if you give the source code or not, but you should
allways "write readable code".

Sure there is a difference between throw away code and a library, but also for
youself it is a good habit to understand later, what you have been doing. And
so much more for other people ...

~~~
itamarst
So, on the one hand, yes definitely.

On the other hand, it's worth digging deeper.

A lot of programming advice is these rules of thumb, and they're mostly good,
but they're motivated by underlying principles (which you explain in this
particular case). So it's useful to not just have these rules of thumbs, but
also to dig deeper and look for underlying motivations.

------
psyc
I believe my #1 defense against mistakes is the faint unease in the back of my
mind that arises when I don't completely understand the problem. If I become
aware of this nagging doubt, and follow it, it leads to the part I don't
completely understand, where mistakes are likely. You can spend quite a long
time seemingly immersed in a problem space without really understanding all of
it. I think I may unconsciously flinch away from specific areas I understand
least, because it's more comfortable to re-analyze the parts I have a good
grasp on. I find once I understand a problem well enough that I have any
business checking in code, and there's none of that nagging unease, then it's
usually mostly correct.

~~~
bmomb
I have that "faint unease" too, i need to give it more importance.

In the beginning i learn to ignore it because the mentality of "moving fast
and break things", and really worked because my tasks were fairly simple and
it would have fewer critical points, but thinking now that is harmful when
doing more complex things, i should slow down and trust in my 'feeling' more.

------
dundercoder
This may not be what you want to hear.

Making mistakes properly is progress. Make the exact same mistake multiple
times? You might need to write them down as you find them.

At one startup we had a motto: Measure once, cut twice. Being fix the bug,
then write code to mitigate that risk in the future. Fix it twice.

Now in critical systems like traffic lights and the like, mistakes kill
people, so you test the everloving crap out of everything, then another person
does, and another.

If your code doesn’t kill people, ease up on yourself a bit.

~~~
bmomb
Thank you for your comment, sometimes im bit to hard on myself;

I can learn from my mistakes, but some of them are really trivial, i can find
better examples in math, like:

In a calculus question, I need to find the volume inside some functions, this
type of question is not new, i know how to solve, but somewhere deep in the
calculation i change 'integral of sin' to be `cos` instead of `-cos` making
the everything more hard to solve and obviously getting the wrong answer.

This kind of thing is currently my biggest problem and i cant find a real way
to improve.

~~~
candiodari
This is the sort of thing that reviewing other people's performance can really
help with. Offer to teach classes, grade homework, or whatever.

Second thing that helps me pretty well is doublechecking through another path.
You know, figure something like this out, check if the angles of the triangle
still add to 180, check if substracting half the equation from the previous
step still yields the same, that sort of thing. For the problem you said, find
an "easy" definite integral that is easy to calculate (e.g. a sine is 180
degrees of the unit circle, so integral(0,1,x->sinx) is p/4).

So take a "trivial application" of the mathematical expression (like
calculating the area of the unit circle), and execute it on every step,
calculating what should be the area of the unit circle. As long as you replace
expressions with equivalent expressions the outcome should stay the same.

And for coding, unit tests, but more than that, running the code, using a
debugger or so.

------
in9
I have the exact same problem as you. The reason why I behave like that is
always due to some sort of anxiety in finishing the task at hand, together
with a flawed protocol to design and review it.

So what seems to help me is:

\- slow down, more time equals more time to think

\- write specifications as neatly as possible and review it with the requester
(even if it is only your self, review it many times). The more bullet points
(checks, and tasks) the better. (Come to think of it, the number of checkable
bullet points in an specification may be a good proxy for how much you are
thinking on corner cases and etc)

\- write extensible tests, read some nice TDD books (I haven't done that
myself, but having some canon way of thinking about tests, together with
reviewing tests can help you)

\- incorporate the expectation that there will be mistakes onto yourself, onto
the client and into your planning

\- practice practice practice

~~~
bmomb
I'm gonna start writing more, i giving myself more time to code and review.

Do you have any recommendations on TDD books?

~~~
suls
Hands down the best book. Plus the authors are really nice guys!
[http://www.growing-object-oriented-software.com](http://www.growing-object-
oriented-software.com)

~~~
kerberos84
I challenge your best book with the book of Kent Beck (founder of TDD)
[https://www.amazon.co.uk/Test-Driven-Development-Addison-
Wes...](https://www.amazon.co.uk/Test-Driven-Development-Addison-Wesley-
Signature/dp/0321146530)

~~~
suls
I was hoping someone would mention it! While it is a good book as well (and
Kent Beck has many of them!) I tend to describe his book as 1st generation
TDD. It certainly was a great breakthrough in 2002 but it misses some very
good thoughts that only came later (and to give credit: probably only thanks
to his book). So, GOOS for me is the 2nd generation of TDD. Especially part II
is invaluable to give as a reading and thinking exercise for my new devs.

------
sclangdon
In addition to what everyone else has said about just having more experience,
my suggestion is slow down and think... and to use assert a lot!

I've noticed that some developers rely way too much on tools to do their job
and they just don't spend a lot of time _thinking_. Think about the big
picture as well as the details. Think about how your code interacts with its
surroundings. Think about what you know to be true at any given line (and
write an assertion), and whether or not that thing may ever change. Think
about what every line means in isolation, and what it means to the surrounding
code. Think about the names you give things.

Maybe it's because of my age, but when I started there were barely any tools
to help. Even syntax highlighting wasn't readily available. Debuggers were
pretty crap, or didn't exist at all. The best thing we could do to prevent
bugs was to really question every bit of code. "What does this line do if x is
not what we think it is?", "Can x ever not be what we think it is?", etc

I feel like a lot of developers today don't think enough about what they're
doing, and care too much about their stack and their tools. Instead of moving
fast and breaking things, perhaps instead try moving carefully, and try not to
break things.

"The most effective debugging tool is still careful thought, coupled with
judiciously placed print statements" \- Brian Kernighan (replace print with
assert for my interpretation!)

~~~
brent_noorda
Second on that use of assert. "Be assertive!" I always say.

Most language offer a way to run in DEBUG mode, or something like it, use
that, along with assert (which only runs in DEBUG mode) to make sure all your
assumptions are correct. You're positive a value can never be NULL? assert
that! You're absolutely positive an integer addition will not overflow? assert
that! You're absolutely sure that your super-fast table returns the same
results as the complete algorithm? Run them both in debug mode and assert
that!

------
henrik_w
Not sure if this is exactly what you have in mind, but I have had good success
with my method of "learning from my bugs". Whenever I encounter a difficult
bug, I write a short entry in my bugs file. I detail what happened, what I
overlooked, where I should have found the bug (coding, testing). I also write
down lessons learned from it, and I try to regularly review the lessons.

More info here: [https://henrikwarne.com/2016/04/28/learning-from-your-
bugs/](https://henrikwarne.com/2016/04/28/learning-from-your-bugs/)

and here: [https://henrikwarne.com/2016/06/16/18-lessons-
from-13-years-...](https://henrikwarne.com/2016/06/16/18-lessons-
from-13-years-of-tricky-bugs/)

------
noxToken
I'm not quite sure this would apply to you, but maybe it will help someone
else: Slow down! You'll likely add more value by being 10% slower with more
correctness than 10% faster with more mistakes.

If you go by average time spent on a given task, I'm one of the slowest
developers in my shop. I'm pretty sure I'm in the bottom 25% for speed. What I
lack in speed I make up for in correctness and readability. Rarely is anything
bounced back to me for a bug, defect, or missing edge case. If I start getting
sloppy, I have no leverage, because now I'm one of the slowest developers who
make just as many (or more) mistakes than everyone else.

Start by fully understanding the problem. If you ever have any doubts about
anything, stop and ask. As you're breaking down the problem, create a set of
abstract notes. You could write it in paragraph form, a set of steps with
checkboxes, sticky notes[0] - whatever helps you get the problem from plain
business requirements to something a bit more concrete and actionable.

Then start writing code. Try to stick finishing in the order of your notes. It
doesn't have to be pretty, but make sure it works according to spec.
Constantly execute your code to test, because it's possible to add a
conditional that renders one of your passing scenarios as a failure. If you
can get a specific lists of tests that will be ran, use that as your
framework. Your number one priority would be ensuring that the entire list
passes deterministically.

After you've got working code, clean it up. Make sure your variables and
functions have good names. getValue() is a very generic name, while
getTotalCost() indicates much more without looking at another line of code.
Use a linter, formatter, and static analysis tools to search for common bugs.
If there are any glaring optimizations, make them.

[0]:
[https://news.ycombinator.com/item?id=16212374](https://news.ycombinator.com/item?id=16212374)

------
mattgreenrocks
One way that helps me is to read the code I wrote in several different
contexts.

Most of my code reading is in my editor. I'm in a certain mode of thought
there, mostly detail-oriented as I piece things together. When committing
code, I use git diff to inspect everything going into the commit, making sure
I agree with it. I do this in a terminal (I don't use a terminal-based editor)
with a different color scheme. Lastly, I'll re-read it again (especially if
I'm not 100% sure) on a web-based git server (Github/Gitlab) as a way to get
some closure on the day/commit.

This works well for me because:

* Most committed code is read at least twice

* Each reading context is different, at least visually

* Time passes between each reading, which gives your brain space to surface doubts

Doubt is your friend here. With enough experience, you'll know when you've
nailed something.

------
matt_s
Knowing edge/corner cases is experience based. You have to understand the
business domain to really understand how those types of things come up. As a
senior dev starting at a new company less than 2 years ago, I still don't
recognize edge cases as often as others that have been there longer.

I would suggest checking your work might help. Put it down and do something
else, then come back to it and pretend you are doing a code review of it.

When you state final quality of code, your work doesn't need to be perfect
before another human looks at it. That is why we work in teams. I'm not saying
be sloppy on purpose but if QA is coming up with trivial test additions, just
add them. People should have feedback on code reviews.

If the mistakes you are making are trivial, we've all made them and all still
make them. Syntax errors and mis-typed variables trip me up all the time.
Those are usually easy to find because the code doesn't work. If the mistakes
are more design related then get some software design reviews from a senior
dev before going deep into having code written.

------
Annatar
1\. run the code through a debugger as soon as you finish it;

2\. run the code and purposely try to break it with all the edge cases you can
think of;

3\. run the code as if you are an end user who knows absolutely nothing about
it;

4\. have your colleagues try to break your code before you commit it.

[https://wiki.illumos.org/display/illumos/On+the+Quality+Deat...](https://wiki.illumos.org/display/illumos/On+the+Quality+Death+Spiral)

[https://davepacheco.github.io/se411/release/fcs-quality-
all-...](https://davepacheco.github.io/se411/release/fcs-quality-all-the-
time.html)

~~~
AstralStorm
1.b. Not debugger, but a tool like valgrind or options like address and thread
sanitizer.

2\. And 3. Does not help when you miss the edge cases.

4\. It's called code review.

And my own: run the logic through an automated theorem prover, for example
Isabelle. They will instantly tell you if any invariant causes a contradiction
(mistake, corner case) or it cannot deduce behaviour given prerequisites.
(missing specification, probably corner case)

Since it makes you write and read the code twice and forces you to think of it
as necessary conditions and invariants, that alone might help.

------
stinos
Like others said: experience. Training for a correct mindset.

For me, for basically every line of code written, and also for bigger pieces
of code, I'll try to think of all possible corner cases which might prevent
the the pre- and postconditions from being established. And make as few
assumptions as possible.

It takes a while to develop that mindset, and it takes even longer to learn to
write code which doesn't have problems in the first place. And I wouldn't even
consider myself being really good at it.

Note that once you get a hold of it, you'll automatically start to write code
which adheres to most 'best practices' like DRY, proper naming, short
functions, you name it. These go hand in hand with fewer mistakes. In the
beginning this will cost you time. But that is not wasted, as it'll teach you
to do the right thing in the first place, and once you do that you'll have to
spend less time debugging and the code will be clearer in the first place so
less time lost reading and understanding it.

As a simple example take code from a person who does lack that mindset
(despite having programmed decades more than I have) which I reviewed just
today: if you just write bar[1].Foo() and don't have a strategy to either make
sure bar does have enough elements, or else a strategy to properly deal with
the error (as in, not just segfault, unless it has been established that is
the way to deal with it) which will occur if you try to access that element
anyway, the code is not good. So when I write even the simplest thing like
bar[1].Foo() I _automatically_ will wonder about that, ask myself 'can this
occur'? If it's supposed to never happen I'll likely insert an assert. If it
can be totally acceptable, wrap it in an if statement. If it's a user error,
complain. Etc. But never ever just assume it'll be ok. And to do that, realize
you must always reflect about _everything_ you can think of.

------
blanche_
1\. Have an IDE that points out the most obvious mistakes. 2\. Write test
(unit and functional), when you forget about corner cases writing code in TDD
style may help, because it makes you think about them before writing the
actual code. 3\. Write your mistakes down and why you made them. 4\. Have
githooks that prevent you from pushing code that doesn't pass test 5\. Don't
feel bad about your mistakes, that's how we learn.

You mind find this interesting:
[https://routley.io/tech/2017/11/23/logbook.html](https://routley.io/tech/2017/11/23/logbook.html)

------
muzani
IMO improve in the small things. In many cases, developers take on large
projects but have little opportunity to see the small things.

Pick a very small but important part to improve in. The most effective
training I did for myself was to practice pressing shift, semicolons, and
brackets accurately.

Wherever you have the most trouble with, narrow it down as small as possible.
Practice writing tests. Practice your algorithms, or working with a very
specific part of the stack. Things like Rx can be quite a lot to grasp.

It's not enough to know something once. You should be achieving fluency in all
the little parts.

------
tomerbd
I would like to sum up the comments + my thoughts:

1\. The more time you put on a task, more mistakes you find and fix.

2\. When finished with a task, come back to it after some time you will find
more mistakes with fresh thoughts.

3\. This means you have other good qualities like imagination and creativity,
which is a side effect of mistakes (internal mind random mistakes).

4\. Find mistakes ancestors - patterns - write them down in a short list, my
top 10 mistakes patterns. When finished with a task review that you didn't
repeat those 10 mistake patterns.

------
fredsted
I think it's something you learn the more experience you have. I think the
more mistakes, errors and bugs you see through your career, the better you get
at recognizing pitfalls when you write code.

Also, I'm a big fan of and practice "defensive" programming. There's lots of
articles written about that, but in short it kind of changes your mindset a
little and steers it towards more robust code. What can fail? How can I limit
and validate parameters most efficiently?

~~~
AstralStorm
There is defensive programming and there is bug hiding. Then there's also
wasting performance in release builds.

Mixing the three is bad.

------
snarf21
You already part of the way there just by asking. Wanting to get better and
knowing you can learn more is the first and hardest step. I'd also suggest
that you force yourself to become more introspective. When you make a silly
mistake that breaks your code, spend time thinking about _why_ it broke and
_why_ you didn't see it the first time. Find a mentor that is smarter and more
talented. Talk to them, look at their code, etc.

------
jjp
You say that "there is always a corner case that i don't think about or some
test that is trivial to the QA team but i didn't do, and my code end up being
broke". Is the corner case that you missed a technical issue or is it that the
QA team has a better understanding of the business problem that is being
solved and that hasn't been translated into a requirement/user story that you
would even know to code against.

~~~
AstralStorm
Also known as "lazy QA team who do not automate tests" problem. This is
because testers are paid to little and writing good automated tests is about
as hard as writing the tested code in the first place.

------
ThomPete
Make notes on paper of your mistakes. Keep them next to you.

------
thisisit
How about going easy on yourself and give it time? People, even the best of
coders, make silly mistakes. No one is above that.

------
markfer
Outside of code, I don't think there is anything with making mistakes. It's a
path towards progress, learning, and growth.

It is important that you figure out _why_ the mistake was made, and _how_ to
not recreate it in the future.

I tell my employees that creating 1000 individual mistakes is fine, so long as
none of them are repeats.

------
reacweb
Find another developer like and try to find mistakes in his code while he
tries to find mistakes in your code. Trying to find mistakes is not the same
mindset as trying to produce good code. Maybe you can go as far as writing the
unit test of each other. I have used this trick mainly to test GUI.

------
candu
If the senior developers around you are worthy of that title, they've reached
that point by making more mistakes than you have - and learning from them.
Here are some techniques I use to learn from mistakes:

Double-checking. To take an example: say you take the integral of `sin x` and
get `cos x` instead of `-cos x`. You can double-check this by differentiating
`cos x`, which will give you `-sin x`. Not only does this tell you you're
slightly off, it suggests exactly how to fix the problem. Many problems can be
double-checked: you get a result, then run the steps backwards to see if you
can get back to the starting point.

Incremental testing. I've recently been learning basic robotics / electronics
as part of a side job. One thing I found enormously helpful was to build up
progressively larger circuits on a breadboard - I'd even test the breadboard
itself (e.g. do the two halves of each row connect? Well, there's an easy way
to find out...) to make sure I had the correct mental model of how my
components were working.

Isolation. When confronted with a problem, try to find the minimal example
that reproduces the problem. I do this a lot when building out interfaces /
applications, where I need to add some non-trivial piece into a larger
application. I'll build a test page that contains just that piece, get it
working, then figure out how to integrate that working example with the
application as a whole. As a side benefit, I've broken my seemingly hard
problem down into two smaller, easier problems.

Informed questioning. You will inevitably hit something beyond your level of
expertise. Half of experience is learning when to identify that this has
happened, and knowing how to coherently explain your mental model of the
problem. Your mental model doesn't have to be right, but it should exist, and
you should know how to describe it to someone who can pick it apart and
improve it. Part of this is a sort of "egolessness" mindset: having the
humility to admit you don't understand everything, and to seek expert help
once you've tried what you can. (We're all bad at this last step, myself
included; developing this mindset is itself a learning process.)

Finally, and IMHO most importantly: failure normalization. Failure is normal
when learning a new tool, framework, language, skillset, etc. In this
situation, one of the first things I do is to explore what failure looks like.
I'll deliberately introduce syntax / logic errors: what sorts of errors does
the compiler / toolchain spit out? How can I use the debugger to step into the
problem, and what does that process look like? Do my tools give me any kind of
visual / tactile / etc. feedback on my error? (If not: where can I find better
tools?)

------
PhilipA
If you aren't embarrassed by the code you wrote 6 months ago, you haven't
progressed enough.

~~~
tw1010
Does that actually happen for really senior developers though?

~~~
Strom
I have 18 years of programming experience and it's definitely still true for
me. [1] Unless I get some brain degenerative disease, I fully expect to keep
improving at least until I'm 80 years old.

I've also seen this echoed by even more senior developers, e.g. this tweet by
John Carmack: _It is scary to look in some old code that hasn’t been touched
in years, and see a completely non-thread-safe static global variable used_.
[2]

\--

[1] My code quality is improving all the time. However I'm more accustomed to
my emotions and fully expect progress, so I'm not exactly embarrassed.

[2]
[https://twitter.com/id_aa_carmack/status/339406631613890560](https://twitter.com/id_aa_carmack/status/339406631613890560)

------
comstock
Confirm results through orthogonal means where possible.

If it comes to it write two solutions (possibly one optimized, one not) that
solve the same problem in different ways, and confirm the results against each
other.

Don’t count on just picking good edge cases.

------
Protostome
Consider adopting TDD (Test driven development). Be your own QA.

After finishing writing a functional piece of code, spend half an hour or so
(maybe more?) trying to break it.

------
kleer001
Take it existential, imagine that there's more at stake than just this task,
project, or your job. I'm not sure exactly what, be creative.

------
segmondy
Read these books, "Talent is overrated" & "The power of habits" & "Checklist
manifesto"

------
bookofjoe
When typing, go more slowly.

------
chvid
No omelette without breaking a few eggs ...

------
cnkk
make more mistakes, so you can learn from them.

------
Tomte
Checklists.

------
kldfjgh
How to make <i>fewer</i> mistakes.

~~~
corobo
> How to make <i>fewer</i> mistakes.

How to make _fewer_ mistakes.

