melreams.com

Nerrrrd

Let’s play CPU!

white ferris wheel against a blue sky with a few wisps of white clouds
Unrelated image from pexels.com to make this post look nicer in social media shares.

I think one of many reasons it’s so hard to learn to code is that the people doing the teaching have all forgotten what it was like not to know how to code, so we skip over some really important basic steps because we think they’re inherently obvious. Case in point, this poor redditor who nobody ever taught how to work through a piece of code with a pencil and paper. I had to read the question a couple of times to understand what they were even asking, it just didn’t occur to me that someone wouldn’t know how to trace through code manually.

The example that user posted was “x=0; y=0 While (x<7) { x=y-x; y=x+x; x= x+ y + 1;}”

First of all, let’s clean that up a little:

x=0;
y=0;
while (x < 7) {
    x = y - x;
    y = x + x;
    x = x + y + 1;
}

In the beginning x is 0, which is definitely less than 7 so we enter the loop.

Inside the loop, take each statement and swap out the variables for their current values and then do the math and put that value in the variable:

x = y – x becomes x = 0 – 0 becomes x = 0
y = x + x becomes y = 0 + 0 becomes y = 0
x = x + y + 1 becomes x = 0 + 0 + 1 becomes x = 1
At the end of the loop x = 1 and y = 0

Now we check the condition at the top of the loop again and x is still less than 7 so we go through the loop again

x = y – x becomes x = 0 – 1 becomes x = -1
y = x + x becomes y = -1 + -1 becomes y = -2
x = x + y + 1 becomes x = -1 + -2 + 1 becomes x = -2
At the end of the loop x = -2 and y = -2

At this point, I’m getting very suspicious this loop will never exit. I don’t think x is ever going to be greater than or equal to 7, but just to be sure let’s go through the code one more time

x is still less than 7 so we go through the loop again

x = y – x becomes x = -2 – -2 becomes x = 0
y = x + x becomes y = 0 + 0 becomes y = 0
x = x + y + 1 becomes x = 0 + 0 + 1 becomes x = 1

At the end of the loop x = 1 and y = 0. These are the same values we had after we went through the loop the first time, so now we can be completely sure the loop never ends. After each time through the loop x is either 1 or -2, there’s no way for it ever to be 7 or more.

That’s it. Working through code with a pencil and paper is just keeping track of what values all of your variables have and swapping out variables for their values. It’s really tedious, that’s why we make computers do it :) And to be clear, you’re never expected to be able to work through complicated code like that purely in your head. Everybody else needs a pencil and paper too, there are just too many details to keep them all in your working memory.

Okay, so if working through code with a pencil and paper sucks so much, why does anyone do it? Because it gives you a really solid understanding of what the computer is doing, which you’ll need later when you start building more complicated things. For a simple loop like the one above you can just throw that snippet of code into an IDE, run it, and see what happens, but you can’t even start building bigger things without a foundation of knowing what the computer is doing when it runs your code.

Repetition is underrated

a brown-skinned woman wearing a dark blue top and a white skirt plays an electronic keyboard
Loosely related image from pexels.com to make this post look nicer in social media shares.

The more I read about the struggles beginner programmers have and the more I mentor at Ladies Learning Code workshops, the more I think that repetition is seriously underrated when it comes to teaching anything technical.

When you’re learning a language or an instrument or a sport or a physical skill like plumbing or carpentry or even math, which is similar to programming in a lot of ways, you expect to have to repeat the same thing multiple times before you remember all the details and get it right every time, but somehow when you’re learning to code we assume you should only need to be told how a for loop works once and you’ll understand it perfectly right away and remember it forever. That’s just not how our brains work and that’s why I think repetition is so underrated.

It is completely normal to need to write a lot of for loops before you get it right every time. Some people do pick up programming concepts very quickly but that doesn’t mean you’re dumb or abnormal if it takes you longer. Something like a for loop (or anything programming construct) seems simple once you understand it, but there are actually an enormous number of fiddly little details you have to keep track of to get your loop to work. You know what’s a great way to learn all of those details so thoroughly you hardly even think about them anymore? That’s right, repetition!

Programming isn’t just a matter of understanding the concepts, you’ve also got to learn them so thoroughly you don’t have to think about how to write a loop, you just write one when you need it. Without that thorough of an understanding, programming is like trying to speak another language by looking up each word individually in your [other language] to English dictionary. That’s one way to learn, but you’ll probably just be miserable and frustrated and forget what you were trying to say in the first place before you’re even halfway through your sentence.

