Deliberate Practice

We discuss deliberate practice and how it can help you hone your craft, and make you even better at using Opaque Types.
December 5, 2022
  • Practice makes permanent
  • Flow book by Mihaly Csikszentmihalyi

Key Principles of Deliberate Practice


Hello Jeroen.
Hello Dillon.
Do you know this phrase?
Practice makes...
Practice makes permanent.
Perfect practice makes perfect.
We should have practiced that one, huh?
Do you want to start over?
Or can we live with our faults, Dillon?
Faults are part of the process, Jeroen.
That's part of practicing.
So what are we talking about today?
Today we're going to talk about deliberate practice.
Deliberate practice?
Now I'm very confused.
Like, does it make things permanent?
Does it make things perfect?
Does it make anything, Dillon?
Does it make anything?
Well, yeah.
What is practice?
Like what does that word mean?
What is deliberate?
Are there...
Both of these concepts are very near and dear to my heart.
And maybe I should preface this with, I don't know that we've talked about this on the podcast
before, but before computer science, I was studying music and piano performance.
You have mentioned it, yes.
So that informed a lot of how I approach coding.
And deliberate practice is like really studying classical performance is like a very good
way to learn about deliberate practice.
Because that's kind of all you do.
I thought you were going to say something like, well, the piano and programming is the
Like you play on the keyboard.
That's also true.
That's also true.
Keyboards are a very important part of my life.
Yeah, absolutely.
Not the same one though.
Have you ever played piano on a Zerti keyboard?
You know, I may have actually tried that.
I'm not sure I'd recommend it though.
All right.
Dillon, what is deliberate practice?
Or do you want to start with practice?
I don't know how you want to introduce this.
So, well, let's think about the word practice for a second.
Because in a way, there are two senses of the word practice.
One sense is we think about, I'm going to sit down and practice my tennis serve.
I'm going to practice my scales.
I'm going to practice this song on the piano.
And then you might have a writing practice, or you might be a practicing coder.
You're a practitioner of programming.
So the difference is when you're a practitioner, you're doing something.
And when you practice, you're training.
And so in a sense, I think that really gets at actually this concept that we were kind
of joking about earlier of practice makes permanent.
I think that's kind of what practicing is.
It's like making things permanent.
So in a certain sense, we're always practicing, meaning we're always enforcing habits.
We're always building habits.
Whether we're consciously trying to build habits or not, we always are.
So deliberate practice is when you are intentional about what habits you want to build.
And in addition to that, there are a couple of principles that help you better ingrain
For example, isolating things down into smaller pieces so you can really focus on them.
You know, I think we talked about this in our learning episode, which I definitely recommend
people go back and listen to if they haven't, about feedback loops and how feedback and
learning are kind of the same thing.
And so a lot of deliberate practice is thinking about, well, if you want to build a habit,
you should probably think about isolating down where you want to build that habit because
you're going to be more effective at building that habit.
Would you be in a way okay with renaming deliberate practice to deliberate habits?
I mean, I love that idea.
To me, habits and practice are the same concept essentially.
Yeah, absolutely.
Deliberate habits is the intended results and deliberate practice is the means in a
But okay, I didn't see it that way, but yeah, it makes a lot of sense.
So, you know, it's really interesting because with music, with classical performance, I'd
say like 90% of what you're doing is deliberate practice.
You know, you also have, of course, performances, rehearsals, things that are maybe more working
to achieve some result.
You need to decide on an interpretation with a group of musicians or you're in a concert
performing, but 90% of the time you're taking those goals that you have and then sitting
down and workshopping them and trying to isolate things to build those habits into your performing.
As programmers, as working programmers, it's not 90% of being a programmer.
No, no, 90% is reading the code and fixing bugs.
And it shouldn't be 90%, but I believe that it's a good idea for it to be more than 0%.
And I believe that for many programmers, it is 0%.
And I can say that like, it's really shaped me as a programmer.
By the way, you shouldn't feel bad if it's 0% because, I mean, Dillon, you wouldn't want
to make me feel bad, right?
No, I mean, if it's 0%, let's put it this way, you have an opportunity to do something
that might make you a better programmer.
If you're doing 0% deliberate practice and you're already achieving the things you want
to with your coding and your career, imagine if it was 1%, 2% of your time, what might
you be able to accomplish?
How might you be able to grow from that?
So I think it's an opportunity.
Well, the question is also like, do you get anything out of 1% of deliberate practice?
But maybe we should explain the difference between practice and deliberate practice and
get into that.
Well, so, okay.
So what I like to think about for deliberate practice, with practice, we're always practicing.
We're always doing, enforcing some habits, reinforcing, whether we're reinforcing habits
or trying to shape habits in a different way.
Well, yeah, but also like if you're just training for a marathon, right, or just running, and
if you just go running every week without much thought, you're practicing, you're training,
but you are not deliberately practicing, right?
I would put building muscle and endurance physically into a different category.
Because you move those muscles and something is happening that's making you stronger.
And the goal is not necessarily, I mean, partially, I'm sure for very high level runners, they
are thinking about their form.
For most of us, if we're going out on a jog, or even training for a marathon, we're probably
not thinking too much about form.
We're probably focused more on just pushing ourselves to do the run.
I'm guessing you could also train specific muscles more, like if you run faster, then
you're going to train some muscles more than others.
And if you run slower, then the opposite.
So there can be an intentionality and goal behind it in a more intentional way or a less
intentional way, for sure.
But at the end of the day, a large part of it is building endurance and muscle, building
up some physical capacity.
But yeah, I think we're more focused on intellectual habits and skills that are not physical.
So this is the example I like to use.
So let's say that you have been entered into a race.
You're going to be...
A physical race?
Do you drive, Jeroen?
You live in Paris, so you don't have much reason to drive.
No, I don't.
I know how to drive.
I've got my license, but I don't have a car and I rarely drive.
I will.
I'll take it.
I'll take this.
Maybe, maybe my example is catered to American audiences or California audiences.
That is quite possible.
Where you don't have the subway.
We use cars a lot in California.
Unfortunately, I wish we had better public transportation in Southern California, but
we don't.
But if you are enlisted in a race, you really don't want to make a fool of yourself in the
You want to place well, and you're given a few months to prepare for the race.
Let's say you're a daily commuter.
You're stuck in traffic for three hours a day.
So every day you're practicing driving for three hours, right?
And so you have to decide, like, how well prepared are you going to feel for that race
in three months with three hours a day stuck in traffic?
Well, not much, I would say.
But why?
Because you're, you're spending three hours in a car.
Yeah, but you're spending three hours in, um, stuck in traffic.
So you're, you're, you're actually training more to stay still in your car than to actually
Now, what if, what if you were doing a three hour commute on a clear highway?
How would, how prepared would you feel then?
A lot more, I think, because you would be able to drive the way you want.
And if you're sure that you won't get caught by the cops or something, then you can drive
as fast as you want and do as many dangerous tricks that you might want to try out.
What if you, what if you had access to the racetrack and drove around that for three
How would you feel then compared to driving on the freeway?
Well, that would feel even better because you would get to know the track.
You would get to know the things you, you would do what you would need to do during
the race.
So you, you would learn all the hooks and crannies of the race and you could notice,
Oh, well, some of them I'm having trouble with.
So you can focus on those.
And you would have to discover them during the race otherwise.
So that would definitely be helpful.
Would you be satisfied with only doing that for the three months leading up to the race?
Like if you really, really want to do well in this race, would that be the only thing
you would do or is there anything else you would add into your routine?
I would add in rest.
That's really quite nice.
Otherwise it sounds pretty good.
In the sense that if I can choose how to drive on that track, then yeah.
Like, as I said, like if I want to focus on some corners, then, then I can focus on those
But if I need to do the whole track over and over again, without thinking about that more,
without being able to select what I want to do, then there's a lot of things that will
be very repetitive in a non-interesting way.
I would say.
Here's what I would be thinking about if I were faced with this choice.
I would be thinking, okay, like this is great.
I have access to this track and I definitely want to take advantage of that.
That's going to be very useful, but I'm not a race car driver.
I'm a driver in casual traffic and I have a set of skills and habits that I use driving
that helps me navigate through that, but it's not really going to equip me that well to
high performance racing.
So I might need to build a new set of habits.
And if I just go for three months, three hours a day driving around this racetrack, I might
be reinforcing some of those habits and get stuck in them and I might sort of plateau.
And so I would be thinking, how do I avoid plateauing?
And so what I would be thinking about to try to avoid that would be, well, what are the
skills I should be learning?
How do, first of all, I would probably come up with like a set of goals and try to understand
like what should I get better at to be a race car driver?
So okay, maybe I should get good at going around turns because maybe the way a race
car driver goes around turns is different than how I go around turns on the highway
or hopefully, hopefully, right?
And probably any passengers in my car are probably going to feel extremely uncomfortable
if I'm going around turns like a race car driver.
I don't think the local police officers would appreciate that.
And I might get more attention than I want to from that.
Remind me never to get into your car.
So that's one thing, like what are the skills and identify those.
And so then I could kind of come up with a set of goals, a set of habits I'd like to
build and just understand what are those techniques I want to learn.
But then I would be thinking about how can I isolate those things because going around
turns, if I just go around a bunch of turns, maybe that's not the most efficient way to
build those habits in.
Maybe I need to isolate that more.
So then I'd be thinking about isolating because if I'm just going around a turn, that might
be for one thing, it's a very long feedback loop.
Maybe it's a long racetrack and I have long stretches where there's not a turn.
I'm mixing these things that I'm practicing.
So my intention, I go in and I say, today I want to work on these turns.
But now I have to wait all this time going through the straightaway section before I
can practice a turn.
And then there are all these other things going on and my brain can't just focus on
building that habit.
So what I really want is a highly repeatable turn, turn, turn.
How would you do that?
Probably find access to a big parking lot space and get some traffic cones and practice
turning around those.
Set up the little thing, try not to knock over any cones.
Maybe I can get somebody to come with a stopwatch and time how long it takes me to get around
turns and make sure I'm improving.
So I'm setting up a feedback loop and I'm trying to drill in that thing in isolation.
So isolation is a key principle of deliberate practice.
And we lack isolation when we are practicing our craft in the wild.
And therefore, we want to take it out of the wild into a lab, into isolation, so we can
isolate it.
Yeah, it makes me think of Trackmania, that video game where you play a race car in weird
environments or weird tracks.
And one of the things you can do is you can just, with the press of a key, restart from
Or from a, I guess you could change the map to train only this section that you're interested
And yeah, you could practice some part of the track and repeat and repeat and repeat
it over and over again until you're satisfied with it.
They can have a very quick feedback loop because they can try it out a lot of times as well.
And tools are actually an important part of deliberate practice, I think, because it helps
you hone those feedback loops.
Like if you're practicing music, a metronome is a great tool for that because if you're
practicing scales and you want to play scales evenly, you can get feedback.
Am I playing that scale evenly?
And the metronome can help you do that.
And there are a number of ways that you can use that to slowly increase the speed that
you're playing.
And so tools are a very important part of that.
And the same is true for programmers wanting to do deliberate practice.
So we'll enter that side of programming a little bit later because we haven't talked
much about programming, but this is still a program podcast.
It is.
It is.
It is not a race car driving podcast yet.
Maybe eventually we'll pivot.
I mean, my company sponsors Formula One.
So yeah.
And you can see CrowdStrike on some of the cars.
That's cool.
A lot of big tech companies do that apparently.
Maybe this is a more realistic scenario than I realized.
I think another thing to think about in this deliberate practice is, so there's a book
called Flow by Jigset Mihaly.
I've heard people pronounce it that way, but Jigset Mihaly, Jigset Mihaly, something like
It's a wonderful book.
It's called Flow.
Definitely recommend reading it.
But he has this concept that essentially there's a flow state, which often people talk about
losing track of time, getting into the flow of things, being in a Zen state where you're
extremely engaged with your work and really tuned into it and performing at a high level.
And he kind of talks about this flow state as, for one thing, he explores like, how do
you get into a flow state?
And for another thing, he has this idea that really flow states are when you're learning
and growing.
And so you should try to stay in that flow state as much as you can to be growing and
not plateauing.
I have a meeting in five minutes, so nope.
I mean, we are practitioners.
We need to accomplish tasks and there's a fine balance, right?
But this idea of flow state, certainly when you are doing deliberate practice, I think
it's really good to think about flow state.
And one of the key principles of flow state from this book is the appropriate level of
So I'm guessing if it's too easy, then you're going to start thinking about other things
because it doesn't require much focus.
And if it's too difficult for you, then you're just not going to succeed and you're not going
to learn much.
If you've never driven a car and somebody says, go around this racetrack, you're not
going to learn very much because it's not an appropriate level of challenge.
If you've never driven stick shift, that's probably more catered to American audiences
But yeah, and you're trying to learn how to drive stick shift, then it might not be an
appropriate level of challenge to just dive into stick shift around the racetrack, trying
to go at a fast speed and do the tight turns.
So isolation can help you balance out to get that appropriate level of challenge.
So that's one of the tools at our disposal.
So like, you know, if you're practicing piano, like one way to isolate things is to say,
play hands separately.
You know, that's like a common technique.
So you have like some complicated passage, play just the left hand, then play just the
right hand.
You have, you know, another way to isolate is instead of playing the entire piece, just
play these four measures or just play this one measure or just play this set of notes.
Or you can create small exercises that are a simplified version of the thing you're trying
to learn to make it easier for yourself.
You can play every other note of a passage.
There are all these, like musicians get very creative with coming up with ways of isolating
the thing you're trying to work on to make it an appropriate level of challenge.
So you can keep sort of cranking up the gears to get to more and more difficult challenges
so you can continue growing.
But you're always trying to like stay on that edge of growth where you're challenging yourself
the appropriate amount to keep growing.
And you can also use like slowing down or speeding up the tempo.
These are all different techniques to isolate and to simplify.
And we can do that with code too.
But if you're doing that in a production code base, that might be challenging.
That might not be the best place to do that.
And also you have a deadline coming up and you know, some users are asking when this
feature is going to be out.
And you know, it's a Friday and you want to get this wrapped up before the weekend or
whatever, right?
Like those are all reasonable things.
Like you're working.
And that's why it's so important to take the time to do deliberate practice because we're
not necessarily going to be able to hone these things.
Also just like driving stick shift for the first time while going 200 miles per hour
around a racetrack with tight turns is going to be too much for somebody who's learning
stick shift.
If you're trying to get good at, now we get into the coding part.
If you're trying to get good at test driven development, guess what?
Doing a very difficult problem that you're trying to solve at work in a code base that
doesn't have any unit testing.
And you're trying to figure out the right way to get test coverage around that might
not be the best place to learn how to do unit testing.
So if you're expecting to get good at unit testing by just trying it out in the wild
in the context of a complex code base, maybe with legacy code and all these things, that's
a really hard way to try to learn that.
And you're also going to have cases like, Oh yeah, this case, like we actually don't
want to do this or, Oh, this is actually quite difficult because there's this hidden requirements.
Yeah, exactly.
So how do we do isolation as programmers for our deliberate practice?
Just like, you know, classical musicians are very good at isolating in their practice routines.
How can we, how can we do that as programmers?
Number one, do something where you're not under production pressure, where you are not
working in a production code base and you are not working under deadline pressure and
where, and in fact, where your goal is not to ship a feature.
That is a very good tool for learning because then your entire goal is learning and you
can completely focus on that and you can create the best artificial conditions for that.
It's like a little lab for learning.
I'm guessing if you can do this learning outside of work, then you're sure not to have any
pressure, but not everyone has the time or, or as the environment to do that.
And you need to learn at work.
Like otherwise you have probably bad place you work, you're working at.
But I mean, if you're learning on your own, then you're sure not to have any pressure
like that.
I mean, it, I think it depends on the individual.
I've certainly done a lot of deliberate practice on my own time in my career.
I've also done a lot of deliberate practice.
I mean, I've done a lot of coaching teams doing deliberate practice being paid to do
You know, I've done more of that than I've done.
I've done more of trying to like get companies to make deliberate practice part of their
employees paid work time.
And I have feeling comfortable to like learn on company time myself as an employee, but
I'm kind of unique that way.
But you know, I, I strongly believe in, in the benefits of companies creating a culture
where people feel empowered to spend learning time on company hours because it benefits
the company.
It makes, it makes the team better at what they do and it, and it improves the code quality.
So it's like, there are very clear benefits to the company, but as you say, not, not everybody
is going to be in a company culture where they feel comfortable doing that.
So you know, if you, if you don't feel that you have the ability to help build that kind
of company culture, you might end up spending some of your own free time doing some deliberate
And if you're a student, then you're going to have to do it on your own time.
Because you don't have a company.
You might do it in the middle of a teacher's lecture, but that's not a good idea.
Stay focused on your, on your lesson.
All right.
And also if you're doing deliberate practice, try to avoid multitasking.
But yeah, so, so if you, if you do set aside the time in whatever context to do some deliberate
practice, you want to do some deliberate practice coding.
What does isolating things look like?
You want like, so first of all, I think an important piece is like starting with a goal.
So a key concept of deliberate practice is it's intentional.
There's a goal behind it.
It's not like it doesn't, doesn't particularly make sense to do like it's, it's not really
deliberate practice if there's not a clear intention.
So that's number one, start with a clear intention and you can get better over time aligning
that clear intention with a routine that is going to help you achieve that goal.
What kind of goal are we talking about?
Is it the goal of results or a goal of like a, I want to, like imagine we're trying to
type faster.
Can a goal be like, I want to be 20% faster or should it be, I should write 5,000 words
in this next hour?
Well, if I was trying to do deliberate practice for typing, which is, which I've done before
and it's, I think it's a good, good thing to do, even if you consider yourself to be
a proficient typist, but the types of things I've done are like, Hmm, am I pressing these
special characters in an efficient way?
Like is the finger I'm using the appropriate finger for that?
And like, is it curving over the other fingers in the right way?
And, and then I can just practice getting better at that and having a faster typing
speed that uses these characters.
And so I, so I would be less focused on, I want to be 20% faster.
I'd be more focused on like, what do I want to work on right now?
Maybe my goal is to be 20% faster overall, but that's like a more big picture strategic
But then when you sit down and you do deliberate practice, what are you going to do to get
20% faster?
Like getting 20% faster is a pretty broad goal.
And if you want like deliberate practice is all about like isolating.
So what are you going to isolate that is going to help you with that broad goal?
And so maybe there's an opportunity with the way you type special characters, maybe the
way that you're capitalizing using shift keys on either side could be improved.
Those are some things you can isolate that can help with that goal.
But then what is the goal for those training sessions?
Like should I be able to type those special keys 20% faster or should I do 5,000 of them?
Like what is the- I see.
I would say the goal, like if I was sitting down to do that, I would be like, my goal
right now is to, to improve the way I'm using the right, the correct shift key.
It really is more of an intention more than a, at the end it's not a goal that you can
So I think it could be, but I think probably like more of a narrow thing than like a broad
strategic thing.
You can keep those strategic thing.
I want to be a 24% faster typist in mind, but I would say if I were working on that,
that would be too broad to be helpful.
But saying I want to work on how I'm using the shift keys would be specific enough to
be helpful or sitting down and saying like, I want to figure out the correct finger to
use for this thing is definitely like maybe an achievable thing that in a sitting down
in a session, I could figure out that thing.
So, so like in the context of coding, for example, like maybe, so first of all, with
a code cadas are a very helpful tool for deliberate practice.
Like when I think of deliberate practice for, for coding, I think of code cadas.
It's not the only way to do deliberate practice.
There are different techniques that are all valuable, but code cadas are, are awesome.
I highly recommend giving, giving them a try.
So code cada is basically a repeatable exercise.
And the fact that it's repeatable is the point.
So a fizzbuzz, for example, you know, given the number one, return one, two, return two,
three return fizz.
If it's a multiple of three return fizz, if it's multiple of five return buzz, if it's
a multiple of three and five return fizzbuzz, otherwise return the number, just writing
a function that does that, right?
So that's one of the simplest code cadas.
And you don't do it once you don't solve the exercise once and then you're done.
You do it repeatedly.
But because it's this boring, easy exercise, you can apply a challenge to that and work
on that deliberately.
So you can say, I want to do fizzbuzz in elm and I want to work on my refactoring.
Like at what stage do I refactor?
I want to play around with that.
I want to.
So like when you're doing this deliberate practice, I think it's really important to
say, to do things that feel like you're going overboard and being too extreme.
Like really, do I need to refactor this much?
Well try it, try it and see how it goes.
And maybe you'll, maybe you'll try it and you'll say, yeah, that was too much, but you've
actually built a habit that makes you more proficient at that.
And now when you go into a production code base, you've built up those refactoring muscles
and you can actually use those.
They're more available to you.
You've built those habits and that skill and that way to just identify refactoring opportunities.
When do you commit during refactoring?
Doing your, so always try to be your best self when you're doing Kadas, even like if
it seems like you're going overboard, just do it.
And oftentimes I will say from my experience, oftentimes when I think I'm going overboard
with Kadas, it actually ends up shaping the way I look at it.
I'm like, I actually don't think that's overboard anymore.
I really liked that.
Like that really worked for me.
Like doing tiny commits when I just rename a function actually really works for me.
And now that's part of how I code and how I think about coding.
So yeah, crank it up to 11.
Yeah, exactly.
But think of it as a time to experiment because it's low stakes.
You're not shipping to production and that's an important part of it.
So how, how else can you, so how else can you practice?
You've got coding Kadas.
I know that when you're studying you can also do like write self quizzes.
Like you write the answer to a question, you can write a question and the answer on the
back and you practice learning that.
I don't think that applies to programming too much, but maybe you have some ideas.
It depends on your context.
I mean, I've certainly done deliberate practice to learn a particular web framework and just
say like, I want to build a to-do list application from scratch five times.
I've done that before and it's very helpful.
Like just being like five times in a row, build a to-do application.
You get really good at that and you kind of, you're like, okay, this is where these components
sit on the file system and this is how you wire them up.
And this is the thing that I kept running into that I messed up and you learn about
So those aren't code Kadas, but that's a deliberate practice that you're honing in on a goal and
isolating to get better at a specific thing.
I'm guessing you could over memorize the technique.
Oh, sorry.
I'm guessing you could over, I'm guessing you could over learn the exercise.
Like if you do writing a to-do app, you could have it all already in your mind and you just
write everything line by line, line by line without ever compiling or working.
But if you're not perfect at it, then you could notice, oh, well now it's not working.
Even after I've written all the code, I don't know where the problem is.
And then you could do some introspection, like how could I, how could I have done this
And I think it's something you mentioned, but introspection and critical thinking seems
very important.
Like how, why am I not fast at this?
Is it because I am having issues with remembering when I need to extract a function?
Is it because blah, blah, blah, should I do TDD more?
I don't know.
You need to have a critical thinking brain next to your working brain, I imagine.
I really liked that you brought up introspection.
I actually, I neglected to put that on my list of points to talk about, but in hindsight,
that is like a hundred percent a core part of it.
Like if you're, if you're not introspecting and thinking, what do I need to get better
at doing some deliberate practice and saying, hmm, what, what's not, what's not flowing
so well or working on production code and saying like, feels like, I don't know, the
way I'm refactoring this code feels like I could be better.
So yeah, absolutely.
You introspect, maybe even have a running list of things you want to get better at or
work on.
And cause yeah, you have to start with those intentions and how do you get those intentions
by being mindful, applying critical thinking, being introspective.
And as, as to you know, a particular exercise getting too rote where you're just spitting
out the same code, it depends on what your goal is.
That might be okay to a certain extent.
Like if your goal is to get, like when I was working on just building a to-do list five
times in a row, I wanted it to become kind of rote to just create components and, and
wire things up.
And it wasn't so much about solving the problem.
And actually sometimes code kata's, I like code kata's that allow me to focus less on
the problem I'm solving and more on how I'm solving it.
So I really like the tennis kata, just a simple scorekeeping app where you, you can just call
a function that says player one scored or player two scored, and it will print out the
current score of the game in, in tennis language.
And sometimes when you get to like prime factor kata's and things like that, it's test, it
feels like it's testing more like math or comfort with certain standard library functions
more than it's testing my ability to like refactor code and extract things nicely.
It feels more like an exercise rather than a drawing board or a practice board.
I'm not thinking about coding.
I'm thinking about like solving a specific problem, but I kind of want it to be like
a vessel for thinking about how I'm coding, not like, because it's okay for it to become
rote where it's like, you know, okay, I've done, I've done the gilded rose 50 times,
but I can still approach it with these steps.
I can still try gilded rose, which is a great exercise by the way.
It's more focused on legacy, getting legacy code under test and refactoring legacy code.
So I can try like different techniques for getting legacy code under test, do it with
a code coverage tool and use that to identify the parts that I get under test and then feed
test inputs into it and commit those tests and get it under code coverage and then start
refactoring or I can try it with fuzz testing doing that.
Or I can try it with a snapshot testing or I can try it with like a particular refactoring
technique once I've got it with tests.
I can try it with, I can try the Kata where I already have existing legacy code tests
and then I try using only editor refactorings to accomplish a particular task or, you know,
try it with Elm Review Simplify and then let Elm Review Simplify help you along and see
how, see how that feels.
And maybe you learn something that you bring over to your production process.
And so like, think of it as a test lab, like if, if you don't have for technology for like,
you know, CPUs or whatever tech stuff, if you don't have the labs and the academia exploring
cutting edge things, eventually the industry stuff is going to go stale and plateau.
You need those labs.
It's not like, maybe you're not investing 90% of the resources into the labs for your
new cutting edge processors, but if you're investing nothing in it, you're going to plateau.
So it's, it's the same with the way we write code.
Like you need to have a laboratory to explore new things and some of them will be successful
and some of them won't.
And that's part of it.
It's part of the learning.
And you want to create that low stakes environment where it's okay to fail and experiment and
try things that you might not like that.
That's part of it.
That's part of learning.
So you can find a lot of Kadas online, maybe not for Elm, but maybe less for Elm.
I'm guessing that what you can also do is if you've noticed you worked on a project
and there was a, an assignment that you worked on and that was more complex to solve than
you expected, like it's not necessarily very complex, but you struggled with it.
You could try to redo it again after the fact when you're in a non-stressful environment,
when it's already been pushed, or you just try to do it again without the stress of deadlines,
without the exploratory phase and figure out with critical thinking, like how can I do
this better?
How can, what habits can I learn to make this easier for myself the next time I encounter
this kind of situation?
So create your own Kada on the fly.
Yes, absolutely.
That said, Kadas are probably designed to be helpful for these kinds of issues, for
refactoring for TDD.
So it might be more appropriate, but if you already have a stake in a problem, then why
I completely agree.
Try your own experiment.
And these Kadas are pretty, pretty language agnostic.
So you can try, some of my favorites are Fizzbuzz, Tennis Kada, Gilded Rose, we've mentioned.
I really like the Roman numeral Kada to sort of produce, convert numbers to Roman numerals.
I really like that one a lot.
And that Kada is very good for practicing tiny steps.
I honed a lot of my skills and my ideas about tiny steps.
Well, I learned a lot of ideas from a lot of great thinkers, you know, like Kent Beck
and Llewellyn Falco influenced me a lot in tiny steps and Woody Zool, but then you have
to like apply those things to understand them for yourself.
And things like the Roman numeral Kada really helped me do that, for example.
There's also the side benefits that if you train Fizzbuzz a lot, then you're going to
rock that tech interview.
Yeah, totally.
I think I had to do it at some point for a technical interview.
Yeah, I did.
With good reason.
Like if you're really good at these Kadas, then you've acquired those skills.
Like you've earned those skills and like, you know, yeah, if you've practiced that specific
thing that's on the interview, okay.
But yeah, Kadas will make you better at interviews probably where there's live coding.
They definitely will.
Is there a Kada for inverting a binary tree or something like that?
I don't know.
I mean, you could do it.
Why not?
I mean, you could do it.
Like you said, you can create your own exercises.
So one thing that I want to emphasize with code Kadas is part of the idea with code Kadas
is that you can apply different techniques for things that you want to learn.
You can say, I want to try using this data structure, this refactoring technique.
I want to focus on incremental steps.
I want to do more tiny steps than I'm used to.
I want to practice committing after every small step.
You can do all these, you know, sometimes people call them constraint games.
There are even more like interesting ones like setting a timer and saying, okay, if
the tests are read after this amount of time, revert everything, you wipe everything out.
You reset hard.
Or I'm dash RF slash, that would be brutal as a, as a way of building up your muscle
and getting feedback for yourself for tiny steps.
Cause then you learn tiny steps.
So you know, all these things are the, sometimes these are called constraint games and super
valuable, but one of the ideas with Kadas is that test driven development is always
part of the practice.
And that's how I think of them.
I'm so I consider, I consider test driven development to be just a core tenant of Kadas.
How so like, like, does it have to be part of it or do you need the safety nets or, or
should you always train TDD for everything?
I mean, I think for example, using, using for me, TDD and tiny steps are really intertwined.
Like it's part of how I practice that.
And it's part of the muscle I want to build up.
It's just such, it's just such a core skill.
So of course some people might disagree with this, but that's how I think of it.
I think of test driven development as such a foundational skill and so linked to how
I think about refactoring tiny steps, getting, getting something read, right?
What is a like tiny steps doing the simplest thing that could possibly work?
Great thing to focus on when you're doing deliberate practice.
Well what is doing the simplest thing that could possibly work if you don't have a test
to tell you, okay, now here's the red that tells you the thing you need to get to work.
Like what is working?
The test tells you this is, this is working.
Now the green tells you that you've done the simplest thing that could possibly work.
That you've gotten it to work.
But let's say for instance, I want to train making opaque types.
I want to, sorry, I had to say, absolutely.
Let's say you want, you want to train extracting a data type into a new module and making an
You don't need test for that probably.
Or I mean not having tests probably doesn't block you from learning this skill.
So here I would say you probably don't need TDD or am I missing something?
So if I were sitting down to do an opaque type practice session, which I also think
is an excellent idea, I would definitely be starting with a test.
And part of the reason is because like opaque types and tests are deeply connected.
Like because opaque types are about the public interface.
So how do you test something with a hidden private interface?
What are the implications of that for testing?
What are the implications of that for tiny steps?
At what point do you extract it to an opaque type?
That's something you can practice.
You can practice, do I immediately create a module where I define that code and make
it opaque from the start?
Or do I do it incrementally in steps?
And to me it's like doing that process like without tests to support me through those
small steps.
Just first of all, I want to take the opportunity to build the testing habit.
I want to have tests to support me refactoring and I want to practice refactoring with tests
because that's what I want to be really good at.
And it also keeps me honest about taking tiny steps.
So like it just, it's a tool that the reason I think test-driven development is such a
foundational skill is because it reinforces all of these things because it is a built-in
feedback loop and it helps keep you honest about are you doing large steps where you're
going from where you have a broken implementation.
It's a feedback loop that lets you know more about that because you have a big red thing
as you're writing all this code that hasn't been tested and taking a big step.
It makes you sort of feel the fact that you're doing that a little bit more.
It's a feedback tool for that and feedback tools are important and test-driven development
is a very good feedback tool.
Yeah, I'm thinking you're trying to learn how to drive a car on the racetrack and you're
doing that using the stick shift because you're used to it.
In this analogy, driving the car is extracting an opaque type and the stick shift is TDD.
Like you know how to do TDD, you know how to use the stick.
But if someone doesn't know how to do TDD well or are that familiar with it, then you're
kind of training both things.
Then it's not deliberately practicing the opaque types thing, you're deliberately practicing
a little bit of both.
So I would say you're kind of diluting the practice if you're not familiar with TDD.
If you're familiar with TDD and it's a tool that you use, then sure.
I wouldn't say it's necessarily you need to do TDD.
If it helps you, it helps you.
But otherwise, yeah.
I see what you're saying, but I would look at it more like, well, first of all, if I
was not super comfortable with TDD, instead of saying, therefore I'm going to do some
kata's where I practice some things without TDD, instead I would say, I'm going to get
really good at these TDD skills and do some kata's focused on that before I do these more
advanced things.
I'm going to learn stick shift before I learn these other things because the race is going
to be in stick shift.
And so I'm going to have to get comfortable with stick shift.
And I want to practice all of these things with stick shift.
So I'm going to do that.
I thought you were going to say that.
And to me, it also feels like practicing music without a metronome.
It's like it's just such a foundational tool because again, it's a tool that assists you
in taking it up a small notch at a time.
And it helps you just like in the same way, TDD helps you control the size of your steps.
So you can play around with that.
It helps you manage your refactoring.
So it's just a foundational tool that I consider to be core to all of these practices.
Yeah, but there will be some exercises where you won't need TDD or for instance, for piano,
you will need to put your hands into specific positions.
Like if you're doing a chord on a guitar as well, you don't need the metronome.
Where the metronome is going to be helpful for so many exercises, but not for some of
them, not for the more, the tiny ones.
But it might be helpful for more things than you realize too, because even practicing particular
chord voicings on the piano or guitar or whatever it may be, if something takes you a long time
to get your hand into the correct position for that, maybe you're without a metronome,
you're going to be practicing that in a way that doesn't nudge you to grow a little bit.
And so what's going to tend to happen is the ones that you're comfortable with, the G major
chord on the guitar that you're comfortable getting your hands into versus the bar chord
that you're less comfortable getting your hands into, you're going to take a little
more time every time you get your hand into the bar chord and you're little by little
going to get really fast at doing that familiar G major chord and stay kind of the same speed
at the F major chord.
If you put on a metronome, little by little, you're going to grow a little bit every day
and you're going to get better at it.
So it just keeps you honest.
And I see TDD as the same sort of forcing function there.
Yeah, I would say this is like, again, the level of difficulty, the level of challenge.
Like if you really don't know how to do that chord, like if it's painful for your hand,
then practice it without the metronome.
Once you feel like you can do it, start adding the metronome because you're now at that level
of challenge.
So yeah, TDD is a good tool to have.
Yeah, we may have to agree to disagree on this one, but hopefully, I mean, people can
come to the conclusion.
We disagree on the tiny details.
Like I'm always nitpicking, but as long as we agree that you should make opaque types,
we're good.
This Elm Radio podcast can continue on.
I wanted to touch on one thing, which is, so we talked about cadas and these different
types of exercises.
Actually so on the topic of tests versus not being a core practice to this.
So there's something called Exercism, which is a really great service.
And I've gone through several of them, really enjoyed them, learned a lot from them going
through different languages.
Definitely recommend it.
Try it out.
It uses Elm Review to check the results.
Yeah, yeah, that's so cool.
Yeah, it's amazing.
So one thing to be aware of with Exercism is that it is different than code cadas, at
least how I practice them, in the sense that the tests are written for you.
So I just think that's something to be aware of.
Do Exercism, have fun with it, get feedback from people that helps you learn a language
and get more idiomatic about it.
It's very good for that.
It does not help you learn and practice TDD because TDD, an important part of TDD is writing
tests and you don't write tests.
You're given a suite of tests and you make them pass.
So it's just different.
It's not bad, but don't go into it expecting to learn TDD because it doesn't, it just doesn't
teach you that skill.
Okay, let's talk about tests again.
So let's imagine you want to do the opaque type thing and you start by writing tests,
from what I understand, right?
Yes, yes.
And then you, once you have that safety net and that feedback mechanism, that's when you
start actually doing the opaque type migration.
So you're going to do this exercise and you're going to be somewhat content or discontent
with your results and you're going to do it again.
Will you again write the tests from scratch or will you reuse the tests?
I will write the tests from scratch.
I'll throw everything away.
I'll get reset hard.
Okay, because that feels like you're again not practicing this turn.
You're practicing the turn and the whole, the very long straight line before it.
It doesn't feel that way to me.
And especially if you become very fluent with writing test cases, that's just how you code.
It's not an extra step.
It's not extra credit.
That's just what coding looks like.
And I think that's, you know.
For instance, if I'm doing the Gilded Rose kata, where the code is already written, but
there are no tests, writing the tests is something that I wouldn't like to practice potentially
because it's interesting.
But in a more realistic scenario, I might have written the code along with tests.
So Gilded Rose is actually a special case for me because it's a legacy code kata.
And so yeah, in that case, I do practice that sometimes with an existing test suite.
So yeah, to just say, here's some super messy code that I want to refactor.
I'm just going to go in and refactor.
And I think that's, for me, that's super valuable.
So yeah.
So I think the difference in what we had in mind for the question was, I imagine that
you've got existing code and you have to write tests for it.
Whereas you were thinking of, I'm going to write tests for the results.
So that is part of the exercise.
I would never do fizzbuzz kata, tennis kata, Roman numeral kata with, here's a suite of
Now I need to make them pass.
I only do those with, okay, what's our first test case?
And that's one of the things that I might experiment with.
What does it look like if I do that with fuzz tests?
What if I do fizzbuzz with fuzz tests?
What does that look like?
I don't even know.
We've talked about that on our episode with Martin, where we talked about fuzz testing.
Martin Janacek.
By the way, that would be fuzz biz.
Fair point.
And I won't let that job.
Instantly fired.
You have not been hired, but you have been fired already.
We may take the unusual case of hiring you for the sole purpose of being able to fire
That's fair.
So we agree again.
So, yeah, exorcism, definitely play around with exorcism.
I also-
That said, for exorcism, you got a lot of exercises which are problems to solve.
If you don't know how to solve them, then it's not a good exercise to practice something.
You need to understand the problem well to have resolved it already before you can see
it as the exercise for different techniques, I would say.
That's absolutely.
So not that there's anything wrong with just exploring and saying, I'm going to try to
solve this problem.
That's totally fine.
But hopefully people have a takeaway that maybe if they really want to do deliberate
practice, they want to set an intention, get better at a specific habit or skill.
A really good way to do that is to repeatedly do the same thing, changing one piece of it.
I'm going to change how I try this thing.
I'm going to change using opaque types.
So that's a really good technique.
It doesn't mean that it can't be great to just explore, like, I'm going to try to solve
this problem and only ever try solving it one time in your life.
That's a great thing to do, too.
But yeah, like repeatedly doing the same problem is a very powerful tool for building habits,
specifically for building habits.
So I think that's it's worth making that distinction.
So there's also Advent of Code, which is at the time we're recording this, very close
at the time people are listening to this, probably starting right now.
It probably started.
You already have a few days of exercises.
You have a few.
Yes, it's not too late to start now.
So absolutely go do it.
And Advent of Code is super fun.
It's a great way to experiment with test driven development or any different programming languages,
different programming techniques.
And it's just fun exercises.
Again, it is like it's not necessarily the best way to just like extremely deliberately
and in a very focused way, build a specific habit.
But it's a great thing to do.
So yeah, definitely have it's fun and learning and fun are inseparable, in my opinion.
Like we shouldn't we shouldn't feel like we're forcing ourselves to do things.
We should be curious and have fun doing things.
So I have heard that Elm Radio is a podcast about Elm.
Maybe we should talk about it a little bit.
So one thing that we'll notice that feedback loops, quick feedback loops are very important
to learn.
And the Elm compiler being very fast makes it very nice.
But yeah, my question for you is, what do you think that Elm programmers should deliberately
practice except TDD and small steps?
Which absolutely.
On three, one, two, three.
Opaque types.
There you go.
Love it.
Yeah, I think I think it's really nice to think about like, OK, so when you establish
a routine of using these deliberate practice techniques and using cadas to hone particular
skills in a certain way, you develop a relationship with it where you can almost like use it to
explore deep questions about how to approach problems, which is kind of cool.
So I like to think of it like that, like, hmm, I wonder what it would be like if like,
what would it be like if I made everything an opaque type?
That would be interesting.
What if I solved a problem where everything was an opaque type?
What if I solved a problem with zero type aliases or primitive types in Elm?
That'd be interesting.
Is it a good idea?
Maybe maybe not.
But you know, you know, what would be a really bad place to do that experiment is in your
production code base.
And you know, what would be a really good place to do that experiment is not there,
maybe in a cada that you can throw away at the end and pretend never happened because
it turned out to be a really bad idea.
That's fine.
Like, this is a safe space to try out your possibly bad ideas.
And no one has to see it ever.
So yeah, use that opportunity to experiment and validate or invalidate ideas.
I think it's a really good place to explore.
So like, if you have a question like, are opaque types really that useful?
Try a cada with them.
And that's a good way to get a sense of that.
So yeah, like what types of things might you be exploring those kinds of questions with
in Elm?
To me, I often think about like, yeah, how do like, how do I want to organize my code?
When do I want to extract my modules?
You know, is like, is fuzz testing?
When is fuzz testing useful?
What kinds of cases can it help with?
Like, that's a really good thing to explore in that context.
How do I approach refactoring?
How can I use my tools to better refactor?
How can I make this impossible state impossible?
Or exactly, do I go get there?
Do I use dictionaries to model this or records?
CodeCad is a great way to explore that.
Extracting functions also, although that will be part of the process as well.
But I mean, if you want to test to, if you want to practice lower level techniques, right?
What about like writing JSON decoders?
You know, like, should I write a unit test with a, for a JSON decoder?
Should I write a fuzz test?
Should I, how does it work?
Like if I write a reversible test for an Elm JSON decoder encoder pair or a codec, if I
use Elm codec or if I use Elm serialize instead of Elm codec, like you can play around with
that and try it, you know, do a, create a little JSON serialization, deserialization
kata for yourself in Elm.
That's like a great thing to experiment with.
Even trying like different dictionary implementations, any dict and it's a great place to just,
it's a laboratory for, for trying these things out.
So if there's something you want to like learn about, it can help you learn and explore an
idea if there's a habit you want to build, you can build that habit.
So like, when should I write, when should I write type annotations?
If ever, what if I did a kata for where I never wrote a type annotation?
What would happen?
Would it, would it suck or would it be liberating?
Can I give the answer?
Opaque type, oh no.
I thought opaque types was the answer to everything.
But there are better answers to this question.
So the answer is opaque types.
No, it's a, yeah, always write type annotations.
But, but you know, like I think if, if you're having an existential crisis about whether
you as an Elm developer should be writing type annotations and you're like flirting
with the idea that maybe I don't always need to write a type annotation, take that heretical
thought and in the privacy of your own home, do a little code kata to see how it feels.
Nobody has to know whatever happened.
It's a safe space.
I'm guessing that for these, there are certain questions like, like these where you will
feel the pain of doing or not doing something when you need to maintain code.
So you need to do, to have larger amounts of code.
So for instance, like why would you use Elm?
Oh, well try a kata.
But if the kata is quite small, then Elm is going to be, feel more painful than JavaScript.
So I'd say that you will not always get the answer you should if you're doing it on the
wrong exercise.
And katas aren't the answer to every problem, unlike opaque types.
Unlike opaque types.
You know, just as I, I said that I think that, you know, like something like, something like
exorcism isn't teaching you test-driven development.
It doesn't mean it's bad.
It's just, you're not going to learn that from it.
Code katas are not going to teach you everything.
It's like, it's a very good way to do a very specific thing, but it doesn't teach you everything.
It's not, it's not a proxy for every real world code situation.
Real world code is messy and ugly and has all these properties that a kata doesn't.
So, but you can have a very short feedback loop to try things very quickly.
And that's a good learning environment for specific types of things.
So know what it's good for, it's not a substitute for all learning.
So in a way I think of, I think of it a little bit like unit tests versus end to end tests.
Like if I have only unit tests in my code base and no end to end tests, I'm not going
to have that much confidence about going to production.
Is my payment processing still working?
Is, you know, I probably want like some monitoring end to end tests, you know, maybe some like
smoke tests, like some performance tests and, and a lot of unit tests because unit tests
are very cheap and easy way to exhaustively exercise all of the behavior of a function.
They're very good at that.
They're not very good at making sure that your entire application is wired up in a way
that's going to accept Black Friday coupon codes and receive money in your payment processing
platform when the big sale happens.
And that's probably something you want to know.
And a unit test just doesn't give you that.
And in the same way, like code cutters are very good for like drilling in a particular
habit or skill or exploring a small idea.
But that's, that's what the tool is for, but you should still be exploring, exploring things
in your code base and introspecting.
What do I want to experiment with in a production context and safely experimenting with things
in production, doing spikes, doing small research spikes where maybe you try some mad science
fuzz testing thing.
Maybe you want to do that in your code base and see how it goes.
So code cutters aren't a substitute for that.
Another thing I wanted to mention is TCR, test, commit, revert, which is a really, really
interesting technique where you, it's, it's pretty extreme as far as XP goes.
It's definitely turning it up to 11.
Yeah, I would say so.
So the idea is you have your suite of tests running, you have a test watcher and you make
a change to your code.
Anytime your test suite goes green.
So you do a refactoring step.
Your test reruns.
It's green.
It automatically commits it.
Anytime your test suite is red, you do a small step.
It makes things red.
It reverts it.
Every time you save, right?
So it's interesting because it, it actually does change the test driven development workflow
a little bit because in test driven development, you start with a red test, but in TCR you
can't do a red step.
So it changes the way you do things, but you have to do a lot more preparatory steps, faking
values along with a new test case.
So it immediately passes things like that.
But it's really interesting for keeping you honest with taking tiny steps.
So that's, I have not used TCR in a production context personally, but it's a very good learning
tool and I really like experimenting with it in the context of Katas.
It's a really good way to keep you honest for taking tiny steps so that that can be
like a nice exercise to play around with in a Kata, for example.
Do you have a tool somewhere to try that out?
I have a little script I can share.
It's just a small little script.
And there's a live stream that Corey Haynes and I did that I'll share a link to where
we did the Gilded Rose Kata in Elm with like a prototype of a snapshot testing Elm tool
I built and we used like a TCR workflow where it would automatically commit a revert.
So I'll share that as well.
Yeah, actually Aaron Vonderhaar and I have been doing some occasional pairing sessions
together where we've actually been doing like some refactoring on the Elm GraphQL code base
as practice, just for fun to hone our skills.
And we've been using like a TCR workflow to refactor and take tiny steps.
So I guess I take that back.
I have somewhat used TCR in a production context, but still pretty experimental.
So sometimes you can find like a way to do exercises in a low stakes safe way where you
can experiment in production.
So you need to create some guardrails and limit the scope and risk of that experiment.
But you can set it up in a way where you can do a small experiment in production too.
So I think we're coming to the end.
So maybe we should summarize what deliberate practice is and how you can use it.
So what I gather is that you should try to find something that you want to improve.
You make an intention, you make a goal of improving some kind of thing, and then you
do some introspection on figure out how can I improve this?
How can I cut this up into multiple separate exercises that I can work on?
And then whenever you do these on repeat, on repeat, and then you do some again introspection
to figure out, did I do this how I wanted it to be?
Did I improve?
Did I did it worse?
And you continue on until you're happy with the results, or maybe you even change the
That's a great summary.
And you need to do TDD apparently.
Dillon says do TDD.
Tell them Dillon sent you.
And have fun and explore and hopefully doing this with other people is great too.
You can learn a lot from other people's ideas about this.
It can make it more fun.
It can give you a way to learn from what shortcut key somebody else is using or...
So much.
Just these little things that you pick up from other people.
And it also naturally makes it easier to be like, do we really need to take that small
of a step?
And you're like, well, we're doing the exercise.
Let's do it.
It helps you sort of stay disciplined about doing the exercise.
Learning shortcuts is also something like you should absolutely do something deliberate
and practice on those a few.
That's a great constraint game.
Yeah, absolutely.
So, where can people find exercises and katas?
So you mentioned exorcism.
Are there any katas that...
I think you have a repo with a few katas.
I do have a repo with a starter for some katas.
And yeah, I'll link to some resources for some katas, some descriptions of katas, a
Gilded Rose kata starter, that video where Corey and I go through Gilded Rose.
And you just sort of have to dive in a little bit too.
It's the kind of thing like you might not necessarily have somebody sit you down and
like say, here's how you do a kata.
So you just start somewhere.
Just do like really just, you know, try to solve fizzbuzz, do elm init and set up a test
repo or you can like pull down my elm kata starter, you know, probably nicer because
you don't have to set up elm tests and things like that.
Clone that, write a failing test for fizzbuzz with one, input one, make it pass, etc, etc
until you solve fizzbuzz.
Like really that...
And then?
And then apply to Dillon's company because he wants to hire fizzbuzz developers.
I want to hire fuzzbuzz developers.
It's more cutting edge.
Am I fired again or?
Double fired.
Double fired.
Twice in a day.
Try fizzbuzz and then try it again.
If you've done that, then you're well on your way to doing katas.
So like it seems very simple, but start there.
Well, so give us a star and heart and favorite on Twitter if that's still around when this
episode goes live.
Give us a rating in iTunes podcasts.
Tell a friend about Elm Radio.
Submit a question at slash question.
Join our Slack channel, elm-radio in the Elm Slack and Jeroen.
Until next time.
Until next time.