Years ago I spent a summer teaching science classes to kids aged 6 to 12 at the Oregon Museum of Science and Industry. This program wasn't particularly well managed, mostly a disaster, but quite a bit of fun. The most fun I had was helping teach a class on game programming to 5th and 6th graders. The class used a pretty nice implementation of Logo called MicroWorlds which benefited from having a simple GUI and IDE for the kids to use. Maybe today we'd use something like Scratch or EToys. Either way the class began with a simple introduction to making things happen in this virtual world, and some of the basics of the command structure. And within minutes there was a volley of hands that shot into the air each with it's very own bug.
That might not sounds like much, but by the time you've engaged someone to the point that they've typed in some commands and arrived at an unexpected occurrence... you've basically got them hook line and sinker. So that day and some of the next was often spent detailing the use of variables, the intricacies of syntax, and what rules exist and why they make their life easier. By the end of the week we would have flies narrowly dodging venus fly traps, and robots that had to defeat monsters.
I'm not saying every kid produced a work of genius, and some had more difficulties than others. But the nature of programming does not have to be a complex and difficult venture. Simply mapping input to a behavior gets you pretty far. This is a big part of the idea of Scheme. How do we build a language that is simple enough that our english majors can accomplish something in it, but powerful enough that our computer science students can develop complex ideas with it. The point is that most people can be taught to create at least rudimentary programs in just a few hours of tutorial.
And this really brings me to the reason I'm writing this post. And that is, that while programming might be easy, making applications, architecting large projects, putting all the various pieces together in a way that gives you the flexibility to accomplish what you might need to, but the structure to finishing what you have to, is amazingly difficult. And two different skills. You can teach someone to use python like a calculator, and to write functions that help them manage their bills. But the ability to take that knowledge and expand upon it to write a personal finance applications is much more difficult to teach.
Some of this is abstraction. Abstraction is difficult for humans, and I say this knowing that of all the creatures we've ever encountered we're likely the most capable abstractors in existence. But while that might be true, or brains are wired to work inside a rather constrained and physical world. There's a test that's often mentioned in literature where they ask the participants to accomplish a mathematical task using variable names, and then ask it again relating it to cards. In the first case most participants answer incorrectly, while in the next they do it with ease. The great difficult of mathematics as well as programming arrises from the depths of abstraction.
Just like Mathematics might be the deep study one abstract layer after another, complex application design mirrors this. While in mathematics at the bottom might be something like Category Theory from which derives Algebra from which derive the infinity of number systems from which derive Real and Complex numbers from which derive Real Analysis and then the Calculuses and on down the chain. A Complex application might have a User Interface which abstracts a Programable Interface which calls down into a Data Layer that then talks to a Persistence Layer that talks to the Operating System on down to the bare metal. Most of the extremely competent application architects I know might be considered a software version of a "tall, thin man". Someone who is familiar with all the ramifications of his design from the top layers to the cost at the bottom layers.
What I'm trying to say is that Programming might be easy. But the understanding of both the ramifications of the current environment (what can be done with the current language and tools) and the cost of the various layers below it, is hard. And that teaching THAT is much more difficult task than teaching someone how to use a fancy calculator. Books like SICP attempt to accomplish this task by dealing with abstraction in it's own right, by merging programing and mathematics and enabling a kind of cross pollination there of. But even that can leave a student with little understanding of how to put all the pieces together. I write this because my focus since college has been into the art of programming. And I'm beginning to understand where the limitations of my studies have been, and where I'm headed. And my new goal of trying to find more people to look at my code and find new ways of expressing those problems.