Hacker News new | past | comments | ask | show | jobs | submit login
Ask HN: How to make fewer mistakes?
67 points by bmomb on Jan 24, 2018 | hide | past | favorite | 71 comments
I'm a developer for almost three years, i (like) to think that i'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.

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'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.

This 'behavior' 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 "calculus 2" exam, all the steps were right, but all the results were wrong;

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?

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!

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.

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


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...

[1]: https://github.com/WordPress-Coding-Standards/WordPress-Codi...

I am notoriously absentminded. I would constantly forget my lunch, leave the lights on, whatever. Since writing down checklists for my morning and evening routines, I don’t miss anything. The fact is that we’re human beings. As the book “Getting Things Done” says, your mind is for having ideas, not for holding them.

Reminds me of the book - "The Checklist Manifesto" by Atul Gawande

That's a helpful post. We do a similar thing in scuba diving: run through a checklist and then do "one final check" to make sure there's nothing obviously out of place.

Changing your mindset is another good piece of advice. When you're done coding, stop thinking like a programmer and think like a user - a bored, fed-up, malicious user who's going to have a go at breaking your software. He's not going to do the things you expect him to, he's going to try to enter ridiculous data, in the wrong order, press stuff that he shouldn't, etc. Be curious. "I wonder what happens if I do this..."

Offer to buy a beer for every bug your colleague finds in your code. Don't want to pay out? Make it hard for him to find any, and any that he does find will be well worth the cost.

I've been coding for nearly 40 years and still manage to write some crap on occasion!

I haven't often got the time for this, but one thing I find helps immensely when I do is to prepare a rough draft of my changes, and then go back and retype the entire function. (This will also encourage you to write short functions!) The act of retyping is a lot like the final walkaround: it forces you to see everything another time before sending it on its way.

The final walk around habit is great. It's even better if routine checks like these are part of a checklist you follow. When performing habitual actions it's possible to get a minor interruption/daydream and accidentally skip some check. Having an actual list of bullet points to go through helps against this.

My advice would echo yours. Only thing to point out is: time. You can do all these things if you start early and don't rush.

As you mention, mindset and habits are key. My mindset for tasks theses days is "focus, and dont be lazy". That allows me to not half ass the checks/checklist.

I will implement the "final walk around" in my dev/thought process, this is a really valuable advice, thank you.

PS. `git add -p` is amazing, thank you for this too.

I think additionally it helps to turn off sources of distraction. Cell phone I am looking at you.

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...).

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/) 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.

"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 ...

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.

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.

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.

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.

Agreed. We learn by making mistakes. Also you have only 3 years experience. It takes more like 10 years to become a "good" developer in my opinion. And even they still make mistakes, they are just less obvious ones.

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.

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.

Look at your intermediate steps, and ask "Does this look like the right answer?" at each point.

Nobody's memory is perfect - so it becomes a question of "How can I tell if I'm going down the right route, and how can I test to spot the mistakes I know I'm going to make?"

Everyone makes mistakes, the trick is catching them before you release to QA. In your math example, you should have some sort of test harness that tests your method against known inputs and outputs. It can be as simple as a throwaway console app.

In critical systems like traffic light and elevators the key is to have a simple system so you don't need to test the crap out of it. Using something like a finite state machine.

Part of making fewer mistakes is going for simplicity over complexity.

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

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

Do you have any recommendations on TDD books?

Hands down the best book. Plus the authors are really nice guys! http://www.growing-object-oriented-software.com

I challenge your best book with the book of Kent Beck (founder of TDD) https://www.amazon.co.uk/Test-Driven-Development-Addison-Wes...

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.

+1 for this recommendation, even if you don't buy into TDD after reading it, it also covers a lot of great OOP principles as well.

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!)

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!

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/

and here: https://henrikwarne.com/2016/06/16/18-lessons-from-13-years-...

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

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.

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.

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.



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.

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.

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

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.

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.

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?

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

Mixing the three is bad.

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.

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.

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.

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

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

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.

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.

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?)

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

Does that actually happen for really senior developers though?

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

Yes. I've been doing this for 10 years formally now, and absolutely yes. There is always something to learn and always ways to make things better, which combines nicely with the odds of being perfect the first time are low.

Not sure what you mean by "really senior", but I've been professionally programming for the last 8 years and it still happens to me. The embarrassment has lessened and it's less frequent, but it does happen.

Unless you are rewriting the same code over and over you are always trying new things and expanding your knowledge. And that means learning new things, and making mistakes doing so.

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.

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.

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.

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

When typing, go more slowly.

No omelette without breaking a few eggs ...

make more mistakes, so you can learn from them.


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

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

How to make fewer mistakes.

Yes, but how did you do that?

Text surrounded by asterisks is italicized, if the character after the first asterisk isn't whitespace.

Text after a blank line that is indented by two or more spaces is reproduced verbatim. (This is intended for code.)



  code block

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact