Teaching programming languages: we’re doing it wrong

A call for debate on how to learn languages in the new century

As a new year resolution, I decided I had to learn Scala. It’s a nice, popular and functional language. So I purposefully started with Functional Programming in Scala. I shouldn’t have done it. I arrived to a point where I didn’t even know how to put whatever code I had written in a file and make it run. So I downgraded to Beginning Scala, where it started with the famous Hello world. A procedural, non-functional, non concurrent, Hello World.

At least it got me a bit further in learning the language. But when I wanted to compile stuff a bit more complicated than a single file, I had to go to

Spoiler alert!

end of the book, where it devotes a single chapter to Scala build tools, or rather Scala Build Tool, the appropriately named sbt.

I ended up using StackOverflow more than the book itself when I actually wanted to do something.

Do you know the joke that says that programming courses should be renamed “googling stuff in Stackoverflow”. Well, it’s funny because it’s true.

But it shouldn’t.

“Hello, world” was introduced for the first time in a book to learn C. You know what they say about C programmers

Or Fortran, or Cobol…

… they are so good at programming that they are able to program C in any language.

There are several problems with that. First one is that current languages are so far away from C as C was from assembly language.

OK, bad simile. That’s not too much…

The second one is that it’s not only about the syntax, it’s about the paradigm. The whole world model that is embedded into many languages is completely different. R, Python, Rust, Groovy, node… can they be further away from the C sequential, synchronous, type-unsafe, single-threaded, procedural, non-functional world view.

Damn, I should have said weltanschauung here. Never skip a chance to use big words in Medium, ever.

But there is a big, fat, final problem. Languages are never alone in that world. They are part of a weltanschauung

That felt sooo good…

that includes, at least, build tools but then a whole well-connected network of operating systems, device substrates and oh so many things that are never, ever, included in that book that teaches that imaginary language. Even C had that. It was created for an operating system, Unix, with its own tools on which it relied; it did have a standard library, many common libraries such as POSIX and build tools such as make. Did all that get into the “Learn C real soon now while you wait in the queue to board the Zeppelin”?

No.

It doesn’t fit into “Learn Futura RSN while you wait in the queue to board the space lift” either.

Futura being my imaginary name for an imaginary future language. Although by the time you read this there might be already a JavaScript MVC framework with that name.

If you’ve been with me so far, my point is that when teaching any computer language, we should concentrate on the troika worldview + substrate + ecosystem.

For instance, until node.js came up, no book on JavaScript really taught JavaScript. It taught how to do funny things on the browser with it. Even with tools such as SpiderMonkey that allowed anyone to work with it in the command line. The worldview focused on the substrate, and taught it for a particular substrate, while it should have focused on the functional, object based, dynamic nature on the language in any interpreted substrate, not only the browser.

Besides, when they learn a programming language, people don’t want to program, they don’t want to write programs. They want to build things.

Including a resume. Maybe exclusively so.

And I mean real things. Real client-server architectures. Real frameworks they can build on to create many different applications. Real apps. Real research workflows that produce something useful (read: publishable) at the click of a button.

So let’s enunciate a few rules, and I want the debate to start here if you have agreed with me so far, above if you haven’t,about what we should do

to teach to learn a programming language good and do other stuff good too

Let’s boil it down to a few rules.

I would love to hear your take on this. Maybe new rules. Whatever.

1. Never teach a language by its lonesome.

Acknowledging the existence of an ecosystem and a substrate means that a language is never taught by itself. Because along with it, you have to learn are at least two, and sometimes up to five different languages,

some of them might be DSL, domain specific or damn small languages, whichever way you might want to call them.

namely

  • The language itself. Of course.
  • An UI language. Nowadays, in most cases, that language is HTML. In some cases you might need some UI description language defined using XML.
  • A scripting language for the UI, for the tools and services you are using from your program, some embedded language. Most of the times this language is JavaScript or Lua, but it might be also SQL for classic or NewSQL databases.
  • A serialization language, which puts in text your data structures and sucks them back from that form. Almost always, that language is JSON, but it might be XML.
  • A toolbelt language or languages. A language for building, testing, deploying your program. Might be shell, might be Ruby, which is used in many cloud tools such as Chef, might be JavaScript again, might be Groovy which is the one used in Gradle… Might be whatever is the name of the language used in Makefile.
Was that M4?

That does not mean that you should name your book “Learn Futura, and JavaScript, and HTML, and Groovy, and shell, and Ruby too in 24 hours”. That means that if you want to learn Futura good, you’ll have to know at least the good parts of the rest of the languages.

I gather that’s part of the reason JavaScript is so popular nowadays. Just add HTML and you’ve got all five languages down.

2. Stack up for the greater good.

Do you think full-stack programmers learn, one by one, every single part of the stack? Or do MEAN programmers learn to be mean all at once?

No pun intended. No, what the hell, totally intended.

What actually makes a language great and popular is sometimes the stack and how it builds up to create applications. Which is what people want when they learn a language. They want to learn Scala to build stuff using Spark

Well, I did…

but then they need to learn HDFS and other stuff. People started to learn Ruby to create Ruby on Rails applications… and people started to learn JavaScript because sometimes jQuery didn’t get so far…