Come to think of it, maybe the kind of drills you do when you’re learning a language could help people learn to program without spending so much time worrying that they’re just not smart enough.

Anyway, repetition is seriously underrated and I wish we collectively talked more about how much practice it takes just to pick up the basics of programming, let alone the complicated stuff like deciding how to structure your code or what to name things (still one of the hardest problems in programming :) ) I think a lot of programming tutorials assume that you know you need to practice without explicitly saying it or without making it clear just how much practice you need. I have to admit I wouldn’t want to write pages and pages of very similar programming exercises either, but it’s not so hard just to say that programming takes practice and you’ll probably need to go through the tutorial a few times before it sticks.

If you did a tutorial or a workshop just once and didn’t instantly become a good programmer, congratulations, you’re normal! If you keep at it, you’ll get there.

The wall

Unrelated image from pexels.com to make this post look nicer in social media shares.

I was talking with a friend who’s learning to code the other day, and the subject of the wall came up. Not the one that keeps the wildlings out, the one everybody slams into when they’re learning to code. Learning to code starts out great, there are so many tutorials that break things down really clearly, but once you’ve got a handle on the basics and want to move on to building your own projects, that’s where you hit the wall. It’s a huge leap from following tutorials where all the hard decisions are made for you to building your own projects with no one standing by to tell you where to start or what database to use or what your UI should look like.

The single thing I most want you all to know is that hitting the wall is normal. It happens to everyone. It absolutely does not mean that you’re dumb or not meant to be a programmer or that you’ll never get over the wall.

As a bit of an aside, I think the number of beginners who hit the wall and assume they’re just not smart enough to be programmers says more about how bad we collectively are at teaching programming than about the intelligence of anyone who hit the wall and walked away. I’m suspicious there’s a connection between how easy it is to write total beginner tutorials and how many of them there are, and how much harder it is to teach people to break down a problem and how few tutorials there are for that.

But anyway, I have some ideas for people who have hit the wall or who can see it in the distance and are getting worried.

One of the coolest things about programming is how many open source projects there are. Find one that you like and take it apart to see how it works. Search for text from the UI in the code and see if you can change it. Throw log messages all over the place to make the code show you what it’s doing. See if you can find some constants in there you can mess with. And don’t feel left out if you want to make games, those can be open source too.

Once you’ve found a project you like and have some idea how it works, see if you can change how it works. Let’s say you found a simple todo list app. Can you add due dates to your list items? Or subtasks? Could it play a sound and/or an animation to congratulate you when you check something off? Could you add a new feature like recurring tasks or email reminders? If you don’t have an open source app handy, just take a tutorial and mess with that.

Speaking of tutorials, if you do enough of them you’re going to start seeing similarities. Most apps have some sort of UI, some sort of data model, maybe a way to save that data for the next time you open the app (that’s pretty advanced, though, don’t worry about it right away), some logic about what users are allowed to do (like due dates can’t be in the past or players can’t have more than x hitpoints no matter how many health packs they use), maybe some communication with other APIs (but again, that’s advanced, don’t worry about it right away), and honestly, that’s pretty much it.

You can try mashing up different tutorials or open source projects too. Let’s say you have a tutorial for a driving game and one for a game where you run around and collect coins or stars or whatever. What if you could drive around and collect stars? What if you had tutorials for a todo list app and a weather app and mashed them up to make a little morning dashboard for yourself?

Don’t forget, you don’t have to do it all yourself. There are great communities like CodeNewbie, /r/learnprogramming, CodeRanch, (and lots more if you do a little Googling) full of people who will help you out.

Dev tool of the day

Exercism is a tool that lets you download and solve practice problems in over 30 different languages. I mentioned it in passing before, but let’s talk more about why it’s great.

First of all, each problem in Exercism has a set of unit tests, so you don’t have to wonder if you’re doing it right, you can just run the tests and know for sure. The tests are also great for experimenting with your code and seeing if you can make it easier to read or easier to change without breaking it.

The problems are also carefully chosen to help you learn concepts that are important to each language. Just because you can solve a problem in a certain language on a coding challenge site like HackerRank doesn’t mean you’re learning anything interesting about that language in particular. I know that’s not really what challenge sites are meant for, but I’ve seen them recommended to a lot of people who are learning and think it’s important to be clear about what challenge sites are good for (general programming concepts) and what they aren’t necessarily good for (learning individual languages).

