Grown-Up Languages

A few days ago, after browsing the Coffeescript docs and examples, I tweeted, “I will take your new language seriously when you have a symbolic debugger for it. For it, not for the C/JavaScript/whatever it compiles to.” So what exactly did I mean by that? Well, a debugger is a program that lets you watch and control another program. (If you’ve never used one, have a look at this 6-minute video.) Instead of staring at your code, trying to figure out why it’s broken, or adding ‘print’ statements left and right to display values, debuggers let you stop the program at any point and look at the values, or tell the program to execute one line at a time so that you can see which “if/else” branches it’s taking, what parameters are being passed to function calls, and so on.

Debuggers make programming much less painful and much more productive, but a lot of students never pick up the habit of using one. Personally, I think this is because teachers have never figured out how to put questions about using debuggers on mid-terms: most computer science programs don’t have an equivalent of the “lab exams” that are common in chemistry and biology, and if students are never examined on their ability to do things the right way, they never have to climb the learning curve. But that’s just a guess, and tangential to the main point of this post.

What I really want to talk about is languages like Coffeescript, and why I won’t use them. If I write a program in C, Java, Python, or Javascript, it is translated into instructions for some kind of machine (either real hardware, in the case of C, or a virtual machine in the case of the other three). When that program runs, the debugger can match up the source code of the program and the instructions that are being executed, so that when I say, “Go to the next line,” the debugger can do what I ask. These debuggers are WYSIWYG: the code I wrote (i.e., the code that’s in my mind) and the operations and data that I’m debugging, line up neatly.

But if I write a program in Coffeescript, it isn’t executed directly. Instead, it is translated into Javascript, and then that is what’s run. If I want to debug that Javascript, I can, but I didn’t write it: a computer program did. Yes, the bits and pieces of that Javascript correspond to my Coffeescript, but the match is not obvious, and may not even be one-to-one. It’s as if I wrote a contract in English in terms of Ontario law, then had to defend it in court in French under Quebec law. Without near-expert understanding of how the one translates to the other, it’s hard or impossible for people to reverse engineer what the debugger is showing them and figure out which bits of the code they actually wrote needs to change.

I first ran into this problem in the 1980s, when the C++ compiler I was working with translated my object-oriented programs into a tangle of strangely-named C functions for me to compile and run. After a while, I figured out that if the error was in XX_@YY@@_ZZ, I should look for a method called XX.YY taking a parameter of type ZZ, but the C that implemented overloaded operators was ugly enough that I never really wrapped my head around it. Debuggers eventually appeared that could handle C++ “in source”, and I’m sure that if Coffeescript proves popular, a native debugger for it will appear as well. ‘Til then, as much as I prefer its syntax to Javascript’s, I will (regretfully) turn away…

In the wake of posts about Shopify's support for white nationalists and DataCamp's attempts to cover up sexual harassment
I have had to disable comments on this blog. Please email me if you'd like to get in touch.