Matthew DiLoreto

A place to keep track of some of my things.

Problems with Programming Books

My girlfriend’s sister is taking her first programming course using an “interactive” online textbook (a Zybook) for school, and I offered to tutor her.

When she needs help, she usually sends me 3 pictures:

  1. The text of the problem statement,
  2. Her python code, and
  3. The error message (there is almost always an error message).

I then decipher what exactly the question is asking for, what the error message says, what her code is doing, and finally write up an explanation to help her understand all of it.

Sometimes it’s easier to facetime.

Throughout this process I’ve maintained notes about what trips her up, because it’s been so long since I started programming that I don’t actually remember what it was like not to know these things. I’ve come to the conclusion that programming “books” (usually a hypertext document consisting of long passages of static text followed by graded problems) are seriously flawed.

My perspective is also colored by my personal experience with codecademy circa 2014, and later in 2019, as well as a few other courses from college (the names of which I cannot recall), so a lot might have changed in some of the better tools, but I’m certain there’s a lot more that can be done.

The main ingredient they all seem lack is interactivity.

Any fan of Brett Victor will know the importance of interactivity, but for the unitiated, allow me (him) to enlighten you:

(Seriously, watch the video from Brett, and read this essay too while you’re at it. The ideas he presents are wonderfully simple. I guarantee they will leave a lasting impression.)

What interactivity does for a first-time programming language learner is remove barriers. A good programming book empowers her to find answers to her questions on her own. It provides endless contextual information for every part of the interface, code, and errors (no, not just some static textual explanation of the topic at-hand 5 pages up in the document). The fewer buttons she has to click to see a result, the more help she has decoding an error message, the more likely she is to keep going, and keep coding.

I boiled down my experience tutoring to a few areas for improvement for a truly interactive programming book.

Language-specific Ergonomics

Let’s start with something programming books usually get right — isolating the beginner from the technology.

As software developers, we love tinkering on the command line. We like to connect services and write scripts and run test suites and version control source code files. We like to be in control of a system.

This is anathema to the first-time programming language learner.

A beginner should not have to set up anything. She should be presented immediately with the opportunity to read, execute, and write programs without any effort. Most books at least solve this problem by providing code execution tools (a bare text-editor and a “RUN CODE” button usually) from the browser, and some tools like repl.it are doing very cool things in this space.

I do think there is more work to be done regarding in-context documentation of language features, though.

Partial Results

One thing I wish more books emphasized is the substitution model of programming. That is, the iterative process of substituting subexpressions for their results to make up larger results in a program, e.g;

(+ 1 (+ 2 3))
; becomes
(+ 1 5)
; becomes
6

Technically this model only applies to expressions, so in a language like Python there are exceptions, but the same basic principle carries over at least somewhat in every programming language, and it is not an obvious principle.

It’s not obvious to a beginner that:

age_input = input()
age = int(age_input)

is exactly the same as:

age = int(input())

unless she is explicitly told so. But the abstract knowledge does not stick immediately, because she will then balk at:

names = input().split()

The code editor should show the results of each part of chained method calls, and of each subexpression in an expression.

As a side note, when describing the previous example I was asked, “How come it isn’t”:

ages = split(input())

What a good question, and the explanation will be completely incomprehensible to a beginner:

“Well in Python everything is an object (except for primitives), and those objects have methods, which are really just functions whose first argument is always the object instance itself. Isn’t programming fun?”

This is a huge WTF for beginners, and I remember spending hours googling “what is an object in programming” when I first started to code. It’s irrelevant to teach a beginner these things, but languages like Python force this confusion from the start.

That’s why How To Design Programs uses a Lisp as its teaching language. Any syntax is overhead which distracts from the essence of programming.

A good interactive programming book might not want to teach Lisp, but it should give insight into the results of each part of every expression.

Error Messages

This is what infuriates me about every single book I’ve come across — they all forward the bare error messages from the interpreter/compiler/VM/whatever straight to the user. This in and of itself is not really an issue since becoming familiar with error messages is a part of software development, but the problem is that they all stop there.

What do software developers do when they get an error message? Well, it depends on the error:

Syntax errors:

My IDE catches this in context AND usually provides a quick fix. A beginner is already used to this common paradigm (e.g. spellcheck). There is no reason for any programming book not to have this feature (Zybooks does not have it).

Runtime errors:

StackOverflow. There is no avoiding the value of google-searching the error message. I would like to see a book that does this on behalf of the user, suggesting a search whenever an error occurs; or preferably suggesting a useful search from a previous user of the book i.e. a post which solved this specific error in this specific graded problem.