And finally, Exercism directly incorporates both giving and receiving feedback. Obviously getting feedback is helpful – to directly quote the Exercism site: “You can write FORTRAN in any language, as the saying famously goes, but with enough feedback, you’ll quickly find yourself writing the language the way it wants to be written.” – but giving feedback is seriously underrated. To tell someone what you think of their code, you have to read it carefully and then think seriously about what makes code good or bad. That’s enormously helpful when you’re new and don’t really understand what “good code” means yet, or when you’re new to a language and just don’t know the best way to do things in that particular language.

Give Exercism a try!

Do you have to be good at math to be a programmer?

Slightly related image from pexels.com to make this post look nicer in social media shares.

One of the most common misconceptions I’ve heard about programming is that you have to be a math whiz to be a good programmer. I’ve mentioned this before but I want to attack that particular stereotype more directly.

It is true that there are similarities between math and programming – programming uses some math terms like function and variable, it’ll be a lot easier to get things onto the screen if you understand coordinate systems, and of course to do math or programming you spend a lot of time manipulating symbols and thinking abstractly, but you know, programming is also a lot like language. I mean, they call them programming languages for a reason. To quote Hal Abelson, Jerry Sussman and Julie Sussman’s book Structure and Interpretation of Computer Programs:

First, we want to establish the idea that a computer language is not just a way of getting a computer to perform operations but rather that it is a novel formal medium for expressing ideas about methodology. Thus, programs must be written for people to read, and only incidentally for machines to execute.

Programming is fundamentally about communication. Not only are you communicating with the machine, you’re communicating with your future self, the rest of your team, and potentially other teams if you end up working for a large enough company. And that’s just when you’re writing code! You’ve also got to make sure you’re building the right thing and let other people who are waiting for that thing know how it’s going. You know what’s great practice for communication? That’s right, English classes! Sarah Mei has a great blog post about the same point I’m trying to make in this one, here’s an especially interesting quote:

The students I saw – all adults – came from a wide range of backgrounds. People with a math background did fine, of course, but people with a heavy language background often did better.

Nobody seems to have an official study on this, but I think there’s something there. Language requires just as much abstract thought as math does, with the added benefit (to your communication skills) of failing your classes if you can’t make yourself understood to anyone else. As a bit of an aside, the biggest problems I’ve run into at work have never been problems of pure programming skill (although those ones do suck a lot), they’ve been communication problems with team members, other teams, management, other departments entirely and other offices.

And to stick another nail in the coffin of the idea that programming is math, I’ve been a developer for ten years now and the most complicated math I’ve ever had to do at work is stuff like “if I have a div that’s x pixels wide and y pixels tall and I want it centered inside another div that’s a pixels wide and b pixels tall, what should my margins be?” I used to believe that programming was math, and some programming is certainly math heavy, but it’s hard to argue with the lack of math in my day to day job over ten years and four companies.

So given that programming is not math, why do so many people think it is? I’m going to quote Sarah again because she already said it really well:

When programming was just getting started, early in the last century, we used it to solve highly mathematical problems like calculating missile trajectories and decrypting secret messages. At that point, you had to be good at math to even approach programming. Tools, such as programming languages, were designed specifically to solve mathematical problems, because those were the ones we thought it was worth spending money on. Computers were for doing math.

I think another issue is the way we teach programming (credit where it’s due, I stole that idea directly from a comment on Sarah’s post). Computers are great at doing boring and tedious calculations, plus it’s easy to tell them how to do it, so why not start teaching programming by having students make the computer calculate something for them? It makes it really easy for the students to check their work too – assuming they’re able to do the math problem themselves, they can easily check if the computer got the same answer.

That assumption can be a real problem, though. If you can’t do the math problem or don’t care about the math problem, you end up effectively shut out of programming, something you could very well be great at, because of something that has next to nothing to do with the actual job of software development.

If you can do basic arithmetic and deal with the concept of variables, congrats, you can be a programmer! That is literally all the math you actually need!

Why not start with an IDE?

Unrelated image from pexels.com to make this post look nicer in social media shares.
Unrelated image from pexels.com to make this post look nicer in social media shares.

In college our first Java classes used a text editor (TextPad), not a full featured IDE like Eclipse, and compiled and ran our programs from the command line. When we finally started using Eclipse, I was kind of pissed off that we’d spent so much time slowly and painfully debugging our code when Eclipse could’ve just told us exactly where the problem was. Knowing what I know now, I totally understand why our teachers did it that way, but I don’t remember anyone doing a particularly good job of explaining it at the time.

For anyone out there wondering why on earth they have to do things the hard way when they could just use a tool that makes things so much easier, the answer is that the tool doesn’t actually make things easier.

