I alluded to this (believing it was true) and was rebuffed: http://news.ycombinator.com/item?id=3434582 . Doesn't seem to be the case.

I think that many more people can learn how to program, and become good programmers at that. It's true now that the majority (at least 80%) of programmers are incompetent, but I think that has more to do with environment, tooling, economics, and the short half-life (5-6 years) of a software developer, than intrinsic limitations on ability. I wrote about this here: http://michaelochurch.wordpress.com/2012/01/26/the-trajector... . The tools and freedom that a developer needs to become good (1.5+) are simply not available in average software jobs.

I think the big problem is that we teach programming using languages like Java, which are actually very complicated. There's a lot of information in "public static void main(String[] args)" that just seems like line noise to a novice, and that people shouldn't even be exposed to until they develop the taste to know when to use OOP and when not (and that takes years, IMO). In teaching, we should start with simple languages like Scheme so we aren't requiring people to lex and parse and generate .class files in their heads before they even know what those terms mean.

Scheme and Python are better starting languages, in my opinion, and we should be starting programming education around age 6. We can (and should) expose growing programmers to C, Scala, Clojure, and Haskell later.

Also, starting with complex languages and tools (Java-style) means we have to teach in an inverted way. In your first Java exercise, you don't write a program, you write a class. Why? No good reason. There's no intrinsic reason a program has to be a class. This sort of botched, improperly-coupled teaching produces a generation of programmers who think every program must be a class, and who produce shitty AbstractVisitorHandlerFactory programs as a result.

This is one thing that annoys me especially in the teaching of Scala-- one of the most exciting languages to come out of the past 10 years, but one that is poorly understood and generally taught quite badly. What angers me especially (I'm writing a Scala tutorial to fix some of these mistakes, probably making others in the process) is when case classes are taught after classes. For example, the O'Reilly book (which is generally quite good) covers traits (a very powerful and highly nuanced advanced OOP feature) in Chapter 4 and case classes in Chapter 6. Case classes, for the uninitiated, are immutable records (data objects) and provide a lot of niceties (automatic .equals and .hashCode, class name as constructor) for free. Since case classes are simpler than full-featured classes, they should be taught first.

The right way to teach programming is to teach the simple stuff (immutable records, referentially-transparent functions, mutable state in simple data structures) first, and then provide some insight into when and why you might want to use the more complicated stuff (OOP, type classes in Haskell, functors in OCaml).

This is the reason why people who start in functional programming usually become top-5% programmers within ~3 years and people who drink the OOP Kool-Aid almost never do. Mutable state isn't evil, and good "functional" programmers use it all the time, but if you don't start with the right (simple) default abstractions-- immutable records and referentially-transparent functions-- you are not learning how to write clean, simple, maintainable code. Not only is this an important engineering skill on its own, but it's also important for the purpose of growth, because reading good code (one's own and others') is a great way to improve as a programmer.