Computer science is hard to teach, especially today. The computer has long entered the home, and most of the computer science students have one at home, one they generally use as end-users use them. It is by no means a way to say they are incompetent at understanding the principles, just a fact : they already know a bunch of programs the way my mother does.
But computer science is that : a science. It has its roots in mathematics, and physics. It has rules, limits and systemic properties. But it also has a lot of usage-driven rules, that might not be easily translated into maths, or useless, from a math perspective.
A quick exemple : to mathematically prove a function is fool-proof, you have to validate 7 hypothesis, some as obscure as rewriting a recursive algorithm to loops, some as clear as “for each entry set, there is an output”.
How can you get people who are used to programming (I know this algorithm is correct! Just look at the damn code!), or people who are only familiar with point-and-click procedures (Look, I don’t care if it’s difficult. On application XXX, when I click, it works!) that the underlying layers have to be precise and mathematically sound?
Teaching computer science, especialy when it has practical usage like object-oriented programming, can be seen in two very different flavors (no pun intended) : either like cooking, or like math.
In a cooking method, you teach receipes, you show sniplets, you go for the empirical : this works, this doesn’t. Try and learn m’boy. The analogy stands on many accounts : there are more efficient or more delicious ways to arrange your components, faster or more exquisite ways to ice the cake, things that will more or less please the customer, a.k.a. the end-user.
In the math method, you teach the reasons behind this, you go for the underlying pinnings that will make sure your program works. If it works in theory (and nowadays, the theory behind computer science extends a lot, and explains a lot of side effects and stuff), then it is 99.99% sure it will work according to plans. It is a sound way to develop a program : plan first, type the code accordingly. It also makes portage to other languages/paradigms easier : either it supports your plan, or it doesn’t. The value of the aforesaid language is irrelevant.
It has been said that a good programming class has a little bit of both. But to most engineering students, theory is tedious. They already have math and physics to learn, now computer science? And the theory has very poor visibility, since the translation to “real” programming languages is not that trivial. Coding receipes? Yes but why does it work? And once you’re outside of the code exemples, the students have to make up their own receipes, without experience to back it up (they are students, remember), so they loose a lot of time in trial and error.
Either way, you let a lot of people in the cold. So generally, I choose the “theoretical cooking” approach : you show a receipe, then explain why it works. The only problem is that it doesn’t really open to other possibilities, while not discarding them altogether, whether they are good or not. I leave that to the questions at the end of the session. I am definitely looking for something both more interesting for the student, and more sound theoretically, to get them to think before coding.