Of course, that means that you should build up on concepts such as map-reduce and model-view-controller and noSQL databases, which are part of the stack and intricately meshed with the language. That means that, once again, the stack should be a part of teaching the language. A good part.

3. These apps are made for booting.

And that’s what they’ll do. But in order to boot an app, you need to do several things: build it, test it and they deploy it. All that is specific to the language, and also part of the language.

We can’t keep teaching any language with the purpose of building single-threaded standalone desktop applications with them. Applications are complex, complicated things with many interwoven services connected via APIs, and we can’t pretend otherwise. Compiling whatever.futura and then run ./whatever form the command line just does not cut it. Even simple applications have dependencies, do source conversions or compilations before deploying and then eventually deploy to somewhere else, usually in the cloud, but always to a production machine or machines.

And we have DevOps. Let’s stop pretending when we teach a computer language we are a single programmer with a QA and a production department that will take care of all that later on in the future. We are all DevOps. And teaching a language should be DevOps too.

4. And DevOps work on teams.

How can you learn to create source without source control? Using a source control system

That is, git. For the time being and the foreseeable future.

to write your code and also interact with the rest of the team is essential even if you work alone developing a libre application in places like GitHub or Bitbucket. The source control system and the tools around it will allow you to interact with clients, create a community around it, but also interact with fellow members through issues embedded in milestones.

Because, remember, people wants to create a project. Working off a SCS from the get go encourages best practices for naming, creating a roadmap using milestones and issues, and also working systematically to achieve goals that can be measured and show up on tables. Working to close and issue is great and good. And gamifies learning.

Few source control practices are specific to a particular language, but best practices related to working on a team

Where to put the parentheses, naming conventions, so on

are. And it is the engine that usually makes the testing-deployment cycle go round, which is one of the best practices for creating projects.

5. Best practices are the best.

In order to teach and because in many cases learning subjects are considered brain dead or close to it, example code include an infinite amount of bad or worst practices, which then you have to un-learn when you set down to actually make something that will go to production.

How many times people print debug information from functions? Or use global variables when they shouldn’t (which is always)?

Or don’t include a single line of documentation along with the code? Code should be documented. Period. Beginning Scala introduces comments in page 31, right behind match expressions. And then proceeds to systematically not use them for the rest of the book.

If you’re anywhere close to a serious software shop, you know that functions should be tested or shouldn’t be. Untested code is broken code. But Beginning Scala does not even mention testing. Most books, in fact, don’t, leaving that for the upcoming “Testing Futura”. The Scala Cookbook, for instance, talks about testing in page 578.

Which means you’re back to StackOverflow.

6. But StackOverflow is there too.

And the rest of the Internet, of course. Most books don’t mention a single resource outside the authors or publishing house. But StackOverflow does not contain everything.

They’re almost there. Just wait a bit.

And if you have to ask a question, chances are if you don’t do it properly it will either not be answered or you will be voted down and your karma will go to the wolves.

And we don’t want that to happen, do we?

StackOverflow and other fora, including GitHub issues and mailing lists, do have a certain netiquette that should be followed. Learning it to get your questions answered is as big a part of the language as knowing how to create loops or compiling a file. Because people will have to do it anyway. And it’s the best if you teach them to do it good.

7. Remember to include the batteries.

Part of the reason I had to abandon Functional Programming in Scala is because I didn’t find anywhere how to read stuff from the command line. In fact, it’s not even mentioned there, nor it is in Beginning Scala. What about Scala Cookbook? Page 203.

If you want to do real stuff with a language, you need batteries: reading from the command line, a mini-framework for web publication, a math library to generate random numbers, reading and writing files.

There are all kind of languages, and some include these facilities in it, some have a standard library which includes them, some have several options one of which is considered best practice and other don’t. Leaving I/O, web things, UI and other things for the “Futura hacks” book leads to frustration and, probably, StackOverflow.

It’s difficult to know, however, how many batteries you need. That’s why a course or book is difficult to design. Maybe your best bet is to create a real application while you write the book, and include it as examples, do it in a source control system so that people can check in vivo its evolution and so on. But there are no silver batteries.

The Ikea batteries, for instance, are silver and yellow. And dirt cheap, too.

This is just the start.

I’m probably missing lots of things, but this is just a start, a call to action, a set of 7 rules that might eventually become 24. But I need your help. What do you think? Have you felt something like that when you were learning? Do you have a proposal on how to fix it? More examples? A banana? I want to hear from you!

Update

After the fact, I have found this article which raised, two years ago, some points of this article:, focusing on how learning today is basically about the syntax and grammar and not the complexity of delivering business value. This article has the same motto: we’re doing it wrong. And it was written in 2012, commenting on “Learnable Programming”, a reflection on what learning a programming language really means. Same here: teaching programming is broken, but it focuses on the problem of grading, which does not scale up. That is so true… Even in the old and unenlightened year of 2009, somebody already thought up that teaching introductory programming war wrong.

This article muses how we’re still teaching programming like they did in the teletype era. “Hello world” is not only wrong, it’s also a residue from where the only thing computers produced were lines of text.

Some reactions

This article reached YCombinator and elicited at least one interesting comment.