Linked by MOS6510 on Wed 17th Apr 2013 21:20 UTC
General Development "You often hear about how important it is to write 'readable code'. Developers have pretty strong opinions about what makes code more readable. The more senior the developer, the stronger the opinion. But, have you ever stopped to think about what really makes code readable?"
Thread beginning with comment 559172
To read all comments associated with this story, please click here.
Article gets it bass-ackwards
by hhas on Thu 18th Apr 2013 21:01 UTC
Member since:

FTA: "A beginner is more focused on the actual vocabulary of the language than what the expression of that language is trying to convey."

This isn't because they're beginners, it's because they're badly taught. And much of the blame for this falls squarely on mainstream languages and their existing users.

As Guy Steele put it: "The most important concept in all of computer science is abstraction." [1]

Or, as Seymour Papert explained it to 7 and 8 year-olds:

1. This is a Word.
2. This is how you execute a Word.
3. This is how you add your own Words.

Compare with how popular 'introductory' languages like JavaScript and the current plague of "learn to code" sites do it.

Khan Academy's Programming Basics course structure [2]:

1. How to Read Documentation
2. Using Math Expressions
3. Intro to Variables
4. More on Variables
5. Incrementing Shortcuts
6. If Statements
7. Booleans
8. If/Else - Part 1
9. If/Else - Part 2

Codecademy's PHP course [3]:

1. Welcome to PHP
2. Control Flow: If/Else
3. Control Flow: Switch
4. Arrays in PHP
5. Loops: For and ForEach
6. Loops: While and Do-While
7. Functions in PHP, Part I
8. Functions in PHP, Part II
9. Object-Oriented Programming, Part I
10. Object-Oriented Programming, Part II
11. Advanced Arrays and Maps

Codecademy's JavaScript course [4]:

1. Introduction to JavaScript
2. Functions
3. 'For' Loops in JavaScript
4. 'While' Loops in JavaScript
5. Control Flow
6. Data Structures
7. Objects I
8. Objects II

I could find many more examples, but that's enough to illustrate some key points. First, look at the topics covered.

- In all courses there are numerous chapters dedicated to the subject of flow control.

- The KA JS and CA PHP courses call out an apparently random selection of data types (Boolean, Array, Map), though what happened to all the other standard types (Int, Float, String, Date, etc.) it's hard to say.

- CA's JS course at least has a complete section dedicated to Data Structures, but it appears after flow control.

- KA gives special prominence to Incrementing Shortcuts, yet doesn't even touch on abstraction. The closest users get to dealing with functions is to be shown how to poke some black-boxed mystery meat that causes shapes to appear on screen.

- The CA PHP course leaves Abstraction to last. Only the CA JS course tries to introduce it early on, while minds are still relatively clear. And neither actually gets to the core of what Abstraction actually is and why anyone should care.

There's a pattern emerging from the above: one that strongly suggests its authors see programming in purely mechanistic, reductionist terms, are happy to tolerate or even embrace arbitrary complexity, and will blindly follow and replicate long-established tradition without question. Programming is primarily seen as a linear task involving the sequential issuing of instructions - Do Step A, then Step B... then Step Z - with an educational approach that progresses much the same: This is Feature A, this is Feature B... this is Feature Z.

Even when the CA JS course does try to introduce functions early on, it explains the motivation thus: "DRY: Don't Repeat Yourself." A trendy insider acronym, to be sure, but utterly worthless for pedagogical purposes. Why should learners care if they repeat themselves? They already have excellent and highly efficient tools for managing repetition - Copy, Paste, and Find & Replace - along with plenty of experience in using them.

So regardless of whether such a Functions chapter comes first or last, the most likely response will be "Pfft, functions, who needs 'em?" followed by several more years of spaghetti code. If they're lucky, such an approach will collapse sooner rather than later, while they've still some chance to undo their rotten ways (as in my case) before that mindset becomes irremovably ingrained. But it's a horribly expensive and counter-productive way to go about learning or doing anything.

So let's go back to LOGO, which combines Lisp philosophy with solid pedagogical principles, and look at how it does it. First up: Papert's objective was not to teach programming principles and practices, it was to teach structured thinking and problem-solving skills; something of great value in a good many fields outside programming as well. That students also learned some programming skills was simply a nice side-benefit of using LOGO as the platform for this.

In LOGO, students are not taught to write procedures to avoid repetition; they are shown how to expand a language's existing vocabulary to better tailor it to their own needs. This is why LOGO's limited built-in vocabulary is not a flaw (as real programmers'd naturally see it) but actually a key feature: when the only drawing operators you have are FORWARD and LEFT, you very quickly reach the limit of your patience when trying to perform complex operations. At that point, a tutor can step in and say "let me show you an easier way to do what you're doing". Thus the student very quickly learns to construct more advanced words such as SQUARE, TRIANGLE, CIRCLE, HOUSE, TREE, STREET,... through composition of existing words. And because students are doing this all this exploration at a really basic level, it is quick and easy for them to learn by making and fixing mistakes, and by experimenting with different ways of assembling their abstractions (e.g. they might initially build HOUSE using only FORWARD and LEFT, and then independently or with a little prodding realize it could also be composed more efficiently from more powerful RECTANGLE and TRIANGLE words).

Whereas if you go back to something like the KA JS course, the closest you ever get to functions is being handed a bunch of mysterious black-box incantations like RECTANGLE(0,100,200,400) and taught how to chant it in order to obtain a desired result. Superficially fulfilling, but leaves students with absolutely no understanding of what goes on beneath, never mind any idea of how to create incantations of their own.

Lastly, it's not just the course authors who are at fault: the fundamental design of mainstream languages also greatly encourages and compounds all these problems. To illustrate, which of the following words is of most importance to a user: break, export, return, case, for, switch, function, this, continue, if, typeof, default, import, var, delete, in, void, do, label, while, else, new, with, checkMyBankBalance?

Hopefully you get 'checkMyBankBalance'. But that being so, why does the language assign such special significance to all of the other words, going so far as to give them special colors, non-standard behaviors, and whole chapters of documentation explaining their use? By devoting huge attention to these smallest and lowliest building blocks, while treating the user's own words as wholly generic, the language itself is teaching its users to believe that these primitive features are the most important words in an entire program, and therefore what users need to devote all their attention to in order to understand what the program actually does.

IOW the original article completely mis-identifies the root reason why novices can't read code effectively. The fact that it stumbles across a vaguely appropriate response (use languages with smaller vocabularies) is incidental, and still doesn't fix the real problem. Until the faulty thinking of mainstream language creators and users towards language-related HCI is rectified, 'production languages' will continue to be baroque backfiring monsters, while more parsimonious vocabularies remain relegated solely to 'teaching' or 'toy' status - for kids and thickies only, and definitely not for Real Work.

[1] Foreword to Scheme and the Art of Programming (Springer & Friedman), p. xv

Reply Score: 4