Thursday, November 20, 2014

Misguided and Hazardous Language Features

Every programming language has features that are problematic.  Some make you shake your head in embarrassment.  Some make you cringe.  Some make you wish you had never learned about them.  In some cases, they are archaic artifacts of assembly language or good ideas that are now obsolete.  Other times, they seemed like good ideas, but ultimately cause more problems than they are worth.  Books and courses on programming often mention these "features" in passing, with a brief section on how they work and a warning to never use them.  Some of these are so bad, however, that it is tempting to leave them out entirely.  While it makes sense to avoid teaching techniques that should never be used, it is also dangerous.

Perhaps the most well known language feature that should never be used is the goto.  Goto's are an artifact of assembly language and other unstructured programming languages.  They are still highly relevant, because machine languages do not know about things like loops.  Structured flow control is implemented using gotos at the machine level.  Perhaps this does not matter to the typical programmer, but it does matter to compiler writers and anyone else that needs to do any degree of assembly level optimization (writing device drivers also frequently requires assembly programming).  In the highest end programming jobs, it is important to understand gotos.  Most books and college courses on C or C++ do not even mention gotos, and this is something of a shame.  Their reasoning is fairly sound: Gotos should never be used in a structured programming language.  If students are never taught that gotos exist, they will never use them.  There are two flaws in this though.  First, what happens when a college graduate is asked to maintain some old code with gotos in it?  It may be true that they should not be there, but that does not change the fact that not knowing a very basic language feature will not look good to peers and supervisors.  The second flaw with this is that they are probably going to find out about them anyway, and without any education on them, they may not realize that gotos are bad.  It is actually fairly common for programmers to try out newly discovered language features wherever possible, either to show off or to practice using them.  Someone who does this is going to get a worse reputation than someone who does not know what a goto is in the first place.

Another ill conceived language feature, that probably seemed like a good idea at the time, is JavaScript's "with" statement (it is nothing like a Python with).  The "with" statement pulls all attributes of an object into local scope.  In cases where the reference tree is fairly deep, this can actually improve performance just by reducing the amount of text that the interpreter needs to parse.  Sadly, it also clutters the name space in the scope of the "with" block in ways that are often unintuitive and subject to change.  Minor changes in the JavaScript language can alter how naming collisions are handled within the "with" block, making behavior version dependent.  The "with" statement is so prone to error and confusion that it is forbidden to use it in strict mode.  Few JavaScript tutorials and books even mention it.  The problem here is that "with" is far more nefarious than goto.  A bit of critical thinking can quickly reveal that gotos are unnecessary in a structured programming language.  A bit of critical thinking about "with" makes it seem like a totally awesome idea.  It reduces typing, and it can improve performance.  The ambiguity it can cause is not obvious at all, and the issues with name collisions are also unlikely to be noticed until one hits.  Ignoring the "with" statement is a horrible idea, because it will eventually get found and used, if students are not warned.

Ignoring bad language features is just asking for trouble.  Besides the fact that many programmers will eventually come across them anyway, and they will not look very smart if they are not at least aware of them, if they are not warned, they are more likely to use them when they finally do discover them.  If we do not want programmers using gotos, letting them discover them on their own is not the right way to do it.  Newly discovered language features are always tempting to try (this is, after all, how we learn to use them effectively).  If students are not warned, they will eventually discover the feature anyway, potentially with severe consequences.  (There are some programming companies that will fire a programmer who uses a goto on the spot, with no questions asked.)  An education in a programming language is not complete without warnings about what not to do.  A course or book that claims to teach a programming language is not complete without warnings about the bad features of that language.