"When I started writing programs in the late 80s it was pretty primitive and required a lot of study and skill. I was a young kid doing this stuff, the adults at that time had it even worse and some of them did start in the punch card era. This was back when programmers really had to earn their keep, and us newer generations are losing appreciation for that. A generation or two ago they may have been been better coders than us. More importantly they were better craftsmen, and we need to think about that." I'm no programmer, but I do understand that the current crop of programmers could learn a whole lot from older generations. I'm not going to burn my fingers on if they were better programmers or not, but I do believe they have a far greater understanding of the actual workings of a computer. Does the average 'app developer' have any clue whatsoever about low-level code, let alone something like assembly?

I have seen this argument before. It starts with a belief that somehow, the lower the level your knowledge is, the better of a programmer you are. I say that while it never hurts...it's also non-sense. I know guys who are whizzes at VHDL or Verilog, but gave up on LISP or haskell.

I know Electrical Engineers who do VHDL or low level C(++) programming, and yet haven't even heard of Alan Turing or what the Halting problem is. And even if they heard of or know what a Turing machine is or being Turing Complete, no EE I have yet met has heard of Alonzo Church and lambda calculus. I know many Computer Science guys working on high machine learning apps that don't know what a stack pointer or stack frame are. I honestly have even met CS people who don't know what the difference is between the heap and the stack (thanks Java). I know EE's who think that recursion is stupid because it can blow a call stack, without realizing that is a limitation of their chosen programming language, and not recursion itself.

So where does it all begin? School of course. It also depends on how you want to concentrate your study. As I mentioned, I know gurus who know ELF, DWARF, and x86_64 assembly, and yet know nothing about computer science. They do not know about the Incompletenes Theorem, they did not take Algorithmic Complexity, and wouldn't have the foggiest about what the difference is between a lexer, a scanner and a parser (or what the difference is between a context free grammar and a regular expression).

Conversely, I know guys that can create their own toy programming languages, can compute algorithmic complexity off the tops of their heads, and yet don't understand timing diagrams, what an interrupt is, or even know how skew, jitter or cross talk can screw up your data.

And then there are programmers who know neither of the above. They just take a (higher level) language, the libraries, and design stuff. These guys (usually) know about TDD, SDLC, requirements gathering, and other software engineering best practices.

Those EE's that play with FPGA's or embedded firmware who may be able to look at disassembled C code and trouble shoot it are also the same people whom I have looked at their code...and found them copying and pasting sections of code, or found them writing 1200+ line functions because "the price of pushing a new function on the call stack is too expensive". They have nary a clue about databases, web programming, or even for that matter more exotic data structures like AVL or Red Black trees. And they wouldn't have the foggiest how to work with huge data sets (all the NoSQL stuff).

Those Computer Science types can also fall prey to the lack of software engineering know-how. They also, to paraphrase Alan Perlis, "know the value of everything, but the cost of nothing". Having a computer science degree myself, I have always analogized it to the difference between physicists and mechanical engineers. A physicist cares about the concepts, but glosses over the reality. "Don't worry about friction", or "treat it like a point object". But rather than just plug in formulas, the objective is to understand the theory. As Edsger Dijkstra famously said, "Computer science is no more about computers than astronomy is about telescopes". Unfortunately, academia fails CS grads in many ways because they don't learn many "real-world" skills. Revision control? Team programming? Shared libraries? Modular design? At least at my school, these best software engineering practices were all things you had to learn on your own.

And speaking of software engineers...they have their use (and limitations) too. While they may solve problems with brute force rather than a more efficient algorithm, and they treat the underlying hardware as a black box, their insights into the "artisanship" of programming can't be overlooked. Much of the nuts and bolts that is created are done by folks of this ilk. I knew EE's who whined and moaned about moving to revision control systems (although if it was moving to ClearCase, then I wholeheartedly agree). I mean really? And it's thanks to them that we even have new careers like Software Configuration Management engineers and Build/Release engineers.

So all this being said, there's more than one criteria to be a "good" programmer. I have been fortunate. As I said, I have a BSCS degree, but I have done a little of everything even in my short 6yr career. I have done embedded firmware development, including some assembly for the Blackfin ADSP, I have done Java Swing and Eclipse RCP apps, I have done distributed computing with some enterprise Java, dabbled in MySQL, I have done test automation with python, I have had to work with logic analyzers, oscilloscopes and DVMs, I have worked with PCIe and SAS bus analyzers, and I am currently a linux driver developer. I also learn functional programming languages for fun (currently clojure and scheme) since unfortunately it's super hard to find a job to use them. And one of these days, I am going to make a (non-compliant) version of scheme using LLVM.

So really...there are programmers of many types, and they all need to learn from each other. It's very rare to find someone who can do it all. Consider that different problems require different knowledge sets and finding someone who can work in all these domains is a rarity.