One error message is usually tolerable, but it’s when the beginner tries 2, 3, or 4 different things, and gets different errors that she quits. My role as a tutor is essentially an error explainer. I explain what the error means generally, then what it means in this context, then why it happened in this context, what line of code is really to blame (you got a SynaxError on line 11 because you forgot a : on line 10), and finally prompt with a leading question toward a solution (or just give the solution if it isn’t obvious). There’s no reason the book can’t do a lot of this work, especially considering it is a document visited almost exclusively by beginners who generate and ultimately resolve the same errors over and over again. There is opportunity to leverage the book’s data collection to help solve this problem.

Case Analysis

This is where the actual programming work begins. Alan Perlis famously said:

Programmers are not to be measured by their ingenuity and their logic but by the completeness of their case analysis.

The problem is that it’s very difficult for beginners to differentiate between errors due to incomplete case analysis and “programming” errors (like using the wrong variable, forgetting a +1 somewhere, etc.)

Software developers write tests in order to increase their confidence in their case analysis, and run those tests when the relevant code changes. Beginners do not write tests, because they do not yet know the value of doing so.

Most books I’ve come across usually provide some mechanism for user-supplied inputs, and typically include a short test suite for graded problems, but this is not enough. Books should provide this list of cases and run the tests whenever the code is updated. The beginner should know immediately whenever one of her changes influenced the outcome of a test case.

The book should also provide test cases for the functions relevant to a solution, i.e. I should be able to hover over `pow` in some Python code and see:

pow(2, 2)  # -> 4
pow(2, 3)  # -> 8
pow(2, 4)  # -> 16
pow(3, 3)  # -> 27
# ... etc.

So far I have not come across any books which have immediate feedback like this.

Exploration

This is by far the most important aspect of programming that books fail at. Almost every one of my tutoring texts includes the phrase “open up your terminal and type python3” (I demonstrated the REPL live a couple times; I’m not a sadist). I then say, “See what happens when you do:” and provide a verbatim copy of a repl session demonstrating whatever concept I was discussing.

You might be skeptical about the merits of REPL-driven development as a style of software-engineering, and prefer TDD or something. That’s fine. It is undeniable though that a repl is more interactive than TDD, and in our hypothetical programming book we’ve already provided the user with a live test suite. The code editors these programming books use really need to integrate something like Quokka or Lighttable for whatever language the book uses.

They should also suggest other things to try. This might have to be problem-specific, but if the preceding chapter discusses the split and join functions, then wherever a list appears in the code, the editor should show it join‘ed, and wherever there is a string, the editor should show it split‘ed. If there is a string in the code, the editor should show how it is made up of characters and how to access them.

I imagine this type of interactivity could prove overwhelming, so I think it would be best to limit its scope to just the topics discussed in the chapter. For example, one chapter might discuss character codes (in Python using ord and chr), so should show the structure of all the strings in the code with their ord, and translate numeric literals using chr. The next chapter would not need to show this same context for numeric literals, but instead might discuss modular arithmetic, so numeric literals should then show their result modulo some base.

I assumed since the REPL is such a simple piece of interactive software that it would be super useful for a beginner, but what I noticed is that, when presented with an empty prompt, she just didn’t know what to type next. I realized suggestions for things to try are imperative.

Memory

Disclaimer: I’ve never seen any programming interface (let alone a beginner’s programming book) which solves this problem. Once the beginner has solved a problem and submitted her program, it is lost in the ether. She goes about her life and (to no fault of her own) effectively purges whatever she learned. This is really more of a problem with books in general, because there is no place other than your own brain to keep the knowledge you learned.

Well, computers have memory, and a sufficiently interactive programming environment should really remember the code it runs.

Whenever a beginner correctly uses a function, syntactic construct, or other piece of source code, the book ought to remember that. Whenever a beginner writes some code that generates an error, and then fixes that error with a code change, that’s a huge success! The book ought to congratulate and remember that also. She should then have the immediate ability to recall that success in another context.

If I used input().split() on problem 1.c, I should be reminded of it when I write input().split() on problem 13.a. Because the amount of code the beginner will write while following the book will be low (maybe 500 lines total?), and will usually consist of the same basic functions, I don’t see any reason this should not be feasible.

Conclusion

I’m sure there is a ton of work going on in the digital textbook space, but from what I see, the majority of “Teach yourself Python!” books/courses online fall into the MVP-product with superstar-marketing category. Maybe that’s simply the economics of the space, but I can’t help but feel we as software developers could do a lot more to craft a wholly interactive and integrated guided experience to learning programming. There seem to be tons of books, videos, and blog posts for every concept a beginner would ever want to know about Python, but none satisfy the level of interactivity I feel is really needed. My sister’s girlfriend said to me “I have no idea how the other students are managing without a professional software engineer helping them.” I don’t know either, but the books are definitely not sufficient.