It sure seems like it does once you’ve got the basics of coding down, but until then it’s just another complication that you really don’t need when you’re already trying to learn something extremely complicated. Take this question I found on reddit for example: you can have perfectly good code but be unable to run it because your IDE isn’t configured correctly. IDEs are powerful tools, and any powerful tool can hurt as much as it helps. If you already know how to write code, compile it, keep track of your files and build path and everything, then IDEs are great. If you try to learn all those things plus how to use an IDE, how to set it up, and how to recognize and fix problems with your configuration if you mess something up all at the same time, you’re going to have a bad time.

You know how your teacher always said to add one a thing at a time when you’re writing code so that you know what caused it if something breaks? That counts for tools, too. If you’re not already good at tracking down what’s wrong with your code, you’ll have a terrible time figuring out whether your code is actually wrong or whether your IDE isn’t configured right.

IDEs can also hide stuff from you that you actually will want to learn, even if it’s a pain while you’re learning it. With java in particular, an IDE can make it seem like you just write code and it runs by magic. That’s not helpful once you start working on projects that need to be run outside of the IDE. You will need to know how to compile your code, what settings you need to get the right output, where that output ends up, and how to use/deploy the compiled code, none of which you’ll learn by hitting the run button in Eclipse.

I can even see the point, as infuriating as it was at the time, of making students manually find issues like missing semicolons without the help of an IDE. The level of attention to detail you learn by finding your own missing semicolons is absolutely necessary to track down the kind of subtle logic errors an IDE can’t help you with. I don’t believe there’s any way to learn that without spending a lot of time being very very frustrated, but it’s an extremely useful skill and one that every programmer will need sooner or later.

If there’s a better (and less frustrating) way to learn to program I’d love to hear it, but I’d be very surprised if there’s a non-frustrating way to learn a fundamentally frustrating skill.

Talk of the day: Be Awesome By Being Boring

Because I’m a Katrina Owen fan, I’ve watched a bunch of her talks. Recently I was watching her talk on Therapeutic Refactoring (it’s great and you should watch that one too), saw that it was from Cascadia Ruby Conf, and decided to see what other talks from that conference were recorded anywhere. One that grabbed my eye right away was called Be Awesome By Being Boring by John Hyland.

The gist of his talk is that “boring” (stable, commonly used, not shiny and new) technology is awesome because you can trust it, you can get help when you need it, and you can focus on building something useful instead of fighting with your tools.

Even if you’re a beginner programmer and nowhere near ready to worry about whether your production database is going to crash, it’s still good advice. Well known, commonly used tools are way easier to learn because they’ve been around long enough to have docs written for them and to have the majority of the bugs worked out of them, they’ve been used enough that somebody else has probably run into the same problem and asked about it on stackoverflow already, and because so many people use it, even if your exact question hasn’t been asked already somebody out there can answer it.

For example, take a look at the number of questions tagged Java on stackoverflow versus the number of Kotlin questions. When I wrote this post, Kotlin was closing in on 4k, where Java had 1.1 million. I’ve heard good things about Kotlin and I’m not saying it’s a bad language to learn, just that you’re going to find answers a lot more easily with the language that has over 200 times more presence on stackoverflow. Not that stackoverflow is the be all, end all of programming language popularity, but I think it’s a decent measure of how many people are using a language.

Be awesome by being boring, it’ll make your life easier!

There’s always something else to learn

Unrelated image from pexels.com to make this post look nicer in social media shares.
Unrelated image from pexels.com to make this post look nicer in social media shares.

Not long ago I read this blog post Why Learning to Code is So Damn Hard, which makes a really interesting point about the “desert of despair” between beginning to learn to code and having the skills to build a complete project on your own. The desert of despair, according to the post (which I agree with) is a combination of lack of resources for learners who are between beginner and expert, and having learned enough to know how much you still have to learn. Many aspiring coders get lost in the desert of despair and never find their way out.

I also read Amy Hoy’s post 5 Things I Wish Somebody Told Me Before I Founded My SaaS. One of the points I found the most interesting was that there’s always another inflection point. By inflection point, she means “those knife-edges you tip toe along, when things could go either way, when you are, say… trying to grow your team but lack the time/revenue to do it, but growing your team would help increase the time/revenue to the point where you could grow your team. Ouch. To me, that’s the prototypical inflection point.”

Where this ties back to the other post is where Amy says “Over the last 8 years running this biz, I have said so many times: “We just have to get through this $INFLECTIONPOINT and then things will get easier.”” Doesn’t that remind you of programming?

