Last month, two of the country's largest and most well-regarded coding bootcamps closed. While there are still over 90 such camps in the U.S. and Canada, these for-profit intensive software engineering schools aren't successfully preparing their students for programming jobs.

According to a recent Bloomberg article, the Silicon Valley recruiter Mark Dinan characterized the bootcamps as "a freaking joke," while representatives of Google and Autodesk said respectively that "most graduates from these programs are not quite prepared" and "coding schools haven't been much of a focus for [us]."

In one sense, the failure of coding bootcamps reflects the near-universal failure of for-profit universities, colleges, and charter schools to provide a usable education. In another sense, though, coding bootcamps represent a profound misunderstanding of what computer programming is all about.

As far as I can tell, most laymen envision coding as something analogous to either writing a to-do list (do this, then this, then this, etc.) or building with Legos (connect this piece to that piece to this other piece). Indeed, the two most common methods of teaching coding--turtle graphics and visual programming--encourage these overly deterministic and simplistic ways of thinking.

For example, many computer programs--video games are good example--are constantly doing multiple things at the same time, any one of which might be interrupted and redirected by events or conditions that occur inside other parts of the program or as the result of actions that the user might (or might not) take.

Writing such programs (ones that work, that is) require a programmer to envision how multiple states and situations will interact, not in a step-by-step progression but in terms of everything happening at once. As complexity increases, it becomes increasingly difficult and sometimes nigh impossible to determine exactly what's going on at any one moment.

Visual programming has similar limitations. Real computer programming means mastering at least one computer programming languages. Like every spoken language, every programming language has its own vocabulary, grammar and syntax, all of which create limitations on how easy or difficult it is to express your intent.

This is more than just "telling the computer what to do." A program must also communicate your intent to your future self (or somebody tasked with supporting your program) when it comes time to alter or debug the program. Just as journalists have different styles of writing, programmers develop individual programming styles, which may be easy or difficult for others to understand.

Well-written code is often poetic in its elegance. A clearly written program will have a felicitous word choice (variable naming), spacing, indentation, choice of algorithm, structure, and more. A talented programmer can produce code that another programmer can understand, update and debug, at a glance.

Poorly written code, by contrast, can be impenetrable, even to the programmer who originally wrote it. Such code is almost impossible to update or debug. It's usually easier to completely rewrite confusing code than attempt to "fix" it, a daunting task if the code is so obscure that it's not clear what the original programmer intended.

Coding at the professional level is highly specialized and requires years of practice to master. That's why successful professional programmers almost always have a computer science degree and extensive programming experience.