Ask HN: What does deliberate practice look like for computer programming? - tim_sw
======
taf2
I think you can divide programming up into a few areas.

1\. Mechanics, how well can you navigate and type using the tools you have
available. To practice this an easy thing to do is formatting your code
without any automatic formatting. In vim for example, this helps you learn the
commands.

2\. Reasoning/problem solving. This one is harder to practice and really
requires experience. Always have a project and spend time trying different
solutions. A nice characteristic of software is you can usually just undo if
something was wrong, so don't be afraid to experiment.

3\. Research- it's safe to assume someone else already solved a problem. Use
google to find their solution and read how they solved the problem. Never be
afraid to open up someone else's code.

------
andreasgonewild
It looks like, and is often accused of reinventing wheels. Forgetting that
it's not about the wheels but what the designers learned from going through
the motions. Writing code that you've never written before on a daily basis is
a good start. The key is to keep raising the bar, keep questioning tools,
frameworks and best practices; to never get stuck on auto-pilot. Solve
problems you care deeply about; or if that isn't possible yet; practice on the
road-blocks, divide and conquer. At least that's what it's like for me.

------
jerf
Doing things you've not done before that stretch you, then generally moving on
after you've done the first 10% that teaches you 90% of what there is to know.
(Numbers may not be precise.)

An incomplete lost: 3D graphics programming, write a compiler or interpreter,
write an emulator (Gameboy is popular), write a web server starting from a
socket, learn a new language paradigm, grab a raspberry pi and do something
with gpio, find a friendly open source project and close some bugs, and so on.

I'm an advocate of the "T shape", where you are deep in one or two things ("pi
shaped") but have dabbled in lots of things.

I would not that while katas as others suggest are not bad, they are usually
count for just one skill. You may learn a lot of clever tricks and some useful
math, but what you get out of them will plateau before you get to the end of
the katas set.

------
subwayclub
Programming more skillfully is primarily about making decisions on which
feedback loops you pay attention to, and not getting stuck on ideas about
feedback that seem momentarily fashionable or convenient, but lead to bad
outcomes later.

Write prototyping code that solves an existing problem as nearly as you can
manage, and then figure out how to improve it on one or more metrics:

* smaller SLOC (automatic programming, data abstractions, etc)

* better portability, fewer dependencies, simpler build processes

* better throughput, latency, or resource usage(memory, storage, bandwidth, energy)

* eliminate one or more classes of errors(e.g. off by ones, null dereferences)

* better user interfaces, better documentation and accessibility

* more efficient development of the prototype

* better working environment (workflow, tools and knowledge of the tools, automations for convenience)

Oftentimes, you can make one change and improve several metrics. Other times
you sacrifice one to get others. There are bad tradeoffs like code golfing or
premature optimization. Having the prototype already in hand is crucial in all
cases since it gives you a spec to bump up against when you're at risk of
falling off track. If you're more daring this can take the form of an existing
shipping codebase.

------
neurocline
Deliberate practice in a nutshell - pick something that has a measurable
outcome, have a target that is just slightly harder than is possible for you
at the moment ("outside your comfort zone"), do it, then compare your measured
results against your target, and then iterate.

I am not entirely sure deliberate practice works for programming. I've been
following Anders Eriksson's work for 10+ years, and it seems most applicable
when applied to domains that have a history of training. Want to learn how to
sing really well? You can probably do it. Want to be the best basketball free-
thrower in the world? Probably.

It's the lack of a body of trainers and training that hurt, because deliberate
practice talks about having quantifiable goals and the ability to compare how
you did it versus how it's supposed to be done. E.g. have a trainer in golf
means the trainer can critique your strike.

If I ever figure out deliberate practice for programming, you can bet for damn
sure I'll write a book.

~~~
segmondy
Deliberate practice works for programming.

~~~
astoellis
EDIT: Just saw your other post, thanks for the clarifications!

Could you please provide some elaboration on your comment? As it stands, it
doesn't explain how that works or why you believe that, and I think others
would find that valuable.

------
whatismybrowser
This is more of a technique for learning than for practice... but one thing
that I make a habit of when learning a new programming framework is
deliberately typing out sample code that I've found in books or online instead
of just copying and pasting it.

