When teaching “programming”, a surprisingly small amount of time is spent actually helping students with logic – and a lot helping them learning & managing programming tools.
Programmers like to think that they spend all their time creating elaborate & complex abstractions but far more time is consumed dealing with the tools and idioms encrusted with historical baggage.
What’s the Problem?
In my experience teaching programming, we spend very little time helping students actually write code. When they first get started, there’s a while when they’re learning “algorithmic thinking” and again when they’re learning new languages or paradigms that we’re helping specifically with figuring out the logic & programming qua programming, but for a course on “learning to code”, code itself doesn’t rank too highly on what they need help with.
Instead, the mentors mainly deal with problems of tooling – “it says ‘EADDRINUSE’ and crashes”; “git is giving an error”; “npm just says segmentation fault”. This is in a program that does its best to eliminate issues of configuration, where all the students use a standardized editor and work in a VM to keep the environments homogeneous. How much worse will it be then, for people trying to learning without the benefit of this setup? There’s a lot of rhetoric around “everyone should learn to code”, but how feasible is that if people need to navigate arcane labyrinths before they can even get started?
Experienced programmers tend to gloss over how much of their jobs are tool-wrangling. We like to have an image of ourselves as these brilliant conceptual artists, weaving algorithms and data structures, holding hugely complex structures in our heads. While there are some positions that allow living at this level of abstraction, I would wager that the vast majority of working programmers spend far more time wrestling with weird tooling issues incidental to actually writing code.
Some Specific Examples
Some broad categories of annoying tool stuff:
Using the Terminal
For most non-Windows developers, a giant amount of time is spent using the terminal. Unfortunately, doing anything in the terminal is, if not a struggle, something very new to most beginning programmers.
I frequently see students move to directories by repeatedly
cd-ing one directory deeper (instead of doing a single
cd dir1/dir2/dir3 command), not being aware of tab-completion, being confused why they can’t click on the line to move the cursor around, and many other things.
How Do I Quit?
A whole sub-category of terminal challenges is quitting the various programs.
Everyone likes to joke about “how do I quit
vim?”, but that’s a real problem for students when the default
$EDITOR is set to
It’s not just
vi though – students need to know that
Ctrl-C will interrupt most things,
Ctrl-D will stop some other things,
q will exit the pager,
\q to quit PSQL.
A fun one some students run in to using accidentally discovering
Ctrl-Z to suspend the process, which to them seems like it’s the same as quitting.
This can lead to some very weird issues, especially when they think they’re quitting their server, but now they have a bunch of copies running in the background.
It’s become a cliché that git is inscrutable, for a good reason.
This is an area where I know that my level of experience with git works against me when trying to help students. I’ve been using git purely from the command-line for so long that I feel very comfortable with it, not to mention spending a lot of time reading about the implementation details. This leads to the problem of trying to teach something when you don’t remember what it’s like to not understand it at all.
I think the students would be better served if they learned to use git using GUI tools, at least initially, but that would be an anathema to the dev culture. One could argue that GUI tools don’t expose all the functionality of git, but guess what? The command-line interface doesn’t really “expose” it at all either – you need to just know about it. At least with a GUI, users can see the buttons and a visualization of the commit graph to get a sense of what’s possible.
I love using Emacs and vim, but I can’t really recommend them to students. There’s so much to learn to just get the basics working, not to mention actually taking advantage of the real power of the editor.
Where I teach, students use VS Code.
That’s still a very powerful editor, but students have no real idea how to take advantage of it.
When I tell students about
Ctrl-p for jumping to files, something I would consider the absolute basics for using VS Code effectively, their minds are blown.
Discoverability is a very hard user-interface problem, no doubt about it. Like most expert tools, programming text editors generally make a tradeoff to be more powerful for experts at the cost of being less easy to get started with for beginners.
“React Week” is always rough for teaching.
Previously, when we were still on class-based React, it was weird, because students had to learn about ES6 class syntax, which adds a whole new bunch of weirdly non-orthogonal syntax. That was rough, but hooks are even more challenging.
I happen to like the hooks-based approach to React, since I come from a background of using React via Clojurescript (using Om originally, now reagent/re-frame). However, if one isn’t already used to a functional style of programming, it’s another giant thing to learn.
It is so hard for students to learn to use hook-based React correctly when it seems to work for so long doing things “wrong” – i.e. directly mutating state vars, or doing unsafe state updates (e.g. referring to the render value of state when setting the new value). Students write a bunch of code, things seem to be fine – it works, no errors or warnings – but then they add some other change, which causes things to start failing in very confusing ways – updates get silently lost, things don’t get re-rendered – and students don’t know why.
At least they have
create-react-app to streamline getting started – if they had to learn to use webpack, babel, et cetera before they could learn React, there is no way they would get anything done.
Even that has its strange issues though.
One of the most frustrating is when its auto-building stops working, so students are making changes and, as far as they can tell, nothing they do works – because their code isn’t actually running at all!
If students just had to deal with one or two of these things, it would be okay. All disciplines have their tools and practices you need to learn that are somewhat ancillary, but that’s just a consequence of specialized tools.
However, with programming, there’s this infinite fractal of new weird things you need to deal with – there’s a reason the term “yak shaving” comes from programmers, not machinists. When people are trying to learn programming, but there’s this never-ending rathole of baffling tooling things that bite them, it’s really easy for fatigue to set in and people to get very discouraged. It’s so disheartening when everything they do leads to more incomprehensible hassles that become conditioned to avoid learning their tools in depth; just get the code working, don’t try to dig more into why things work or how to do them more effectively.
What Should We Do?
I’ve long thought that a really useful course would be not necessarily about programming, but about how to use your computer like a programmer. It often seems like that’s really the biggest skill we develop – not algorithmic thinking, but having a deep knowledge of how to use the computer just to do stuff.
Is it a failing of us as developers of software, that people need to be experts just to use the basic tools of the trade?
I’m not sure.
There is a good amount of essential complexity in many of the tasks, but it certainly could be made much easier. As I’ve written about before, I fear that there’s some kind of pride in accomplishment that makes programmers not really want to make things that much easier. They had to put a ton of effort into learning how to use these tools and if they became much easier to use, it feels like all that effort was a waste.
I suppose it might be a generational change – as people today start learning to code with tools like Glitch, perhaps their diminished tolerance for the kludgey tools of today will lead to better things. Developers today do seem to generally prefer more user-friendly things (interpreted languages, graphical tools), although there absolutely still is a pretty strong contingent of people that advocate for a reversion to a “simpler” way of doing things – use C instead of “high-level languages”, advocate against syntax highlighting, etc.
Some things that I’m trying:
- Reassure people that it’s not unusual, or a failing of theirs, to waste a bunch of time on weird tool issues
- Do my best to gently & gradually introduce new features & functionality to students – don’t throw a ton of stuff at them all at once
- Don’t be dogmatic about the “right” way to do things – e.g. “Real Programmers only use git from the command-line”
But these things are all bandaids. How can we make programming actually about programming? Is that even feasible?
At any rate, I think that if we’re cognizant that this is a problem, we can try to gradually make things better for the next generations of programmers.
One can dream…