Is learning to program inherently hard?
computinged.wordpress.com
computinged.wordpress.com
The percentages of people with specific inherent skill sets will vary widely in society, so 'hard' is best defined as 'requiring a skill a smaller percentage of the population possess'. Good programming does require specific skills, but I don't see it as being any more difficult than other specialized tasks.
I don't find programming hard at all... perhaps that is because I started very young, perhaps it is just a 'natural' ability to understand and evaluate systems. To me it's second nature. However when I watch an artist form a mental image then extract it from a block of stone, or I watch my math PhD friend throw around set theory and abstract dimensions like cake recipes... I am fascinated.... and lost.
Hard is relative.
I think the difference here is that riding a unicycle is a fundamentally bounded problem: you balance, you move your feet, you do a couple of other things. By contrast, programming is effectively unlimited in its potential problem domain.
Philosophy? Music?
These are both hard to do really well, but they have a much greater margin for error and often aren't provably correct or incorrect. When I write an academic paper, if I have a typo on the fourth page, the entire rest of the paper won't catastrophically fail. When I write a program, however. . .
Hard is relative.
Very true! But some fields still, at least to my mind, feel harder than others. One (limited) way you could look at "hard" is in the context of universities: I've seen dropout graphs for various majors. It's not at all unusual for someone to go from electrical engineering to com, or CS to English, but I've yet to hear any English majors say, "English was too hard for me, so I switched to Chemical Engineering."
It might not catastrophically fail, but it might mean anything from not compiling through to not outputting a newline or create a possible security issue via a buffer overflow.
Like the majority of things in life, it comes down to shades of grey, and that's why it's tricky at times ;)
I disagree about the 'skill' bit. Skill can be acquired. There are many skills that few possess that many could acquire, if they wanted to. For examples, consult the Guinness book of world records.
I'm fairly janky in terms of my motor skills and learned to unicycle in a week or two. It consists of hacks, concepts, and fundamentals just like most seemingly complex tasks.
So, depending on how you approach computer science, you may find that those same skills have prepared you for linguistics, or vice versa. Either way, I highly recommend learning linguistics; it is a fascinating discipline.
Jon Skeet wrote a blog on the topic: http://msmvps.com/blogs/jon_skeet/archive/2009/01/29/program...
Jon Skeet is right. Programming is hard, except the most trivial tasks. And anything that is not trivial is probably broken. But we're OK with things being a little broken, and we've made users bend to our will sufficiently now that we have pushed much of the cognitive load to the users.
http://www.cs.princeton.edu/introcs/42sort/
According to Knuth, the first binary search algorithm was published in 1946, but the first published binary search without bugs did not appear until 1962.
http://googleresearch.blogspot.com/2006/06/extra-extra-read-...
http://www.cs.princeton.edu/introcs/papers/bentley-binarysea...
This reminds me of something I've read about writing:
"A writer is someone for whom writing is more difficult than it is for other people." -- Thomas Mann
I wonder if this also applies to programming.
That is, perhaps the reason programming for Knuth is so hard is that he has such high standards and that he's working on such difficult problems.
Perhaps programming is so hard ... that teaching it is easy.
If programming is so hard that an older programmer has little teacher younger programmers, then everyone is equal when trying to the mountain.
Charging a machine-gun nest with only bayonet is incredibly hard. Learning all you can learn in attempting this is fairly easy...
Probably not true but worth tossing around in your mind.
Programming is sometimes hard and sometimes easy. One of the things that makes it very hard is having a standard that demands the complete absence of bugs.
Fortunately, sometimes buggy programs are useful anyway.
Still, it seems like in fact saying things about "programming" might also being inherently hard!
I mean, we can say that the halting problem is inherently but the halting problem doesn't reflect the day-to-day practices of the working programmer. Yet how do we characterize what does? The boundary between programming and using computers is fuzzy and given Church-Turing, just about defined activity can be encompassed in using a computer (a lot of machinists have become "programmers" of numerically controlled machines but this use is more similar to artists using Photoshop than software engineers using c++). One might argue that the advance of computer technology will create more and more professions which involve the high-level use of computers but won't be "programming as such" (spread-sheet use, UI design, etc).
By that token, if "real programming" is what's left when you've codified the other occupations, one could argue that it is inherently hard. But we're still a bit at the level of tautology.
To any of the non-programmers on who read HN a lot, I'd recommend doing what I did
learning to program is deceptively hard.
First you think it hard,
then you think its not,
then you think its hard,
then you think its not,
...There are, of course, parallel examples of open problems- writing a novel is much the same way, I think. And I think most would agree that writing a novel is also hard. And doing original research also falls under this umbrella.
No, of course the complexity grows for each new instruction - and that's why it's hard. Software engineering is about managing this complexity. Programming is the easy part.
http://www.joelonsoftware.com/articles/LeakyAbstractions.htm...
It's not about knowing all the details of how it works, it's about making a mental model.
As everybody knows, doing what you like to do is easy. Doing other stuff is not.
I get better at programming as I do it more. I think you're correct that individual knowledge points aren't "practice" per se, but practice definitely factors into skill over time. Just like I imagine it does with the guitar.
If you support the 10K hours argument, some things are willingly done and others less so. I make coin with programming, yet people pay to see guitarists.
But obviously some guitar practice is more involved. It's something I think about a lot actually, as when I need a break from programming first thing I do is pick up my guitar. My musical goal is to be able to improvise on the guitar using jazz theory. To do that you need to internalize abstractions like scales/modes and chord progressions. You need to be able to transpose the same abstraction/pattern to different notes (on the most basic level this would just mean sliding further up the neck and using the same shape for fingering), and you need to be able to 'search' your options (some chords can substitute for other chords, which might then allow a whole new path of music) on the fly.
In programming you don't need to wrangle all these abstractions in a strictly timed performance, and there's no physical component to the challenge. But still, I often think about the similarities. I guess playing jazz guitar, while complex, can still be kept within a manageable scope of permutations and ultimately 'mastered'. But with programming you can't tame the complexity, you just get good at dodging it.
I am not sure what the term "inherently hard" is supposed to mean in this context.
I see programming to have a lot of parallels with being a combination mechanic and automotive engineer.
A mechanic fixes cars, diagnoses problems, tunes a car and so on. It's really a lot like (code) reading, testing, debugging and maintenance--all key programming skills.
An automotive engineer will actually a design a car, design and various components, model how it should work and so on. This is really program design and programming specifically.
The thing about programming is that involve perhaps the most tractable medium humans have ever used. It takes a long time to design and build a car. It still takes a long time to make significant changes to that car. Now compare that to software, which is easily changeable with a feedback loop that can be measured in as little as a few seconds (edit code, save, reload page in browser).
Of course some software has a longer feedback loop but at worst it tends to be in hours, possibly days. It's a different order of magnitude.
Cars can be adjusted within fairly tight limits (meaning you can make the engine more efficient or make the brakes work better or not at all but you can't easily make that car float or fly).
Is programming harder than being a mechanic and/or automotive engineer? Empirically I can't answer that question. I would be useless as a mechanic. Could I learn? Possibly. Would I be as good as those with a natural affinity? Absolutely not.
One thing I'll add is that the barrier to entry for programming is probably higher but this might simply be an issue of complexity.
Consider a car from 40-50 years ago. It wasn't that complicated. Now? Cars have dozens of computing units in them and qualified mechanics have to use computer systems to interface with them. So perhaps modern software is more like a modern car than a car from the 70s.
Now consider another discipline like medicine. Is medicine hard? It certainly requires a lot of knowledge. Part of many medical disciplines it appears involve a significant amount of rote learning. Bone names, nerves, diseases and so on.
Some have an affinity for rote learning and some don't. I know I don't.
The other part of medicine is the mental attitude required. Not everyone is psychologically capable of dealing with a patient who is dying or has the mental endurance to perform a 12 hour heart transplant. It's very exact.
But is it harder?
My own theory is that some people can become programmers and others can't. Some of the ones who can't sadly are employed as programmers.
Programming requires an extremely high level of abstract thought. I remember demonstrating to my sister how I used Splashtop on my iPad to connect to my PC at home to start it doing something. To her, it was for all intents and purposes magic (to paraphrase one of Arthur C. Clarke's laws).
To me--and anyone reading this--there's nothing magical about it. It's simply a system of concepts built on top of other concepts.
This also changes my thinking. I see (human) language much like a network protocol. Letters are merely agreed-upon symbols that, when combined, form sounds (most) humans are capable of making. Combine those sounds (or groups of letters) into words and you have a another layer of agreed-upon concepts (or definitions).
Network protocols work much the same way. Ultimately there is a physical layer where certain voltage differences equate to 1s and 0s. Once you have the concepts of transmitting bits, you arrange them into bytes. Certain bytes or byte sequences resolve to characters. Combine those characters and you have a message.
It's systems built on systems. Do non-programmers see language that way? Unless they're linguists, probably not.
So I guess my point is that programming (or anything for that matter) may simply look hard because the foundation in concepts simply isn't there. Whether or not someone can learn those concepts and whether or not that makes programming qualitatively hard is another matter.
I just learned programming just like how I learn the artistic craft: Through sheer practice.
(Now, ironically, I actually make more money doing my lesser skill in art than I do in programming)
At the same time though I do think there is a class of people for which programming comes very naturally.
90% of being a good mechanic, just as 90% of being a good programmer or a good doctor, is debugging. If you're a good debugger, you can damn well do anything.
My old CompSci lecturer answered the question this way. In most fields of engineering, mechanical, electrical, chemical you can design knowing you can build with certain tolerances in mind. In software engineering you have zero tolerance.
1. Learning to think algorithmically; 2. Abstraction.
What do I mean by these? By "thinking algorithmically," I really mean "taking a large problem and breaking it up into an ordered series of steps or sub-problems." This is surprisingly hard for a lot of people, in part because the correct "size" of steps or sub-problem can change from problem to problem and from language to language. This can absolutely be taught, though. Some students have an easier time of this than others, but eventually (in my experience) they all get there in the end, and develop an intuitive sense of how to do it... at which point 99% of people immediately "forget" what it was like to not be able to do it, and become incapable of recognizing and dealing with students who haven't gotten there yet. :-) Most programmers (myself included, at least until my dozenth or so student, at which point I figured out what was going on) fall into this category: thinking in this manner is so deeply imprinted into our cognitive processes that we typically have a very difficult time visualizing what it's like to not be there. We're sort of like fish and water, if you know what I mean.
The second problem is much more difficult to address. Abstraction is one of those things that, I'm convinced, some (most) people can "get" and others simply can't. For example, I've had students who seemed to understand arrays perfectly, including the idea of using an integer subscript to refer to the value at an array index such that if you showed them the following code:
<pre>
myList = ['monkeys', 'elephants', 'giraffes'] print myList[1]
</pre>
they'd easily tell you that it would print 'elephants' (yes, they can usually get their heads around zero-indexing without issues). If, however, you showed them this code:
<pre>
myList = ['monkeys', 'elephants', 'giraffes'] idx = 1 print myList[idx]
</pre>
a lot of them would be more than a little bit lost. Even worse would be if you showed them this code:
<pre>
for i in [0, 1, 2] print myList[i]
</pre>
They'd be really lost, then. Even if you walk through it line by line, with lots of extraneous print statements, there is a certain sub-type of (otherwise perfectly capable) student that just isn't gonna get it. I'm convinced that this problem--- lack of abstraction ability--- is also why so many students have problems with loops. Dealing with loop counter variables (and the things that you usually want to do with them--- array indexing, printing, doing math, etc.) is very hard if your brain isn't able to think in this abstract manner.
It's worse in Java than it is in Python, just 'cause there's so much more code involved (meaning that it's harder to pinpoint exactly where the confusion is coming from), but the problem totally persists even in sane teaching languages. I've talked to a lot of other CS educators who've noticed the same thing- no matter how you approach it, this level of abstraction is just beyond some students' reach. It gets worse once you try and teach them about object/class distinctions, and so on. It's not that they're stupid- my students are usually MDs working on their masters' degrees. It's just that some people's brains don't work that way. And it's not that they can't do other computer stuff- some of these students have gone on to become pretty good at SQL and even relational data modeling, which you'd think would use some of the same cognitive patterns, but apparently is different enough that it's doable.
I don't know if the problem would be better or worse teaching with a purely functional language; my gut says "worse," but I haven't tried it so I don't know, and the fact that many students with this problem go on to handle declarative languages pretty well gives me pause.
As somebody who's been programming for most of my life, it was really hard for me to learn to think about this stuff from the perspective of somebody who'd never seen it before. Many thought patterns and cognitive skills that are second nature to us programmers are, for a lot of people, very difficult to learn.
by
indenting
four spaces in always
wondered
how that workedI know that personally I enjoy conversing at least specific level of detail that includes only the subset of things that are relevant, while my wife will enumerate all the elements in a set even if there is a perfectly good description or name for that set.
I really just want to tap people on the shoulder and ask them, "excuse me, how do you think that thing you're doing works?". Unfortunately I haven't found a setting where that is socially or professionally appropriate, and includes people that would give interesting replies.
Conversely I know just enough about cars to be dangerous, I'm sure there's a mechanic out there that would find my explanation of the workings of an engine interesting.
To me, that's one thing I enjoy about teaching- a lot of the time, you're having to try and figure out how a student is perceiving the subject or lecture. In essence, you're constantly reverse-engineering your students' perceptions of what you're telling them.
But if your programming involves complex mathematics,physics, linguistics, biological, intricate interactions with the world, heck even philosophical concepts then programming is in the cartesian product of the domain and field and is as hard as the toughest problem you are attacking, judged with respect, also to the source field. The true difficulty is in balancing multiple species of abstraction, domain knowledge, device knowledge and encoding instruction in a way that satisfies all of these.
So there is the base difficulty of abstracting and then converting mental concepts to a set of computations compounded with the difficulty of getting the abstractions of your domain knowledge to transfer to a set of mental concepts that are transferable to a set of computations. heh. If the field you are dealing with is easy And Or you are continually dealing with the same problem more or less (just different facets) such that you had internalized most of the process to automated subthought (mastery) then yes it will appear easy.
Programming then, would only be bounded by its own internal difficulty, which gets easier the more you explore it and learn widely applicable abstractions. Once you mix in the difficulty of the field the same applies till you have reduced the interactions of field+programming to mastered concepts. If the field has a high minimum then this reduction may still always remain extremely difficult. So if one finds programming easy it could also be a sign that you are not challenging yourself enough, not pushing your boundaries sufficiently.
My theory is that those of the greatest skill have burning curiosity and will to improve, respond positively to challenge, and have great ability to focus - together this allows them to hold on to and continually attack a problem to a greater depth than most. You need only pick 3, maybe only 2. If there is any inherent genetic advantage held by some - greater ability to focus, efficient use of nutrients, quicker and more enduring synaptic connections, whatever - for the rest of us, I feel the brain is marvellously malleable and can be tuned down another set of dimensions. The space of intelligence is gigantic and non euclidean and likely with no concept of a global maximum. If the person is so determined they will work around their deficiencies and or train their mental processes stronger so that any "lack" of inherent skill does not get in the way of what they wish to do. This is what I believe I do and did. I do be slow as molasses.
You make an excellent point: the difficulty of programming is not only that of instructing the computer but also that of the problem the program is to solve. I agree.
(As an aside, the main problem with your comment is that it was rambling. This obscures your otherwise valuable insights. I recommend a course of obsessive-compulsive editing :))