If I can just learn enough to get my code to compile then things will be easier.
If I can just learn enough to add a feature to an existing project then things will be easier.
If I can just learn enough to start a project on my own, then things will be easier.
If I can just learn enough to break my code down into good methods, then things will be easier.
If I can just learn enough to break my code down into good classes, then things will be easier.
If I can just learn enough to break my code down into good layers, then things will be easier.
If I can just learn enough design patterns, then things will be easier.
If I can just learn this new framework, then things will be easier.
If I can just learn this new style of programming, then things will be easier.
If I can just build enough different projects, then things will be easier.
If I can just learn enough…

There’s always going to be something else to learn, it’s never going to become easy and stay that way. Things do get easier once you find your way out of the desert of despair, but initially learning to code just leads to worrying about whether your code is good leads to worrying about design and architecture and scalability and reliability and security and those are seriously hard problems.

Despite how it may sound, I’m actually not trying to say that coding will suck forever and you should just give up. I’m saying that it’s normal to feel like you still suck at this even after years of working as a programmer. You don’t actually suck, it’s just normal to feel that way. What’s really happening is you’ve levelled up. When you do that you see the problems that used to give you trouble as too simple to count and focus on the stuff you aren’t good at yet, which can easily make you think you suck.

The thing I struggle with is design. I’ve been at this for ten years now and I’m still never sure if I’ll regret the design I’ve come up with the next time we add a feature to the system. Plenty of times I’ve come up with something that seemed like a good idea at the time, only to find out that it had serious flaws when I came back and changed it later.

It’s tough sometimes but on the upside, you will never ever run out of things to learn as a programmer :)

Learning How to Learn

I’ve been kind of skeptical about MOOCs (massive open online courses) for a while, but I took the Learning How to Learn course on Coursera and it was actually really good. Turns out there is free stuff that doesn’t suck :)

Photo from create her stock

Like any free resource, some MOOCs are great and some are… not. On the upside, the fact that they’re generally free (although some sites charge for a certificate of completion) means you aren’t out any money if you didn’t learn anything or were too bored to finish. The only problem is you’ll waste a lot of time if you’re too stubborn to give up on a course that’s not interesting. Do as I say, not as I do and all that :) I’m currently stubbornly hoping that I’m actually going to learn something in a very vague and high level software architecture online course I’m taking. Maybe it’ll get good in week 3?

The Learning How to Learn course, aside from being interesting on its own, is also a good example of what other courses should probably be doing. It teaches you specific concepts that you can actually go out and apply to whatever you want to learn right away. Some of the most useful things I learned in that course were the pomodoro technique and the fact that part of procrastination is that the brain reacts to a task you don’t want to do the same way it reacts to physical pain (at least, that’s how I remember it) but that if you can hang on through the initial pain, it goes away pretty quickly.

As a software developer I have to learn new stuff all the time, and because I’m totally irrational sometimes I worry that the thing I need to learn this time might finally be the thing that proves I’m just not smart enough. The Learning How to Learn course makes learning sound much less scary. Instead of learning being this mysterious thing that some people can do and some people just suck at, the course breaks down the process of how the brain makes sense of and stores new information. Learning is actually a simple process of repetition, chunking, using different modes of attention, and managing your time, it’s something anyone can do if they put in the time and effort and have learning materials that make sense to them.

It also has some tips for taking exams that I wish I’d had when I was still in college. If you have any important tests in your future, the course is worth taking just for the exam tips. I’m guessing here because I don’t have test anxiety, but I think it would be really helpful to have a simple plan to follow when your mind goes blank.

Learning about different modes of attention is also really useful for when you’re working on a really difficult bug. It’s hard to step away when you’re convinced you’ll get it if you keep trying (especially when the total refusal to give up is a pretty central programming skill), but taking your mind off the immediate problem really does help your brain to make the connection you need to solve it. When you’re too focused on a problem, your brain sort of sticks to the information you already have. When you take your mind off of it and think of nothing in particular, your brain can start making connections between things that didn’t seem to be connected at all and that’s where those sudden eureka moments come from.

The course is based on a book by one of the professors, A Mind for Numbers: How to Excel at Math and Science (Even if You Flunked Algebra). As much as I love books, I’d actually recommend taking the course first, because being tested on the material helps you learn it (a concept you’ll learn about in more depth if you take the course or read the book :) The due dates in the course also helped persuade me to make time to sit down and do it. The course also has transcripts for all the videos, so if you prefer reading to watching you’re covered.

If you want to learn things faster with less effort or you’re just interested in how your brain works, take the Learning How to Learn course.