It's the equivalent of writing out notes by hand from a school textbook
instead of just photocopying the pages... some how the process of actually re-
typing it out causes it to stick in my mind better. And then later, when
you're really "in the zone", you don't break your focus by needing to keep
referring back to the book, it's already embedded in your muscle memory and
you just keep plowing away.

~~~
laythea
Yep. This works even better for me when hand writing something as opposed to
typing. Obviously useless for programming though :)

~~~
Lordarminius
Not useless. I type out code from books but resort to pencil when the snippets
I find difficult; that way, I can annotate and manipulate the code more
intensely.

------
dmux
I posted a link to a paper [0] about "Deliberate Performance" the other day
that some may find useful. In that paper -- along with making the distinction
between practice and performance -- they describe deliberate performance as:

>the effort to increase domain expertise while engaged in routine work
activity.

They then go on to give four types of exercises to focus on: repetition,
timely feedback, task variety, and progressive difficulty.

[0] [http://peterfadde.com/Research/Deliberate_Performance-
PI-101...](http://peterfadde.com/Research/Deliberate_Performance-PI-1011.pdf)

------
segmondy
Code jam & katas are fine. But they are not deliberate practice. They are just
exercises.

Deliberate practice is about working on your weak area till you're no longer
weak in that area.

You MUST perform a retrospective on all your projects. Ask yourself what you
struggle with often, what are your pain points? Identify them, then work on
them. The mistake I often see is that most developers create more problems for
themselves by attacking multiple problems at once. If you have XYZ problem,
and you decide to use a new language, a new framework, a new cloud
service/API, a new DB and a new design style you have never used before. You
will never be sure your pain point.

What you must do in this world of too many choices is LEARN TO CONSTRAIN. Pick
a language, DB, framework, etc that you know. Nothing should be new to you but
the problem. Yes, it's true that your existing tools might not have everything
you need. LEARN TO BE RESOURCEFUL. With that said, attack the problem, if you
have any issues, it will be obvious and apparent.

Let's say you have a great project you understand through and through and you
wish to learn a new DB. Keep all things constant, rewrite your old project and
the only thing that should be new is the DB. Repeat till you master the DB.

You must limit your problem to ONE and ONLY ONE at a time. This allows you to
measure and correct faster if on the wrong course.

------
indescions_2017
Attempt one Google Code Jam problem per day. Allocate one hour of intense
focus to get as far as you can. Solutions and winning code examples are also
there if you get stuck!

[https://code.google.com/codejam/](https://code.google.com/codejam/)

------
siegecraft
You could try TDD katas (see [http://osherove.com/tdd-
kata-1/](http://osherove.com/tdd-kata-1/) for a starting point). For me, the
value in this practice is becoming hyper-proficient with your chosen
development environment, not neccesarily learning TDD well. TDD is just a good
problem domain that enforces the rest. I think of it in terms of "mechanics"
practice. How quickly can you add a new file to your project? How quickly can
you integrate it into your workflow? Do you have a tightly focused
write/run/debug loop? Are you proficient with keyboard shortcuts and templates
or whatever else will accelerate your speed. It's about being able to keep up
with your mind when you get into flow and are ready to crank out code.

~~~
chi17
I think katas are great. So are all of the various tests you can take, as long
as they provide accurate answers and information, because not all do.

However, I don't spend time on those. I'm not saying that you shouldn't, but I
don't want to do it just like I don't want to go to a karate class. I have
nothing against karate, but I don't want to hit and kick people. Similarly, I
don't want to code the answer to some problem that someone else came up with,
just because it's a kata or test.

I've been a programmer for more years than a lot of the people on HN have been
alive and a professional developer for close to 20 years. That doesn't make my
opinion right. In fact, I think the majority of you are probably better
developers than I am.

But, if you don't like katas and don't like tests- don't feel bad about
yourself. You might be like me. I just like to find my own problems and
attempt to solve them. And that's ok. There might not always be a place for me
as a developer, but there will always be a place for developers that think
like that.

As long as you don't hurt anyone, just be yourself.

------
jwilliams
I use a painting/art metaphor for my practice. Usually when i want to develop
a new major function or approach - or adopt a new technology - I do a
"sketch".

The sketch is a standalone project that embodies what I want to understand. It
could be React with a basic router and a test framework. I'll iterate on that.
Sometimes several times. Then I integrate into the projects I'm working on.

Usually this is verifiable in some form. Being reliably testable is one. But
others could be micro-benchmark performance. Occasionally the aim is just to
re-write in a different language.

In the future, if I wanted to make a structural change (e.g. a different
router) - I'll go back to the sketch and make the change. Sometimes I also do
a sketch from scratch. However, I find working on the original sketch informs
changing the production code a lot better.

In "deliberate practice" terms that's a very macro-level approach, but it's a
balance that's worked for me.

------
stephengillie
Code is both math and language.

\- Deliberate literature practice involves as much (or more) reading as it
does writing. Tangentially, code review is an important way to both learn how
other people express ideas in other ways, and to learn new features and tricks
to express yourself in a given language.

\- Deliberate practice in mathematics begins with rote memorization, and later
with repeated application of algorithms. So practice could first involve
typing common algorithms, including brackets and other grammar, until they
(e.g. a FOR loop) can be typed from memory. Or possibly automating this step,
and practicing using the automation. Later practice could involve repeated
application of algorithms - possibly algorithms of your own making.

------
reading-at-work
Not sure if linking to reddit is frowned upon here, but there's a great
subreddit called r/dailyprogrammer which has fun coding challenges ranging
from beginner to difficult. I've found they are great for practice because
they have defined "success" states, they really make you think, and you can
compare solutions with others in the comments. And you can use any language
you want.

------
kleer001
Working through a new programming book?

Answering questions on Stack Exchange?

Watching marginally related recorded talks at conventions?

Focusing on the thing for an extended period of time while exploring new
territory?

The muscles you're wanted to exercise are pattern recognition and lateral
thinking, all in the problem solving family.

So, find a problem, them solve it.

------
OtterCoder
Excellent answers already. It also involves some time problem solving on the
craft at large. Take some time reading the words of people who have innovated
in the field and argued with their peers. See if you can work out where the
champions of OOP pushed our understanding and where they failed. See if you
can understand the functional programmers have created beauty out of chaos,
and where they've drunk a little too much Kool-Ade. Once you've understood,
write a few example programs in those styles and languages.

In understanding the radical designs and patterns that great coders have used
and argued about, you'll see you own code style change, even unconsciously.

------
gdubs
Get a copy of SICP and do all the exercises (and or follow along with the MIT
course videos on YouTube)

------
auganov
I have this tendency to get stuck in an incrementalist mode of coding where
I'll unnecessarily "test" little changes before it really makes sense. Forcing
myself to write out as much code as possible before running it, is a form of
deliberate practice for me.

------
throwaway2016a
Hacker Rank practice problems

------
lhuser123
Excellent question. Looking forward to read all the answers.

~~~
Lordarminius
I assume you probably made the comment to bookmark the article? There is a
'favorite' option that does that for you.

------
williamle8300
Believe yourself to be competent. Never believe yourself to be wise.

------
zaptheimpaler
Deliberate practice for X literally means do thing X.. i think that is simple
- the best way to get better at X is do X. So it really depends on what you
want to get better at.

Practice for algorithms could mean doing a lot of leetcode/interview style
algo problems.

Practice for working with large codebases means practicing
reading/understanding code quickly. So maybe picking a large scary open source
project and trying to make a contribution.

Reinventing wheels like andreasgonewild is the most useful and fun kind of
practice IMO. Pick a cool technology and make it yourself from scratch. Maybe
in a new area you know nothing about. A distributed KV store? A stack-based
programming language? A code formatter?

If you develop something big like that, you will surely exercise all the
muscles it takes to develop something. Reading too many tutorials or watching
too many videos is narrowly exercising the "learning" muscle. Solving
algorithmic puzzles is narrowly exercising the "CS fundamentals" muscle. But
the best workout to prepare to chop wood is to chop wood.

~~~
qq66
Deliberate practice is VERY different from "doing the thing." For example,
there are plenty of people who take thousands of photographs and only get
marginally better with each photo taken, because they simply take the
photograph and move on. Deliberate practice is taking the photo, seeing what
you like about the photo and what you don't, figuring out what you need to
change to make it come out that way, taking the photo again, and repeating the
process. It multiplies the speed by which you get better by thousands.

~~~
segmondy
Well said, I recommend folks read a book called "Art and Fear" & "Talent is
Overrated" to understand more about deliberate practice.

