Code Reading Club with Katja Mordaunt

We discuss Code Reading Club, how improving your code reading skills can make you a better programmer, and the readability of Elm code.
September 25, 2023


Hello Jeroen.
Hello Dillon.
Read any good code lately?
I read a lot of great code.
I thought you were going to start by doing a bad pun, but I feel like you're reading
The Room recently and I feel like you shouldn't.
I was having trouble decoding your joke at first, but it finally landed.
Well, hopefully we've got somebody who can save us from our terrible puns today.
Katja Mordent is joining us.
Welcome Katja.
Thanks for joining us.
Thanks for having me.
I'm excited.
I'm excited to do some, I don't know, code reading The Room.
You're supposed to save us from the puns, not tangle us into them further.
So Katja, what is Code Reading Club?
Wow, that's a big question Dillon.
Our episodes are usually pretty long, so you have all the time you need.
Is an hour and a half sufficient?
So Code Reading Club is not a club where I get together with lots of small children and
teach them to read code, which is a common misconception.
So a lot of times people say, oh, you do Code Reading Club.
That's so cute.
But it's not.
It's for professional developers.
And it was inspired by research that Felina Hermans did.
I saw her speak at a couple of conferences and then approached her after one of them
and said, all of that theory that you're talking about would be really interesting to bring
into practice.
I can see all of these problems manifesting with my development teams.
And I'd really like to make some strategies and techniques and things to help bring this
knowledge to them.
So that's kind of where it came from.
Have either one of you ever been to one of my Code Reading Clubs?
Are they online?
They are online.
Yeah, I mean, they're in person and online.
So if I go back to our original question, probably I should introduce what Code Reading
Club is entirely, because it is a club where you read code, or a set of clubs where you
read code.
Code Reading Club is a set of exercises that have been designed to help professional programmers
get better at reading code.
It's to help with getting into a new code base.
So looking at a piece of unfamiliar code.
It's to help with finding bugs and like figuring out what's going wrong.
It's to help with how you can review code and have conversations about code with your
And the way that it manifests is about an hour, it takes about an hour and a half, and
you should run your clubs with the same people over and over so that people get familiar
with each other and how they think.
You can do it with your programming teams in your company, or you can do it with a group
of people from lots of different companies, and they both have different benefits.
And the exercises are designed to start from like looking at the very first exercise that
we always do is an exercise called first glance, where you look at a whole piece of code in
one glance and like less than 10 seconds and try and identify what the thing that jumps
out at you is.
And then you try and identify what the second thing that jumped out at you was.
And then you try and think about why those two things jumped out at you and you have
a conversation.
So every exercise is designed for like individuals do it by themselves and reflect on it by themselves
and then bring it back to the group and the group has a conversation about it.
So I'm going to pause and let you ask me a question.
So I kind of want to ask you like, what are the kinds of things that pop out that jumped
at people, but maybe that will spoil the exercise for me.
I don't know.
No, there are no spoilers.
And there are no like wrong answers and in code reading clubs either.
So I should also go back and say that we always look at a piece of code that is an open source
piece of code that is real, like in production somewhere.
We tend to try and use packages that we think a lot of people are using.
We look at all different languages.
The only constraint that we make is that the code should be like around 120 lines and we
don't do any editing.
So we don't take out any comments.
We don't take out any white space.
We don't do anything to it.
We just take it as it is out of GitHub.
And we have a tool in our code reading club website, which allows you to make a PDF out
of a piece of code in GitHub and another tool which allows you to annotate a piece of code,
which is another one of the exercises we do.
But so in terms of like the things that jump out at people, they can be like really trivial.
They can be some like comment block.
They can be a word.
Often if there's a word like Microsoft in there, then that jumps out at people.
Sometimes it's like a really long variable name or sometimes it's I mean, it's different
One thing is that beginners tend to look at the top of the page and read like if they
were reading like a natural language prose, whereas more experienced developers will like
try and like jump for the export or something like look for the return statement or like
dive into the middle of where something looks like a big nested loop or things like that.
It makes me think of I recently read a really great book called The Inner Game of Tennis.
And one of the things it talks a lot about is sort of natural learning processes as opposed
to like sort of more top down learning where, you know, if you're trying to help somebody
with a tennis stroke, telling them every physical motion and describing it in great detail versus
having a high level tennis player hit some tennis balls and saying, watch this and repeat
after me, you know.
And this book talks a lot about, you know, looking at following the tennis ball or looking
at the seams of the tennis ball to really just bring your attention to specific places
and then trust the learning that comes from watching that and tapping into that rather
than just intellectually trying to overthink.
It's trying to tap into your subconscious because your subconscious is going to be able
to play a way better tennis game than your conscious brain.
And it seems like there's something here that maybe your subconscious is going to be able
to have more insights about code than your conscious brain.
Do you see that as part of it?
Yes, definitely.
And I wanted to go back and say that a lot of that.
So Felina wrote a book at the same time as we were developing the exercises for the Code
Reading Club.
And that book is called The Programmer's Brain.
And in the book, it details a lot of the theories behind the exercises that we developed and
also some of the exercises that we do, although we made them so the ones in the book are made
so that you can do them by yourself or do them like you can do them in pairs and things.
But the ones that we made for the club are deliberately like designed for like working
in a group.
So the book, it basically she set out to study what are the cognitive processes that happen
in your brain when you're trying to read code, because she started trying to teach children
to code and realize that.
Yeah, very, very cute.
It's a sad story how she got to that, because unfortunately, when she was doing her PhD,
she got a little bit slated by the programming community, which made her in her own words
cry, because she was she was tasked with making a domain specific language for the finance
industry by her PhD supervisor.
And she went and did all the research and found out that they already had one.
And it was called spreadsheets.
And it was working really well for them.
And she did her PhD on the on spreadsheets or programming.
And a lot of the programming community did not like that.
And so she took a whole different branch in her career and started thinking about the
cognitive processes and what she started thinking about teaching kids to code, because she thought,
oh, I know one thing I'm good at programming.
I can teach kids to do this and then found that she couldn't teach kids to do it because
there wasn't any good methodology for doing that as there is teaching and other things.
So the basis of the book and the basis of the exercise is like three parts of your brain,
like how brain process, which is your short term memory, your long term memory and your
working memory.
And your short term memory is about information.
And as we probably mostly know, you can only hold like very small, like amounts of information
in your head at one at any given time.
There's like a debate of whether it's like four or seven or something.
It's well researched.
But you can hold chunks of information.
And that's one of the things that maybe Dillon was alluding to.
I know it took me a long time to get here.
Back to your point.
But you can hold chunks of information, which are your previous knowledge and your previous
knowledge, your long term memory is like a network of related things.
So it's really good.
Like one of the things that Felina says is if you do deliberate practice in, for example,
learning syntax or learning like common patterns that we use, often programmers will think,
oh, I'll just look that up every time I know I can.
I know I can look that up on the Internet, so I don't need to memorize it.
But actually, what happens if you just look it up on the Internet is you end up going
down a very fascinating rabbit hole and all sorts of other things, probably.
And you're distracting yourself away from from like being in the flow of writing code.
And on top of that, you're also taking away from yourself the ability to be able to chunk
things and see like see the bigger picture.
If you have it memorized in your brain, then you'll be able to like more fluidly read the
And so it kind of benefits you in both ways.
And one advice is like, if you must look it up, firstly, write down somewhere the things
that you're looking up and make flashcards out of them so that you don't keep looking
up the same things all the time.
And the second thing is, before you look it up, try and remember it.
Try and do it yourself, because that's how we make those.
I can't remember what it's called.
It's called something with elaborate.
I don't remember what it's called exactly, but it's how you make that retrieval to how
you make that connection to something else in your brain.
And we're very good at doing it like associations with experiences and things.
But we don't really think about doing it with programming, but it is the same thing.
And there's some research that says that your subconscious brain like holds everything you've
ever known and ever seen and ever, ever, ever.
But it's the fact that you can't retrieve it.
That is the problem.
It's the cache misses.
I don't know what that...
Well, your brain, your brain is...
Oh, the cache!
It's not in the cache, right?
It's in the cache.
I'm like, who is this cache misses scientist?
What are you talking about?
Yes, yes, the cache misses.
Miss and Mr. Cache.
So, yeah.
So, if you try, if you try deliberately to remember or to like reproduce something or
remember something, even if you're doing it wrong, you're actually not training yourself
the wrong thing by guessing, which is maybe what it feels like you might be doing.
Or making a pathway in your brain so that next time you will be able to remember it.
To be able to access it faster.
I remember hearing that if you try to come to remember like a word and you know you have
it on the tip of your tongue and you try to recollect it and someone gives you the answer,
then you're not going to remember it for the next time.
So if you come, if you try to remember it and then you succeed, then you just made a
pathway where it will be easier to remember next time.
But if someone tells you the answer, then you won't.
I don't know if that's true, but I've heard it.
I should look up the research somehow.
I mean, I think that, I mean, that makes sense with what little I know about the brain process,
which is what I've all learned from Felina and her book and talking to her.
So one of the problems that you hit in programming is that this long-term knowledge, if you don't
have knowledge about the domain or if you don't have experience in programming this
specific pattern from before, then that will stump you.
That will take up all your cognitive process when you're trying to work it out.
And the working memory is where you're actually trying to process or calculate something as
you're reading it.
So when you're going through reading code, you can do what's called a cognitive refactor
to try and like split things out separately so that they're in small chunks that will
help you be able to process like each small chunk.
And that's one of the reasons why Elm is really great as well, because it encourages you to
write in ways that are really easy to process in our tiny brains.
So I do really want to get into this topic of why Elm is easier to process in some ways,
but let's put a pin in there for a second because I'm still really fascinated by this,
you know, retrieval and chunking and stuff.
So I read once about a study they did with chess players where they took...
It's in the book.
Are you familiar?
Yeah, it's in the book.
Oh, cool, cool, cool.
So the gist of it is that they took, from what I remember of the study, it was like
you take very skilled chess players and then some lower level chess players and you put
a chess position in front of them for however long and then take it away and then ask them
to set up and recreate the position on the board.
And what they found was that, as you would imagine, the much more experienced skilled
chess players performed far better than the less experienced chess players.
But then it actually changed when they started showing them positions that were nonsensical
because pawns would legally not be able to arrive at certain positions or certain, you
know, rooks like to be together in the same rank or file, but they weren't.
And maybe there are two dark squared bishops or things that just don't make sense in a
chess game.
And suddenly they were equalized.
The less experienced and the more experienced chess players were equalized.
And the moral of the story being that basically the advanced chess players were chunking these
things into high level groupings.
So they were noticing dynamics instead of piece by piece, remembering where each piece
They know, oh, this is a fianchetto position and the knight is, you know, the king is castled
kingside and this looks like a Sicilian, you know, things like that.
They were just one high level concept in their brain that was easily retrievable.
Whereas the less experienced players were just looking at every single piece on the
So I think that there is a clue there about how to get better at reading and writing and
maintaining code, which is, you know, having these shorthands and these ways to think in
higher level terms.
So as you said earlier, Katya, you can't increase the number of items in your short term memory
that you're able to hold, but you can learn to think in higher level terms and equip yourself
with some high level concepts that allow you to navigate a particular area.
Well, it might allow you to navigate a regular chess board, but not an abnormal chess board,
but that's okay for a real game of chess.
So in Felina's book, as I said, she does give that as an example of chunking.
And there have subsequently been some people doing software, like research with software
developers in chunking.
And yes, if you use familiar patterns, and if you use more high level, like functions,
like mapping rather than for loops, then you will take away some of the cognitive issues
that people will have when they're trying to process reading code.
There's been specific research on that?
That's kind of cool.
So like more a more declarative style?
That definitely resonates with my experience, but I am highly biased.
I was wondering if you wanted me to go back to the code reading club exercises, because
I only mentioned like the first one, and I just wonder, there's about 10 that I can just
use over and over again, and I can maybe just give like a really quick explanation.
I didn't know how much time you wanted me to take on specifically like what happens
in a code reading club versus like, what happens when you read code?
I'm interested in both.
I'm very interested in like how to apply these things to actually get better at reading code.
Yeah, that sounds great.
Yeah, and writing and writing code, which is one of the like side effects.
And one of the very exciting side effects that happened was making people aware of how
to write more readable code for the like diverse teams.
I would say that is a controlled effect.
A managed effect?
Yeah, not a side effect.
Because you meant for that to happen.
I didn't.
It was totally unexpected, and I don't know how to process puns.
Rolling your eyes like you just did is perfect.
That is the intent.
So there wasn't a side effect.
So as I said before, like all the exercises are designed so that you do them individually,
and then you come back and discuss what you like, what the experience was like for you.
And the amazing thing that happened was that that obviously makes people who are in the
group much more empathetic with the other people who are in the group.
And they start asking questions like, oh, so if I wrote it like this, it would be easier
for you to read.
And then the person says, yes, it would.
And they say, oh, well, then I'll write it like that from now on.
And that's been really very cool.
So the exercises start out by, as programmers, we are always wanting to figure things out,
Like solve the puzzle, figure out the problem.
And so when you put a piece of unseen code in front of a programmer, they're immediately
like, I want to crack this code.
And so we try and step back from that and explain that we are trying to learn like deliberate
techniques, practices that we don't use every day.
You already know how to Google things.
You already know how to use a syntax highlighter and like your ID, because that's one of the
other things that we always look at, just black and white code.
So or any color, but like two tones.
So and people question that to begin with.
But it is training your brain in a different way to just look at the code.
And one of the really cool things as well, when we first started was we printed things
out on paper.
This is before the pandemic, when we did all of our clubs in person.
And it really does change the way that your brain processes what's on the page.
It's amazing.
Like, I know my brain, when I look at it on my computer screen, my brain's constantly
trying to like process it and make it like evaluate, right?
When I look at it on a page, like I guess people get it from reading textbooks about
computer programming.
It's a very different, it's just a different part of your brain, I think that's acting
on it.
So would you say that highlighted code is easier to read or worse to read?
I think that it's different to read.
And I think that it makes it makes it more dynamic in your mind.
What do you mean with dynamic?
So it makes it like that the code is evaluating, it makes it like that the the actors in like
the words have more properties than just being a word.
And there's there's from a long time ago, and I think it was maybe in the 70s, there,
there's a video that someone showed me of a person who was experimenting with making
annotations in IDEs that were for reading code that's different to the ones that you
use when you're writing code.
And that is a cool idea for me, like, that's one of my like, side side side projects in
the future one day, you know, when I get to be retired.
That I will look at because that is fascinating.
And if there's a lot of research now happening on what will help us read code, that I can
I can apply that research to this like switching editor of like, now I'm writing now I'm reading,
what different things would you want highlighted?
You know, you don't have to wait until retirement.
It's called open source, you just need to spend hours and weeks working, right?
It's fine.
But I already have some other things like code reading club that I have to do in my
spare time.
Yeah, so so really, I keep getting distracted.
But in terms of the exercises, we start off by just looking at words in isolation or a
line in isolation.
So there's one exercise, which is random line where we just select a random line in the
And then we think about what that line means on its own, and how it relates to the other
lines around it.
And one of the themes of code reading also is about which things are specific to the
domain of the program and which things are knowledge that you need from computer science,
or or from so.
So that's one thing that that your brain will hit when you're trying to read code, because
we always read the this code out of context.
So people won't even know what domain it's in.
And sometimes words get very, like people have misconceptions about like that a word
is referring to a specific thing, when by the time you finish the club an hour and a
half later, you realize that that is not the not what that word meant at all.
I can't think of a specific example right now.
But that that happens pretty frequently.
Cash missing is a perfect example.
That in itself was a cash miss.
So I guess yeah, so the thing that we're trying to do at the start of the club in the first
half is looking at what are the stumbling, like what are the building blocks and what
are the things within those building blocks that are going to make it really difficult
for you to process or different people in the room to process.
So another thing we look at is syntax, just asking people to highlight things that look
confusing to them, things they don't understand.
And then other people in the room can say, oh, that looks similar to what happens in
this language.
Maybe it's this.
One of the things that that really trips people up a lot is types in TypeScript.
If they're a JavaScript programmer who's never done TypeScript before, they get really confused
about what where the types are declared.
Whereas when you do Elm code, nobody gets confused about where the types are.
So that's that's one that's one thing.
But yeah, so we look at the syntax and then we don't we don't the facilitator will not
participate in a way of answering questions.
They just participate in facilitating the conversation in the room.
So we do that.
People make make wrong declarations and and just let it sit because you're working with
the knowledge of like everyone's on the same same playing field, as it were.
People have previous knowledge that helps other people.
It seems like there's a lot of the like diverge type activity where you're just like, let's
not start limiting and constraining the ideas we're going to explore.
Let's get everything we're noticing on the table and opening your your mind, because
what happens a lot like I actually used to used to run a learn to code meetup in my hometown.
And and so I would observe a lot of people who were brand new to coding going through
the process of debugging something or trying to make some code work.
And what I noticed was happening a lot, like one of the biggest stumbling blocks I saw
was just not trying something without having a theory of what was going on.
So like debugging and just typing some code, I would try to get people in the habit of
saying like, OK, before you type something, what do you think is causing the problem?
And what's your hypothesis?
Like what do you believe is causing the problem and how will you evaluate the change that
you're about to make?
How would you expect that to have an effect if that is the source of the problem or if
it's not the source of the problem?
But that type of thinking that what that wasn't the comfortable process that people.
So I'm not sure if there's any, you know, connection there with with reading code, but
just have it making your intentions more clear.
I thought it was really powerful and also that opens you up to more possibilities because
you can get very tunnel visioned on one specific line and not can.
So it's a good thing to step back first and say, well, what are the possibilities here?
There is currently a project that I'm trying to refactor where there is a type that I don't
It's it deals with parsers and it's too complicated for me.
And right now what I'm doing is I'm changing the type, trying to change the type to do
something else.
And then I get compiler errors.
And that tells me a little bit more of what is going on, like what it is trying to do,
what it what the type is for.
And I'm again, a little bit more understanding every time I try it out.
But yeah, so I make a change and then I try to understand what I discovered.
So are you are you saying that you're doing the thing that Dillon was discouraging in terms
of you're just trying something because you can't you don't even know where to start in
terms of figuring out a hypothesis in a way.
But in this case, I have a compiler that helps me.
Which compiler would that be?
Maybe a long compiler, who knows?
Out of...
Lucky you.
But yeah, like if this was JavaScript, like no, this is not helpful.
Maybe tests would help.
But yeah, otherwise, not the way to go.
It's really because I really don't understand the code.
I'm just trying whatever and see what what sticks.
So this is like a little bit tangential.
But one of the one of the things that inspired me to start Code Reading Club was this practice
of rewriting other people's code.
So I found a lot that there would be a new person on the team who would be given a feature
to write or a bug to fix and they do it.
And then the person who does the code review was like making a suggestion to say, why don't
you just do it this way instead of actually bothering to read what the person had written?
Or even worse than that, not even like letting it through the review process.
And then in the next feature that's being made by the person who's been on the team
a longer period of time, they're like sneaking in like a whole refactor on the code that
the other person had had successfully submitted and was working and had gone through the review
And that to me is is a lot of because we practice writing so much.
That's what we feel confident and comfortable to do.
And we don't practice reading enough to feel confident and comfortable to talk about and
reason about what things that exist already mean.
Something that I've learned from Dillon and from Llewellyn Falkor's talks is refactoring
to understand code as well.
So if something is too complex or does something odd, then you refactor, you chunk it, you
rename things, you inline things, you outline, extract things.
Should be outline in order to understand it.
Yeah, so this is what Felina calls the cognitive refactor.
And the way that she promotes it is that you should do it if you're new to a project or
if you're new to programming, but you should also change it back if it was more maintainable
the way it was before.
Yeah, that's right.
You have to think you have to think about it.
But sometimes you're making it more maintainable by doing it.
And again, I know we're not allowed to talk about Elm for some reason yet, but we are.
There's so much we can talk about there.
But that is another like, really, really, really, really beautiful, amazing thing about
Elm in terms of all the things that I'm trying to promote with Code Reading Club, which is
that if you need to rename a variable because the thing has changed or you need to rename
a function because the thing that you're doing has changed, it's not scary.
And so you don't get these legacy like naming things where people have just left it because
they're worried about what is going to happen that they can't see, which is which is one
of the things that makes Elm like so much more readable on the surface than other languages.
So I'm curious about this because I as we're talking about some of these things, I definitely
find like for my understanding of code, I am pretty dependent on syntax highlighting,
you know, changing code, like using refactoring tools to change code to understand it better,
doing go to definitions and navigating to test files and things like that.
So I do find if I'm looking at a static piece of paper and it doesn't have highlighting
and I can't navigate to definitions and tests, that's definitely out of my comfort zone.
Like my brain definitely wants to go jump to things and do things with the code.
But so like what are some of the benefits of like specifically developing that skill?
It makes you quick, it makes you quicker at programming because you're not getting that
fundamental thing of like the distraction.
So you're going to another file and looking at the test, you're going to look at a function,
you'll go you you get faced with a bunch of imports at the top and you think, oh, I must
understand all the details about all of these imports, where they're coming from.
Whereas this like allows you really to just focus on the thing that you're looking at
right now.
And this is a very good time for me to like go into the next level of exercise.
So those ones at the beginning are the ones where we're looking at things in isolation.
And the last one of those exercises is about naming.
And I could probably talk about the naming stuff for a really long time.
And Felina is in fact doing a lot more research about naming at the moment.
And there are other other computer scientists who are doing or have done lots of research
about names.
But the naming exercise that we do is just highlighting all the things that a developer
made up a name for.
So basically everything that's not like a keyword, you're highlighting that in the code.
And then you're thinking about how those things are related to each other.
If there's any patterns that you notice or any anomalies.
And there was a piece of code that we were looking at in the last club I did, where there
was one function, which had all single letter variable names.
And all the rest of the code was very like verbose.
And all the variable names were very verbose.
And we had some fun like trying to think about how did that chunk of code get in there.
We ended up probably that it was from cut paste from Stack Overflow.
And that they didn't bother changing the variable names.
But we don't know.
We could because we always use code in GitHub, we could have, after the fact, looked it up.
I got distracted.
So I never ended up trying to find the source of truth.
It could have just been a different developer.
It was also something that was like it was a for loop or something.
There was something some other reason why it might have been used like that.
But back to just naming things.
So then you see, look at all the names and you try and start thinking about like, which
ones are specific to the domain that we talked about before, or which ones are programming
computer programming concepts or math concepts that you know from other parts of your knowledge.
And then this is also one of the first things that made me want to do this with development
teams, which is that you can actually come up with a set of guidelines for your team
for naming so that you don't have like snake case and camel case in the same code base.
Of course, Elm like solves that problem for us.
But in other programming languages, you do have those choices and you do have a mixture
of both.
And there is I'm probably going to get this wrong, but there is some research which maybe
Evan knows about that camel casing is much less error prone to read.
It takes you a little bit longer than snake case, but it but it has like a lot higher
cognition after you've read it.
So camel case is the what we use in Elm usually.
Snake case is the one with underscores.
OK, I was going to bring this up and I my memory says that it was the opposite.
The snake case was actually easier to understand.
It's quicker to read according like, yeah, I mean, maybe maybe we need to look this up.
Maybe I'm wrong, but I haven't looked it up in a year or so.
It's quicker to read snake case, but it's you get the wrong idea more often.
Oh, you have the wrong concept in your head more often.
And there's a lot of things that Felina talks about as well, which are just like very simple.
Like if you if you ever use abbreviations or you never use abbreviations or because
sometimes I see code a lot where you start at the top of the function and then like an
outer layer of the function with a full word like object and then it turns into OBJ as
you start processing it and then you do a little bit more and it turns into O at the
end and it's the same thing that's flowing through.
But it's really difficult, like it takes so many extra steps for your brain to to like
process that it's the same thing that's flowing through.
And yeah, you can just make you can make rules in your team to like always put like the word
max or min at the start of your variable name instead of the end of your variable name.
Because again, every time you come across it in the other way, it trips you up.
Whereas if you get used to certain patterns, which again is the thing in Elm that is like
very like across lots of different packages in the you know, and the community as a whole,
there's a lot of naming conventions that have just kind of stuck that people use, which
you get used to when you when you work on different projects.
And it's really nice that the whole community has like, almost is starting to come up with
its own sort of naming conventions that that you can rely on.
I think there's also in what we're discussing here, like there's, there's this underlying
idea that that small cognitive costs add up in aggregate to a larger cognitive cost, which
I think some people's intuition might be like, hey, it's just just a little abbreviation.
How is that really going to slow me down?
Or is that really the bottleneck to understanding code, but I certainly am of the opinion that
like these tiny cognitive costs, you know, compound, and that also, these tiny micro
skills that we can develop, can combat that and break down and make us stronger.
So small costs accumulate, and small skills build up to make us better at dealing with
those things.
I would definitely agree with that.
And the more that I've done code reading, the more I start to reflect that that's the
other thing that it does for you is it makes you start reflecting on everything you read
and everything you write.
And you can feel those like, you can feel those cognitive like bombs when you see them.
Yeah, it's kind of like you hear people talking about this with productivity, too.
It's like, do you do you get clear on the big priorities in your life?
Or do you get clear on like, the email that you need to send today and the bill you need
to pay today?
Like which one do you do first to get more clarity?
Like which one is more important, right?
It's like, well, what could be more important than the meaning of my life?
It's like, well, but if you're drowning in like, a bill you need to pay today that you
might forget, maybe you're not going to do such a great job thinking about the meaning
of your life.
So similarly, people think about like the high level architectural patterns of their
code and stuff.
And these little, little spots that add a little cognitive load can be forgotten, because
it's like, well, first, let's get the architecture right.
But I think there's value to just starting with those little cognitive burdens.
Yeah, definitely.
And the other thing about just to bring Elm back into it again, is that there's so many
architectural patterns that are just well established within the community, because
there's only like a fixed number of ways you can do things that that that whole burden
is taken off you.
And if you even if you like, I always start with a totally different architecture than
the one that I finished with, or that or like, oh, I guess I'm never finished, but like it
transforms over time.
And with Elm, it's such a low overhead to like keep changing your whole data model to
keep changing the whole way that you know, the whole way the architecture is set up.
It's such a low burden to do that, that you can focus on those little cognitive wins,
I guess is what you were calling them.
So you talked about like, these, you know, domain concepts and names, and then like,
computer programming concepts, or computer science concepts, would sort of like, fmaps,
and monads and things like that, fit into the category of computer science concepts?
And would that be like, is there any research on readability for concepts like that being
used heavily?
Maybe there's not that.
Yeah, I'm thinking I don't know the research that Felina that you know, that I'm familiar
with Felina is just around programming patterns in general, and that it is easier when you
recognize when you recognize a pattern, because you because you know it, and it's worth studying
them in terms of like, specifically functional, like, I guess what you're talking about is
like, almost like pieces or tools that you can that you can leverage.
I suppose one problem, one thing for me would be like, if you called if you called monads
my monad, then that would be a cognitive bomb for me, because then I'd have to start thinking
about what's a monad, what's a monad, what's a monad, every time I saw it.
But I think that's like a different that that's a totally different conversation.
And I think it's like Haskell, the Haskell and Elm communities have like arrived at at
opposite perspectives here, where the Elm community has said, let's use domain terms
here, whatever the terms are in your domain.
And let's sort of not talk about the fact that this is a functor, even though it's like
a thing that you map, let's just use, let's try to use the word map most of the time when
we're doing that type of thing, but let's not talk about this abstract idea, because
beginners can get hung up on it.
So let's not use those that technical jargon.
So it's just very interesting how those two communities have arrived at opposite conclusions
And I think in terms of the readability and the cognitive load, you're you're coming with
a whole bunch of baggage when you use the word functor, or you use the word monad.
And if you're just using the thing that's specific, the concept that's specific to the
thing that you're writing about, then that's that is easier for you to understand that
the name, it's not Felina's research, I can't remember who it is.
But there is some research on how to design well, like how to well design names, how to
choose good names.
There's some research and I always get this wrong, it's in my code reading club, which
is that like only 7% of the time, would you come up with the same name as your colleague,
if you have no conventions together.
So it's a it's a huge field, obviously, naming is famously difficult, right?
But this the way to come up with a good name is I'm going to try and remember it's three,
there's three steps.
One is that you need to identify what concepts you're trying to get across.
The next is to think about what words you want to use for those concepts.
And then the next one is to arrange those words in a meaningful way.
So it's like that's very abstract.
But if you if the middle part of that the the concepts mapping to words bit is like
a glossary that you define with your domain that you can even put with your code, like
this is how we refer, it would solve a surprising number of of those where like the two different
people are calling a person person and someone else is calling it human or whatever those
kind of that's a huge cognitive burden if you're referring to the same data in your
program and someone's calling it humans and someone's calling it person.
What choices like, oh, we tend to use verbs in the present tense, the naming choices,
would that be part of the second step as well?
Yes, yes, I think.
So so yeah, the first step is like, what concepts do you need to get across with this?
Like, what is what is this thing actually doing?
And then and then what words are you going to use to describe and that would include
the tense of those words.
It's just reminded me as well, like way back in the beginning of my code reading club journey.
Another one of the surprises that we discovered was that if you so sometimes we use code reading
club exercises as an interview technique to just to start to understand where a person's
at in their knowledge around not just programming, but just generally, you know, how would they
how would they be able to process this code?
And one of the things that happens when you ask, so I'm like segueing a little bit because
I'm remembering I'm remembering the whole the whole story.
I'm doing like the joke backwards, right?
Great, so yeah, I won't I won't be upset when you don't laugh at the end.
So if you if you assign a new person to your team, a problem, and you tell them what to
call the things in it, you refer to the parts of it in name, you won't learn as much about
what they understand.
So if you don't, if you resist the temptation to tell them what the parts of it are called,
and you let them name it themselves, then you will understand you will see like how
much understanding they have about the thing that they're writing.
So what happens to me often is I'll write a function or name a variable.
And then 10 minutes later, I'm like, that is not what that thing is at all or what it's
doing or what I need that function.
And then I'll rename it.
And when you get a new person on the team to do to do that process, and they they maybe
don't get to the part where they're renaming it because they haven't quite understood where
it sits and what its purpose is.
That is really fascinating.
Also, I like my backwards joke.
I hope that makes sense.
I'm a big fan of a series of blog posts that Arlo Belshi wrote, where he talks about it's
called naming is a process.
I think one of the ideas in there is that like, basically, just acknowledging that a
certain chunk of code is a coherent idea, it can be step one.
And he talks about giving it nonsense, nonsense names like he uses applesauce, basically a
name that it's clear you are going to need to loop back around and change because it's
not connoting anything.
It has no meaning, except that it's like this anonymous thing.
So it's basically a way to clearly mark that this is an anonymous thing that doesn't yet
have a meaningful name, but it is a meaningful group of behavior.
That is, that's very cool.
So I like that idea a lot.
And I use that in like in refactoring, I'll often just be looking at some code and be
like, Oh, yeah, this does look like a paragraph.
You can even like add some white space between a few sets of things that might seem like
they're grouped, should be grouped separately or you know,
But then elm format takes it away again.
I was thinking the same thing.
That's true.
You couldn't put a comment and in that case, you will space it out.
Right, exactly.
And you can just start extracting some things and, you know, give them meaningless names.
So that's a good first step.
Yeah, that's a really good technique to like unblock yourself, right?
We don't always know what we're writing.
Yeah, I think of it like my cognitive pulleys because, you know, it's a technique that allows
you to distribute force over a greater distance.
So you have to exert less force over more time, because sometimes it's too much of a
heavy lift to just do in one step.
You don't know the end result you want, but you know the direction you want.
So you can just start pulling in that direction.
So let's talk about elm.
What's been your experience in these code reading clubs with people looking at elm code
versus other languages?
One of the problems is that the exercises were designed to get people to think about
things in terms of classes and functions and variables.
So one of the exercises that we do after the listing names one is where you then start
highlighting where things are declared and where they're used.
So you can see how the data flows through the program.
And that exercise is often problematic with the elm code.
Apart from you can see where like functions and values are, well functions, where you
can see where all the functions are declared, and then you can see where the functions are
But there's not as much interesting things that happen with that.
Inheritance hierarchies and things like that.
So a lot of the problems that Felina like uncovered in her cognitive research are not problems
in elm.
And so something like this exercise is designed for a code which has those problems.
Identifying like potential mutation that's happening in places or identifying like how
it's basically like how the data flows through the code and like hotspots.
So like if you have like nested for loops and things like that, where you start to get
like super deep into something, these those exercises will highlight like where areas
of the code that look particularly complicated to process are.
And elm comes out very flat in that type of analysis.
It's already done the hard work for you.
It's like, where does the code change?
Update and yeah.
And often because we're also just looking at single files.
I do with elm choose and I don't do this with any other language, actually.
I choose like example files or where where someone's like showing you the whole the whole
functionality rather than like actual elm files.
Firstly, because elm files do tend to be like really long and I'm looking for things that
are less than 120 lines, but also because you don't get as much meaningful analysis
from many of the elm files as you do from other languages where where things are kind
of grouped together in different ways, I guess.
And maybe I need to select different exercises because you definitely get interesting variable
naming conversations.
And like I said before, it's very obvious where the types are.
And there's there's a concept of beacons, which are things that you put in the code
or things that are in the code that help a person frame what's happening.
And like variable names can be beacons or comments can be beacons or function names
and things like the update function being a beacon for like, OK, this starts this section
where we update the model.
Is that the kind of beacon you're thinking of?
Yes, and maybe not.
So like the update function, that's more of a convention of a pattern to like to know.
So you know that that's where the updates are going to happen.
Beacons are more like helping take like helping give the person a hint of like, what's that
thing in their brain that they should be connecting this to?
Like what what are I'm always like struggling to come up with examples, but it's it's like
a hint about.
So what I was going to say is that the variable names in Elm are often like so descriptive
and explicit and specifically formed within like known patterns that they can be like
really good beacons.
The idea of these exercises that that look at hotspots for mutation and things like that,
it actually it's interesting because it it does remind me of something in the context
of Elm that Richard Feldman gave a really nice talk called Scaling Elm Apps.
And one of the key points there was basically like, just make the you know, make the type
annotation for a function as limited as possible.
So if you depend on if you depend on less data as input, then pass in more narrow parameters,
whether that's like just passing in a single value instead of a big record with additional
context you don't depend on.
Or he uses a lot of extensible record syntax to sort of say, you can pass in the whole
record, but I'm only going to look at this.
And I'm going to return the whole record, but I'm only going to possibly change this.
So and don't return a command if you're not going to perform a command, like just as a
default scope it down more narrowly.
So I could imagine doing a similar sort of hotspot analysis in an Elm code base, where
you're saying, well, what is this return?
Or like, if we're trying to follow the code path of like, how this value in the model
could change?
Where could that possibly happen based on the type annotation?
Yeah, and that's a really good example of how you can make something more simple to
understand and make make your intentions more clear about what what you're what you're doing
in that specific place.
Because the exercise that follows on from that data flow one is getting people to independently
identify like the four most important lines in that 120.
And again, that throws up some like very interesting like differences of of why people choose things
that are important.
So people will choose things that have bitten them in the past, people will often choose
like an early return.
And then most of the other people in the room will have not even noticed that it was there,
which is fascinating.
And you know, why it's maybe not such a great pattern.
But again, like things like that, just with with Elm, like, because everything is a function
that returns something, it kind of takes away all the fun.
Right, exactly.
It is so interesting, because like, I always felt like out of place with some of my opinions
on this stuff back in my days doing Ruby on Rails and like different different programming
languages where, you know, there would be an early return and I'd be like, hmm, can
we do this like with an if else and it's like, well, that's like an unnecessary amount of
code that's like, people would think that that was a code smell because it's more terse
if you just do an early return.
But for me, I'm like, this is making my brain think harder.
This is like a very dramatic little keyword that we can put in here that has like an outsized
effect on the behavior of this thing, and like makes it incongruous.
I even have the example where I was going to a coding club, not a reading club, coding
And it was very object oriented.
And at one point they said like, oh, here's an empty pattern, use the else keyword.
I'm like, what do you mean?
Yeah, basically, they were saying you should always use the return, an early return.
And I'm like, exactly.
I would say the opposite.
Like, in some mentors have that opinion to like, there are rules for this to say, oh,
this could use an early return.
Yeah, I guess it does make sense if you're in a community where you've been trained,
where it's conventionally accepted to use early returns, because then people get used
to that.
Yeah, then you can spot them more easily.
That makes sense.
But it's also I think we need to change the way that we're writing code now to reflect
like, the number of people who are needed to read and write code compared to 10 years
ago or 20 years ago, the types of problems that we're solving are different to those
that we were solving 20 years ago and 50 years ago.
And I think there needs to be some like realization that like the things that were true then and
were good then maybe are not true and good in our current domain.
And that might be that might be one of them.
You brought up Ruby earlier, and I have done like Rails code in reading clubs.
And that's one of the ones where it relies on a lot of knowledge about Rails.
There's so much magic.
And it's fine if you're a Rails developer, right.
And the same with React as well.
People who come in a lot of times who are not as experienced developers, a lot of times
they're coming, I mean, coming to Code Reading Club, a lot of times they're coming from a
boot camp background, which means they probably did do React.
But when people are career changers, sometimes they haven't done React.
And that again, has the same problem.
They get really overwhelmed and tripped up on like, all of these like things that don't
appear to have a source.
They're not coming from anywhere that's in the file.
I mean, so again, that's another thing Elm is so explicit that it really lends itself
to that, like being able to process the whole thing independently of the context, which
is what the Code Reading Club is all about, which is what our brains can really only look
at one piece in isolation at a time.
So it's really great to have Elm in our lives.
So would you say that the experience of reading Elm code is positive in Code Reading Clubs?
Because often what I hear from people on podcasts or on the Elm Slack is like, oh, at first
I was afraid of the syntax or I was alienated by the weird syntax, which I have trouble
empathizing with or relating to.
So that's definitely a problem.
The very first time that I did Elm code in a club.
So people, so the rest of the people who are in the Code Reading Club, the company Code
Reading Club, are not Elm fans like me, right?
So I have to be very careful how much I keep bringing it in.
And also, like I said, it's not as fun to do Elm code because there's not as many things
to discover.
But yeah, the first time I did it, we didn't have the syntax exercise yet.
And it really, it really did stump people.
It really very much did confuse people.
And after that, I introduced a syntax exercise and it just unclear, like it clears some very
big cognitive black spots, I guess, for people who have never seen it before.
And once you've done that, then it's very easy for them to read.
Reason ML had a big change in their syntax, which is like a functional OCaml dialect that
compiles into JavaScript.
They made a big shift.
It's created by the same people who created React.
And they changed to C style syntax and rebranded as Rescript.
So they made a big decision to use less OCaml style syntax and more C style JavaScript style
So one of the things that that's reminding me of is that there's very few keywords in
Elm as well.
So you don't have those like function or funk or def or return.
And so if you don't know that, if you don't know that kind of very fundamental information,
again, it can be very confusing to look at.
And other thing that it reminded me of is there's a concept in Felina's Programmer's
Brain book, which is just brain concept in general, which is that if you try and transfer
knowledge from one domain to another domain, you can often make like a wrong assumption.
False friends.
Is that another pun?
No, maybe that's a way we have in French of saying that something looks like another thing,
but it isn't.
So it's a presumage of false friends.
Yes, false friends.
That's what I'm talking about.
I think the bad example that's popping into my brain is what happens if you put a coat
on a snowman that like people immediately will think it melts faster.
But most people with some science knowledge will then like after a second thinking, realize
that it like preserves the cold inside the coat.
But that is an example of where if you just assume that putting a coat on anything makes
it warmer, it's not true.
Only if you put it on a warm blooded animal does it make it warmer or the sun maybe.
I don't know.
That's how we use global warming.
Just put a coat on the sun.
But yeah, it can be a very fundamental.
You can imagine like in a practical science setting that that would be a very fundamental
like mistake to make at the outset.
And the same thing can happen if you misapply like a syntax, you know, a symbol in a computer
I think it was maybe rust that we were doing.
And there is some syntax which means like evaluate this thing, which looked like it
was doing something totally different, which confused a lot of people.
But yeah, if you use the same symbol in two languages to do different things, then that's
very confusing.
So Elm has very few operators, operator symbols mostly.
Does that help, do you think?
Because I would imagine that having plenty of operators is like one of the more complex
things to grok because it's not something you can pronounce as long as you don't have
a name for it.
So like if you have a like those weird Haskell operators that people do or the ones that
we did in Elm before custom operators got banned.
If you don't have a name to give to something, then it's harder to keep in your mind and
to assimilate.
Yeah, definitely.
And that's one of the very beginnings of Felina's research was about how you pronounce the things
that are on the page.
And it has a huge knock on in when you're like trying to discuss something with a remote
team or when you're trying to teach something to people, especially if their first language
is in English as well in programming.
That's a whole nother like landscape that we're not going to enter into in this podcast.
But that's where her research has moved on to now.
But yeah, so if one of her suggestions in that talk was to sit down with your team and
just agree the names of what you're going to call the operators.
And I was thinking at that time, I was already using Elm and I was thinking, wouldn't that
be amazing if that was part of the Elm docs, like this is how we pronounce these things.
And you're right, having a much smaller number, like having just a very tiny language to learn
makes it easier to read because you can master all of it in terms of like that chunking effect.
You can master that linking your long term knowledge with what you're seeing in the short
There's one thing that I do a lot when I'm writing Elm code, which is I write in like
closures and then I transform it into a pipeline because I know that it's going to be easier
to read in a pipeline, but it's easier for me to write in like inside out.
And one thing that I notice in my Elm code bases when I'm working with a team is that
people will choose like different styles of doing that.
And there's another operator that you can do away with parentheses, right?
If you do like the backwards pipe, I don't know what you would call it.
Yeah, left pizza.
Left pizza.
Is that like an official Elm?
It's pretty common, but it's obviously a little silly, but it kind of stuck and I don't mind
I'm not opposed to pizza.
There is an Elm review rule to forbid left pizza.
That's good to know because I find myself trying because I'm trying, I do a lot of like
new projects with new teams and I try and let people make their own mistakes and let
people do things in their own style.
And like, I try not to like step on it too much at the beginning, especially.
And that's one of the things that I always, I find myself sort of biting my tongue going,
please don't do that.
But I don't say it and I could justify it with it.
It does make it very unreadable.
It's like, especially if you're using right pizza and left pizza, like it's, I think we
need to lobby just to get rid of it.
Who needs it?
I think some people find parentheses hard.
If there are too many left pizzas in a particular expression, then it's definitely like, this
seems like a right pizza kind of expression.
Yeah, they both sound delicious to be fair.
They do.
This is the wrong pizza and the right pizza.
That's not, that's not cool.
I mean, you have two kinds of pizzas.
The one on the right has all the ingredients you like and the left pizza has pineapple.
That's how you should see it.
That's very controversial.
So do you want me to move on into the, like, I've kind of covered a little bit of like
code reading club, the whole, that's the whole, like the first time you look at a piece of
code with a group of people.
Those are the things that you do and at the end, hopefully you can start to summarize
what you think the code does because people through you, you would have had so many conversations,
particularly like in the important lines conversation where people start to articulate to other
people in the room.
The reason why they chose this line is because they think it's at the core of what this thing
is delivering or doing or operating, or they might've chosen it because it's something
which is something you need to watch out for.
So after you've done that with one group of people, you get the same group of people back
a week later or a couple of weeks later and you look at the same piece of code with all
of that knowledge behind you and you've told them now the context so they know where it
sits in like the wider world.
And some people then go and do a little bit more research in terms of like which other
things it's connected to.
You come back and then you do a little bit of warmup exercises on that and maybe like
on board people who weren't there at the last time.
And then you launch into thinking about what are the themes and concepts of the code.
And more interestingly, like my favorite, favorite ones are getting people to list out
all the decisions that got made by a person when they were writing this code.
So any decision, it can be like super trivial, like using left pizza, or it can be like very
complicated, like some kind of algorithm that they chose over another algorithm.
And then you just get list all those out.
And then you ask people to choose one or two of those decisions that you've listed out
together and think about what are the consequences of those decisions, like what has happened
because they made that decision.
And then you have like a whole conversation around that.
And then you think about why, why possibly like you're not going to know you weren't
there, but why might they have made those decisions.
And you can get some really interesting answers from people and like reflections from people
saying, oh, yeah, like when I first looked at that, I thought, oh, what idiot would have
done it that way.
And now these eight people in the room are telling me eight different reasons why that
like person who's not an idiot might have done it that way.
And it really gets you to think about not being judgmental.
That's awesome.
I love that.
Like honoring what the role the code has played and that it got its job done and that it came
into existence for a reason which you might not know.
Like I love that.
And I think that it really does better equip you to deal with code because as you're sort
of saying, like if you're assuming the worst about the reason it was written, like, oh,
my God, this this code is idiotic, it's gonna get you making assumptions instead of being
open to possibilities and like, well, what could how could this have come to be?
What might be behind this?
And it's going to give you a more open mind, which is going to empower you to navigate
that code better.
Yeah, definitely.
I mean, if you come into a situation and you're feeling like essentially what you're feeling
like angry about something being being wrong, right, then your whole like ability to reason
is totally clouded by that, as we know from other aspects of our lives.
Do you ever give code examples where you're expecting people to say WTF, like the XKCD
No, we don't.
We don't bait people.
Is that?
No, no, we don't.
We don't do that at all.
And also, we do like refrain from just calling things bad code, because it's just it's code.
So we do explicitly like set out at the very beginning of every single club that we're
not we're not here to talk about how good or how bad this code is.
We're here to talk about this code.
And code is a process.
Do you try to find ways to improve the code at some point?
Yeah, we do often like have that, what I was saying earlier, where somebody in the room
will say, oh, if I wrote it this way, it would be easier for you to understand.
And we have had a couple of sessions.
And I really want to do more of this, where somebody brings their own code to the session
and lets other people read it.
And here and here's how here's how people read it.
So there was somebody who brought like a piece of code that he thought was problematic to
understand because it was so complex when he was writing it.
And he did actually do a big refactor after he after he had that session.
So it was like really, really helpful, very helpful for him to like see, because we're
very limited in our scope of thought, right?
We have that tunnel vision.
So often it is the way that you can only see one one way of doing things.
And it really does open your mind to hearing other people's strategies and experience how
they experience stuff.
Katya, how has this influenced the way that you approach code?
And like, if you're coding day to day, like, how do you read code differently or navigate
code differently?
I'm much more of sort of forgiving of myself when I'm writing and reading, like when I'm
having a tricky problem, I think to myself, it's just because I'm missing a bit of knowledge
And I'm sure I can find that knowledge either here in this paper or by asking somebody or
by looking it up.
And so rather than just thinking, oh, I'm never going to be able to understand this
and walking away.
It's also so, you know, sometimes when you stare at something and this happens to me
and when I'm reading a book, as you know, a book, yeah, I'm reading words when I'm reading
English words, where you like reread the paragraph like five times, you just keep rereading it
and you still don't understand it.
And you keep rereading and you stare at it and they say like, that is something that
used to happen to me in code where I just like stare at the screen blankly.
And just you keep trying, you keep trying and then you just give up.
And what what's happened, what happens now is I start to think, well, how can I pull
this apart into pieces that I can try and understand rather than like getting into that
like terrible cycle of like reread, reread, reread.
So yeah, so I find that that is also the same thing that I that I do now when I'm reading
a book with a concept or something that I don't understand is like trying to identify
what are the concept, like what are the specific things that are stopping me from understanding
it rather than just keep reading it over and over and thinking that's going to solve the
So yeah, breaking things down into an awareness that there is.
It's been proven to me like time and time again, with like all different groups of people
with different skill levels in programming and different mathematical levels and different
linguistic levels and different languages like people.
Now that we do the code reading clubs online, like people come from all over the world and
participate and it has proven to me that every person in the room is like able to, even if
they were to do these exercises independently, get more understanding than they did when
they walked in the door and saw the piece of code, which when you first look at it,
you think I'm never going to understand this.
And you can if you just take it one piece at a time.
If somebody wanted to get involved and start attending some code reading clubs, what's
the best place to find out more and find a good place to join?
I would say our website, but it's in the middle of a rewrite at the moment.
So there's not very much information on there because we took everything down and just put
the very minimum up and it's too minimal.
By the time this comes out, I can try and put a little bit more on there.
But Discord is probably the best place.
We have a code reading club Discord and then you can like ask specific questions.
What our intention has always been to help people set up their own clubs.
So we used to do on the first Tuesday of every month, this like international online club
and then got to be too much for us to do that on top of like also running in person.
Like once the pandemic is well behind us now, there's more in-person stuff happening as
well and it's just too much to promise to do that.
But we do do those occasionally.
And the other thing that we found with those is that they're more like tasters.
So you come along and like if everyone in the in the session has never done code reading
before, then you're mostly teaching the techniques.
Whereas if everyone in the session has done it before, then you're actually reading the
code together.
And so we're trying to rework our like the way that we invite new people into code reading
to like you have to do an intro session and then you can join like a regular club.
But we haven't quite designed how that is going to happen.
But definitely like if you want to start one or if you want us to come and facilitate one
in your workplace, we will do that and then help you like help you get your own club started.
But there's a we have a GitHub as well, which is called Code Reading Clubs, I think.
And that has resources that you can use to start your own.
But again, that's another thing that we're working on making it more easy, easier for
people to come into.
So did that answer your question?
We will link to all those resources and people can jump into the Discord and say hello.
And amazing.
Well, this was a lovely conversation.
Thanks so much for coming on, Katya.
Thank you.
Yeah, thanks for having me.
I really enjoyed it.