Learning to Program vs. Learning to Write Software

By Shamus
on Jul 11, 2011
Filed under:
Programming

There’s a book called Teach Yourself C++ in 21 Days, which can be read for free online if you have the inclination. When people have come to me asking for suggestions about where to begin with C++, that’s usually where I send them. Looking back, I’m not sure that was the best move. Although, I don’t really know where else to send them. College maybe? That’s an excruciatingly expensive and time-consuming way to learn, and probably not a good choice for the curious person looking to test the waters. Even that might be a bad idea. A lot of people seem to read books and take courses and emerge on the other side having no idea how to make useful software.

Imagine a book titled, “Become a novelist in 21 days.” There’s also a college course that purports to teach you novel-writing skills. Inside, you will be instructed in grammar, spelling, punctuation, proper capitalization, and page formatting. Afterward, you march out into the wide world calling yourself a “novelist”. I mean, that’s what writing a novel is, right? Putting words together? And you totally know how to do that. You got an A and everything.

I’ll admit I’ve never seen the inside of a university as a student, and I’ll freely admit Ive got shameful gaps in my knowledge as a self-taught coder. But the way C++ is taught seems to have the most alarming omissions. For example, I know people supposedly educated in C/C++ who have never had to:

  1. Create header files.
  2. Use external libraries (outside of the default libraries) in their own project.
  3. Deal with or consider cross-platform issues.
  4. Do anything, anything at all, with a windowed interface.
  5. Use profiling tools.
  6. Use source code control.

I’m sure these things are taught, somewhere. (People seem to know them, at any rate.) But they aren’t mentioned or covered in any of the books I’ve come across or inside of the heads of any second-year university students I’ve known. Books seem to begin and end with, “Here is the syntax of the language. Got it? Good job. Off you go now.”

I think just about everyone understands that programs come from source code. A programmer types some stuff, compiles it, and gets a program.

//The classic "hello world" program in C++.

#include 
using namespace std;

int main ()
{
  cout < < "Hello World!";
  return 0;
}

Aside to other programmers: I really think the "hello world" program for C++ is misguided. The point of the simplest program is to make something so elemental that a complete newcomer can understand every part of it. But here, the conversation is likely to go:

Student: Hey, what's this 'cout' thing?"

Teacher: Oh, that's an object. We'll cover that later in the course.

Student: What about 'using namespace std'? Is this related to sexually transmitted diseases?

Teacher: Hopefully not. I'll cover namespaces after we do objects.

Student: Okay then. What about those two less-than signs?

Teacher: Er. Normally two less than signs is a bitwise shift, but in this special case it's used to put items in a stream of the 'cout' object.

Student: So, in this entire example program we have something that's too advanced to explain to me, a symbol that is a unique exception to a rule I don't yet understand, and the words "Hello World"?

Teacher: Also, #include is usually a header file followed by a .h, but iostream is a special case.

In my mind, the old C Hello World program is a far better place to begin learning, and I get the feeling it's not used simply because it doesn't have any C++ specific code in it. As if that was more important than clarity and comprehension to a first-day student.

All C programs begin with main (), a function. If you're doing more than printing "Hello World", you'll likely need to add some other functions rather than cramming the entire program into main (). So I'm writing this program to create killer robots and wipe out humanity:

//A small project I'm working on because I HATE THE WORLD!!!!!!!

void KillAllHumans ()
{
  //To do:  Add my human-killing code here.


}

int main ()
{
  KillAllHumans ();
  return 0;
}

Eventually I'll have code for rounding up members of the resistance, tricking them into revealing the location of their base, identifying objects that are being used as makeshift weapons against my deadly robot army, and so forth. Eventually I'll have more code than can reasonably fit in a single file. It will be time to break the program into multiple files. Maybe I'll add a new file, called "Locate.cpp". (the .cpp stands for 'C++', but it's just a text file like all source code.) In Locate.cpp I'll put all the code related to finding humans and differentiating them. Then in Exterminate.cpp I'll have the code that drives my army of merciless killbots.

Another coder might have a different way of breaking up the project. Maybe one file for locating, another file for classifying, another file for prioritizing targets, another file for killing. My files will be larger. The other coder's files will be smaller, but there will be more of them and more total lines of code. Where is the balance? What is the best way to break things up so that they make sense, are easy to maintain, avoid overly-convoluted program structure, reuse code where applicable, and still get the job done?

And here is where the "software engineering" bit kicks in. This is where you move from "learning grammar" to "writing a novel". This is the stuff that some people are never taught. I say this because I so rarely hear people discussing it. I've seen endlessly pedantic arguments over code formatting, variable naming, and other stylistic choices that, in the long run, don't make a lick of difference to the end user, the compiler, or even other programmers. But I hardly ever hear anyone discussing the theory and practice of designing a software project like this. Some people seem to assume that once you can write syntactically correct code, you're a programmer. You can find evidence of this dangerous line of thinking as you go out into the world looking to use code written by other people. Some code will be neat, clear, organized, and have an interface only as complicated as it needs to be.

holly_hop_drive.jpg

Your code should allow another programmer to come in and begin using it without needing to read and understand everything you've written. If you write a library to (say) load 3DS files, I shouldn't need to know about how the files themselves are constructed or about how you organized your code. I shouldn't have to make choices about options I don't understand and I shouldn't have to deal with features I don't need.

Here, let me give you a concrete example. Let's say you're writing some program for Microsoft Windows. You want to create a window for the user. Here is how to do that using the Microsoft Windows API:

    //For clarity and fairness, all error checking has been removed. 
    WNDCLASSEX wc;
    HWND hwnd;
    MSG Msg;

    //Step 1: Registering the Window Class
    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    RegisterClassEx(&wc);
    // Step 2: Creating the Window
    hwnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        g_szClassName,
        "Sample Window",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
        NULL, NULL, hInstance, NULL);
    ShowWindow(hwnd, nCmdShow);

Now here is the same code if you're using SDL:

screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE);
SDL_WM_SetCaption(“Simple Window”, “Simple Window”);

Now, someone might defend the windows code by pointing out that there are a lot more controls there. Basically, there are more knobs and dials and switches for you to use. But this front-loads all of that complexity so that I have to flip all those switches and turn all of those dials before I can do something simple.

reactor_controls.jpg

Note the part where it says "CW_USEDEFAULT". That's where I specify where the window will appear on the desktop. The vast majority of windows simply accept the system default. (Try opening up a bunch of windows at once. Notepad, minesweeper, whatever. Note how each one begins down and to the right of the previous one, cascading down the screen. That's what the default value does.) Some windows are designed to appear minimized, and so this option doesn't apply. Other windows appear maximized, so this option doesn't apply. But whether or not you care or regardless if these options have any meaning for you, you must always specify that you don't care. It would be like a car that you couldn't start until you decided if you wanted to use the radio or not. Even if you want the radio off, you have to explicitly say so (and the windshield wipers, rear defog, headlights, heater, air conditioning, and dome light) before you can turn the engine over. This exposed complexity is bad design. (In defense of the Windows API, it's friggin' old and was created while the windowed interface was still evolving.) A better design would let you do the straightforward, obvious thing in just a couple of lines of code, and then give you additional features to do things outside of the norm.

So a more honest answer to the question of "Where should I go to learn programming?" is "I don't know". I did it for a couple of years before these concepts dawned on me, and even longer before I began to form a framework in my mind of how things should work and how this code would appear to another coder. And it wasn't until I began using code from other people that I began to understand how important this was, and that it was more critical than just about anything in any of the books I'd read.


Comments (251)

From the Archives:

1 2

  1. Veloxyll says:

    It’s funny that you post this now, because this bugged me earlier today:

    http://www.bugcomic.com/comics/how-to-be-an-artist/

    oh terrible puns, how I love thee

    I think this occurs in a variety of fields though – They teach you how to perform the mechanics of the job, but they never really bring it all together.

    As for coding itself, I remember making a program in Java at uni, and for ages the first half of the program was auto-generated code that every program has to have. Come to think of it, a lot of the program was still code that every program has to have. Which begs the question – if every program needs it, and it’s mostly the same for 99% of programs, why not have it auto-load, and then have the programmer just enter data if an exception is needed.
    Well, besides the fact that nerds like to lord their knowledge over uninitiated nerds of course.

    • Because as Shamus mentioned, flexibility of function sacrifices usability of the language (to some extent) – you may see 99% of your programs defining the same thing at the start, but this may not be the case for the vast majority of all programs or files.

      In fact, IDEs (Integrated Development Environments, or programs used to write code) do auto-fill a lot of this stuff for you in a newly created program – Eclipse can do this easily for Java, for example.

      • aldowyn says:

        I’m pretty sure Java only has a couple lines that it “has” to have, and that’s just naming the class and the main.

        The main was the only part of “Hello World” that was taught by saying “we’ll get to that later”.

      • Mephane says:

        auto-fill a lot of this stuff for you in a newly created program

        Enter the mighty code generator. I have a deep passionate loathing for these things. Instead of, well, allowing you to write compact, easily maintainable code, you get a tool that generates usually convoluted code with formatting so horrible that trying to read and understand it in case it does something unexpected is a real pain. And want to change a detail, well, better never have to generate the code again, you’ll have to stitch together the newly generated code and your changes. Oh the generated code has a memory leak? Let’s fix the code generator* manually, notify it’s makers about the issue and how we fixed it, and pray that they might not forget fixing it for real in the next release.

        Which actually proves Shamus point. There is code out there, publiched, meant to be used as a library by someone else, but written with such an awful interface that I can’t even fathom what a mess it sure is in the inside. I’ve had a library that was meant to (among a lot of other things) do some fancy XML parsing, and it brought a whole XML DOM model with it, a pull parser etc. Guess what I found the tool to actually do? Use some low-level C code, directly bypassing their DOM model and producing an unreadable mess of oh_no_more_extra_long_function_names_crammed_together lines.

        *I’ve done this for real. Some tool we had to use produced C++ code that looked like a monkey ported it from Java, 1:1, even with Java-like memory handling (hint: none, Java does that for you, in C++ you’re on your own). Luckily the generator was a Java .jar archive and I could manually edit some XML templates inside in order to fix the issue, but wasn’t this code generating thing about saving time and headache?

    • I have found that I have the opposite problem with art classes. I want them to teach me about what I can do with a pallete knife, with different types of brushes, or with various software programs. They want to teach me how to make a proposal to a prospective client, prepare 30 different thumbnails that may all address different needs, and how to format the final product for ease of use.

      Hawah?

      • Octal says:

        I had similar experiences with (college level) art classes–I wanted to learn techniques, learn about tools and media, and get practice; they wanted us to… “make a sculpture that represents yourself”. All three of the intro-level art classes I signed up for in college had that exact assignment (with the medium varying according to the class, though)–two of them as the first assignment.

        This comic pretty much sums it up.

        • Jjkaybomb says:

          In my experience, I’ve run into art classes that taught technique and others that just said “do art” at you. I’ve only run into one fiction writing class that has ever tried to teach both. I consider her one of the best teachers I’ve ever had.

      • Same here. College art tends to be all about getting in touch with your creative soul and nothing about “why would I want to use cold pressed cotton paper rather than hot pressed” and what on earth is the difference between student grade and professional grade materials. AND in my experience (art minor at Slippery Rock U ages and ages ago) they tend to focus on “who cares about the quality” that is the traditional way of doing things and we have thrown off ALL things traditional. I only had one class that explored different drawing media and even that was focused on getting us to loosen up.

        I wish there had been an art media class that really just explored all the different materials available and why different ones are better for different things. Art media is EXPENSIVE and buying a $30 pad of paper is HARD when you are not even sure if you will LIKE it.

        On the other hand I had a great writing class that encouraged both.

  2. CrushU says:

    I just finished a four-year CS degree.
    There was a class, don’t recall the exact numbering but it was billed as a 200-level course (and the prof. said it should rightly be a 300-level course) that was all about Software Engineering. How to design/build. Absolutely no code was written for this course. I found this single course to be one of the most useful.

    It probably helped that the prof. had job experience in the coding field, working on large-scale projects himself. (Yes, it was C++)

    • Nathon says:

      My college’s CS department had a course like this, 3rd year required called software engineering. I think it’s pretty common these days. Of course, I write code for a living and my degree’s in electrical engineering so I never actually took that one.

      • Traagen says:

        I’m a graduate student at the University of Victoria in British Columbia. I don’t really know about elsewhere in the world, but here you can earn a degree in Computer Science or in Software Engineering.

        If you take Computer Science, you learn all kinds of cool things like Graphics, AI, Compiler Construction, Human-Computer Interaction, Computational Geometry, etc. But you never learn to actually write code. I taught labs for 3rd and 4th year students who didn’t know to write a function to perform their cross product operation. Imagine trying to debug a graphics program with everything in main(), the code for things like cross product just copied and pasted throughout. Even the courses on data structures and algorithms were heavy on the theory with virtually no application.

        On the flip side, Software Engineers learn all of the really useful stuff like GUI design, System design and analysis, project management, etc. They can’t really do anything interesting, but they can write good clean code a manage a project!

        The scary thing is how many students make it through either degree without taking courses from the other as electives. All I can say is that I am glad I went to a school where there was no differentiation. This is a very elitist mindset which, in my opinion, only harms the industry.

        • CrushU says:

          Where I went to college, there was a style guidelines that EVERYONE had to follow:
          No line longer than 80 characters.
          No method or function longer than 30 lines.
          Main() shall have no complicated algorithms of its own.
          Only catch exceptions you can fix.

          You got serious points deducted for breaking these rules in the 100 and 200 level courses, some higher-level courses would make exceptions for the 30 line limit if you gave a good reason why it was so long.

          These rules pretty much enforced Good Coding Habits.

    • Wtrmute says:

      I had a class in Uni about software engineering (two classes, actually, because of grid reorganisations which made me take the class again). I confess that I recall hearing about Waterfall development model, Rapid Application Development, &c. As a professional developer, I have never been able to use one line of those things I was taught there.

      I actually learned to program as a kid, but only 80s-flavour BASIC (MSX-Basic, for those who know such things), so nothing that would translate well to my future life as a software developer. Where I learned proper structured code, object orientation, multiple files, &c., was actually in the practical programming assignments in University. The first one was to write a breakout program for a Computer Graphics class, and after that I had to implement a system call in Minix, set up a CORBA service, write an Employee-Department-Project database and infrastructure in ORACLE (8i, so using those stone-age tools that were available then for that database). Windowing systems were crash-taught to me in my internship in the fourth year.

      Where I’m getting at is that while there are good books about learning a language, and there might be good classes about structuring your development-work, nothing really beats having concrete goals to reach and specific software to write.

      • Alex the Elder says:

        I very much second this comment. What I know how to do (be it programming, sysadminning, setting up a network, fixing a car, building a chicken coop, healing in raids or battlegrounds, etc.), I mostly learned by having a specific problem to solve, and then solving it through research and (more importantly) trial and error. This is not what managers of tech people, or users of their services, like to hear (hence the profitability of the certification racket), so bullshitting is another thing you’ll need to learn on the job very quickly.

        • Bubble181 says:

          See, the terrible thing to realise is that this same principal applies to nearly everything.
          Your first-year lawyer, doctor, psychiatrist, psychologist, gynaecologist,… are all people who’ve learned the techniques and names and stuff, but have no idea how they fit together.

          • kerin says:

            As far as the doctor and gynecologist go, med students shadow experienced professionals as a sort of internship/apprenticeship for years before they’re cut loose. This is what gives them the “big picture.” Psychiatrists deal with this problem by prescribing Prozac automatically for the first three years of their practice, but sometimes stay in this stage indefinitely. Lawyers are granted this perspective in Hell, as they kneel in supplication before their dark master.

            Our world is a funny place.

    • Lintman says:

      I think most (good) CS programs offer a course like that.

      This illustrates the core reason that you don’t see books like “Teach Yourself C++ in 21 Days” covering profiling, GUI development, external libraries, cross-platform, etc. And that reason is:

      The programming language is only a small part of what you need to know to do serious programming.

      The scope of that knowledge is just too big to fit in one book. Particularly when many of these books are written to also appeal to programmers who already know those other bits and just want to learn the details of a new language.

      CS is a huge broad and deep field and extremely few people can honestly claim to know it all.

      For writing a programming book or creating a programming course, the difficulty lies in covering the most important topics for the largest part of your intended audience. Since you have limited pages and limited time to write or teach the material, you can’t possibly cover more than a small fraction of what’s out there to be learned. So authors and teachers have to pick and choose the topics they emphasize.

      Shamus, if you think that the existing books out there are emphasizing the wrong things (or just missing some critical ones) and you feel strongly about it, perhaps there is an opportunity there for you. Seriously.

      • Alan says:

        “Shamus, if you think that the existing books out there are emphasizing the wrong things (or just missing some critical ones) and you feel strongly about it, perhaps there is an opportunity there for you.”

        Let him finish the other one first…

  3. Psithief says:

    Where should I go to learn programming?

    stackoverflow.com

    • CrushU says:

      And its companion:
      Where do you go to learn how to not program?

      thedailywtf.com

    • Alex the Elder says:

      No, stackoverflow is where you go to learn, in minute detail, the extent to which the stackoverflow regulars hate you. Unless you’re coming there to offer THEM a morsel of knowledge, you’re not worth their time – they’re quite up-front about this.

      I mean, this is true of most serious tech dicussion forums, but stackoverflow is the first place I’ve seen where it’s actual policy.

      • kerin says:

        Stack is very civil. Even in cases where the asker obviously had no what was going on, I’ve never seen anything less than politeness.

      • Kyte says:

        Totally not true. I’m yet to offer significant contributions (mostly ’cause there’s nothing I CAN contribute. I’m still young and learning after all), but I’ve always had my questions answered (or attempted to. I have bad luck with bizarre behavior).

        All you need is to ask nicely. And show you attempted some research on your own. After all, it’s not a “do everything for you” site.

      • Mephane says:

        I have no idea what site you are talking to. Never before in my life have I seen such a mature and helpful community like there. The only thing you won’t get a nice answer for I’ve seen yet, are the questions where someone posts a homework task, sometimes in the exact wording, with no tangible question whatsoever, and expects the community to do his homework.

    • bob says:

      This is harsh, but IMHO I think http://www.google.com would be better. Stack overflow assumes you can at least “talk the talk”, which a new programmer wont be able to.

    • Tizzy says:

      I have only a passing familiarity with stackoverflow, but it’s definitely NOT where you go and learn programming: it’s where you go to get help getting past technical hurdles, nothing more. As Shamus makes abundantly clear, that’s not what programming is.

  4. Thadius Girth says:

    So basically what you’re saying here is that programmers can act an awful lot like the fans of any given show or comic or anything else, rambling to you with more information than you need or care about to get the story.

  5. Alden says:

    I remember after I finished university and got a job, and discovered how complicated it was writing code for Windows, I logged on to the university’s BBS system and asked why none of the courses taught programming for Windows. The answer I got was something along the lines of “we don’t want to scare people off programming.”

    • Zukhramm says:

      In my experience the courses themselves have done a good enough job of scaring people off without the help from Microsoft. I had done some programming myself before so I had no problem (in fact, having had courses in C++ which I did not understand much of earlier, this course in C was a step towards the easier) but for those who had never been close to programming in their lives the course was moving a bit too fast I think.

    • James Schend says:

      I dunno when you went to school, but fortunately .net and WinForms (and more specialist environments like XNA and Silverlight) have changed that. Believe me, even Microsoft knew the Win32 API was extremely complex and crufty.

      The real problem now, and one not addressed in Shamus’ post, is getting people the hell off crappy languages like C++ and using memory-managed languages. Just switching from C++ to C# will simultaneously prevent bugs and give the programmer much more free time to do all those not-technically-programming tasks listed in the article.

      • kerin says:

        Switching to C# is only appropriate when you are developing software for which requiring a runtime library is acceptable. It isn’t always, not by a long shot. C++ is absolutely required if you ever want to be able to write, say, device drivers or kernel modules.

        In fact, let’s get metaphorical: a powerdrill is clearly faster and better than a screwdriver. However, you can use a screwdriver anywhere at any time. You don’t need to have access to a wall socket, or remember to charge your batteries. It’ll take a while, and it’ll be harder, but for some kinds of work it’s what you have to use.

      • Mephane says:

        I am with you about switching to the next higher-level language, but there are real projects out there where you have no choice, even if in many cases it is only because some manager decided “do it in C++, because we’ve done everything in C++ so far” (sigh).

        I think Microsoft should really have made a C++ implementation of basically the full .Net library and declaring that as the definitive way to go. Instead, you will find everything out in the open, from bare Windows API calls to MFC (shudder) and third party libraries.

        That said, my private project are now all in F#, which has the same capabilities (and .Net libraries) as C#, but functional languages are, in my opinion, the next level of programming language evolution. Heck, even in my C++ code at work every couple of days I do something where I could point out the parts where doing it in a functional language would require only half the amount of code, time, effort and maintenance.

  6. Maldeus says:

    I make a lot of comments in this vein, and I still stand by them. I would pay money for a book called “How To Not Suck At Coding” by Shamus Young.

    …Making the assumption it was actually a guide on how to not suck at coding, at least.

  7. The Bard says:

    I took Intro to Computer Science in college back in ’96, which was a C++ course, and the professor was a tenured 65-70 yr old man who frequently wrote things on the board, stared at them in confusion for a few minutes, then erased everything and told us to forget what he’d just put up. Next, he would draw up the same exact equation and declare it to be correct.

    I got a 13 out of 100 on my final exam, and it was curved up to be a 79 (I was proud of my C+ in C++). Suffice to say, I dropped out of Computer Science II because I was sooooo inadequately prepared by the intro class. So I did the logical thing and picked up english/studio art instead. 8D

    • aldowyn says:

      For some reason CS classes always seem to have bad teachers. My thought is that no one really knows what they’re doing in the first place, and everything is done with a lot of trial and error.

      You can easily tell who’s committed and who’s not by who actually tries to learn >.> (I was somewhere in the middle)

      • The Bard says:

        For my class, at least, the big difference maker was who had access to resources in high school. It was assumed most people had some programming experience prior to college. All I had access to was home economics, pottery, or shop. This helped them overcome the failings of our 95% senile professor.

        I went through three tutors, and we just kept getting more and more remedial and I kept saying “no clue, no idea, and never heard of it.”

        I think it might be akin to teaching Shakespeare, and one kid says “I’m lost.” The tutor goes over the specific play, then backtracks to go over the concept of a play itself, then goes back to look at the actual written language used in the play, and then ultimately we discover the student is illiterate. Period. And the tutors weep shamefully and tell you you’re a lost cause.

        • WJS says:

          The analogy breaks down at that point, however; someone who is totally illiterate would only be a lost cause so far as the Shakespeare class was concerned, he’d be able to go learn to read and write somewhere else (although learning is obviously easier as a child), where is the “somewhere else” for programming, if not a programming course?

  8. kikito says:

    Regarding the “hello world” problem: C++ was thought to be a lot of things, but “easy to learn” wasn’t one of them.

    In other less verbose languages the “hello world” program takes exactly one line. Python, Ruby or Lua come to mind.

    The best way to learn C++ is learning another language first. One that is designed with newcomers in mind.

    • Ben says:

      Very much this. Java (the seemingly favorite teaching language) has very similar problems to C++, you have to declare the class, the main statement will include syntax for command line operations whether you are using them or not. Then you have System.out.println which is no more intuitive then cout <<.

      Start with Python for a few weeks, maybe a month to get a feel for basics programming and then go into Java or C++

      • Alexander The 1st says:

        System.out.println() is traceable though, since it follows general function syntax, and while verbose, is at least a LOT more clear than “cout <<"

        For 1.)

        If cout is an instance, I'd presume convention should put it as cOut, correct?

        Or…"c.out"?

        Whereas with "System.out.println", you can identify "System" and "Out", and something that looks like "print". Simple enough, I think, if a bit over-verbose.

        Though granted, I started with one course (4-months) in Python, so…yeah.

      • Jarenth says:

        I still remember that my opening Java class had us type

        public static void Main(String[] args) {
        System.out.println(“Hello world!”);
        }

        I still don’t actually know what half the syntax in that example does.

    • Kdansky says:

      Yes. Don’t start with C++. Just don’t. It’s a nuclear-powered flaming vorpal chain saw. Ruby, Pascal or Python make much better learning.

      People should be able to write a decent piece of code (example: display a given picture imported from google maps, and colour everything red that might be forest, and figure out the percentage of “forest” on it), before they have to learn the difference between pointers and references, and how memory (heap vs stack) works.

      I got an MSc in CS, and write C++ in a multi-million lines of code project for a living. Don’t start with C++. Don’t.

      • Ragnar says:

        No, no and no.

        First you should learn how to break down and analyse problems. This is easiest done by learnig math. Discrete math, logic, algebra, calculus. Math is the foundation of programming and also the foundation of breaking down and analyzing problems.

        Then you should learn how programming and computers work. This works best with scheme and then C. You will never really be able to construct programs until you know the intricacies of how things work at the low level. If you start with high level programming, you will only end up as someone how has tools that they don’t know how they work.

        • Alan De Smet says:

          Screw math.

          Okay, I’m overstating it. Math is useful in programming. But math as a basis for learning computer programming or (basic) computer science is vastly overrated. Lots of people who are “bad at” math (frequently because math courses suck; a real shame) can be great programmers. Maybe I wouldn’t trust them to debug a fast Fourier transform, but there is a heck of a lot of programming work that doesn’t require math past algebra. My poor calculus knowledge began rusting away, unloved, pretty much the moment the classes end. Logic is valuable, but it’s possible to learn logic as a side-effect of learning to program.

          I’m dubious of the value of Scheme or any other functional language as an introductory programming language. There is a lot of value to knowing how to write in a functional language. Every serious programmer should learn at least one. But as a first language it’s a weird starting point, “Here’s something unlike what 95% of programmers are write.” It’s like declaring that before you can learn English, you need a solid foundation in Latin. It’s uncommon, idiomatically wildly different, and much harder to find others who can help you. Start procedural.

          I absolutely am with you on getting C early, maybe first. It’s a small, relatively simple language. (Admittedly features Scheme shares) There isn’t an assumption of huge libraries and lots of powerful built in functionality to lean on. And by God, you’re going to have to learn to deal with indirection (in the form of pointers) early on. If you can’t cope with indirection, computer programming probably isn’t the career you want. You can do a lot of work without indirection, but you’ll never be promoted out of the Visual Basic trenches.

        • Samopsa says:

          Using tools even when you don’t know how they work is not strange or dumb though.

          A builder probably has no clue how his electrical power-drill works. But that doesn’t stop him from building a shed with it. Painters don’t start with inorganic chemistry to learn how molecules get their colors. But they can still make a pretty picture. I can knock up hundreds of analogies like this.

          Likewise, a programmer might not know how to read or write assembly code, but can still pump out everything he wants using higher level code. NOT black-boxing stuff that gives you perhaps some percentages of better performance if done manually isn’t going to help anyone programming.

          Math does help obviously, but is not as essential as you make it out to be imo. Yes, if you’re doing graphics or something it’s going to be an amazing help. But most of programming is just plain logic. Telling people who want to get into programming that they need 2 years of math and low level shenanigans is not the way to go. Yes, the end result might be better, but most people will just say ‘screw that, I’ll just go do something else then!’

        • Kdansky says:

          I want to point out that you don’t necessarily need Math. You need the ability to abstract first and foremost. The easiest way to get good at abstraction is to learn Math (and Math itself is incredibly useful for programming many things). So yeah, Math is necessary at some point, but you don’t actually need to spend three years on it before you can write your first Flash animation.

          As for the machine: You do not need to know how the machine works to be able to write code for it. A novice mechanic learns how to change a wheel before he figures out the intrinsics of a Wankelmotor. It’s the same with programming. If you know how to use your tools, you can learn to program. And when you start to get the basics, you should next figure out why the basics work.

          As for learning C: Why would you want to start with a language you cannot use? You’ll also acquire habits that are seriously bad for OO development later on. It’s a decent choice when you are ready to learn about the insides of your machine, from a purely academic point of view. But to get some experience, stick with Python or Ruby.

          • Alan De Smet says:

            Being introduced to OO early on was completely wasted on me. On the small projects you do early on it’s frequently unnecessary complication. I didn’t appreciate it. So I said screw it and wrote C for the next year. As my projects grew, I learned the value of OO in the C idiom (see also: FILE*). I was far better prepared to appreciate the benefits of OO and use them correctly.

            In counterpoint, working in academia I see a lot of graduate student code. What they write has classes and objects, but it’s not really OO. They never really learned why OO is a useful tool, they just know that you use it, so everything gets smashed into classes, frequently nonsensically.

            It’s a crude analogy, but leaping into a higher level language is like skipping arithmetic (hey, we have calculators these days you Luddite!) and jumping right to algebra. I have no doubt you could get a lot of work done, but because arithmetic is just a black box you’ll find yourself limited. Some people will go back and learn the arithmetic, but many won’t and will delude themselves into thinking that they have mastery.

            • silver Harloe says:

              It’s a crude analogy, but leaping into a higher level language is like skipping arithmetic (hey, we have calculators these days you Luddite!) and jumping right to algebra. I have no doubt you could get a lot of work done, but because arithmetic is just a black box you’ll find yourself limited.

              Quoted for truth. Seriously.

      • Alan De Smet says:

        My introductory programming class was C++. That was serious mistake. So much time was spent handwaving about details that I had zero appreciation for it. Out of spite I switched to working entirely in C for the next few semesters. Armed with a solid understanding of C and idioms for clean, reusable code, suddenly C++’s virtues were obvious.

      • Daimbert says:

        I took an introduction to AI Cognitive Science course at the graduate level a while back, when I have a Computer Science degree (and a Philosophy degree) and everyone else had almost no programming experience. I was paired on the group project with the person who had absolutely no experience, for obvious reasons. The course was in Python.

        I had to resort to a C example to explain how iterating through a list works, because Python hides all that.

        In teaching a language, you want to start with a language that forces you to use as many concepts as possible so that you know what they mean. That’s why it was so easy for me to pick up Python lists and so hard for her; I knew what “i” was and she couldn’t figure out what that was getting assigned to or how it was iterating.

    • DrMcCoy says:

      To be fair, Hello World “tak[ing] exactly one line” is not necessarily an indication for the user-friendlyness of a language. Case in point: Perl.

      • Jon Ericson says:

        Perl is the ultimate in user-friendliness despite reputation. The problem is its not always reader-friendly.

        print "JAPH\n"

        • Alan De Smet says:

          I’m so sad to see Perl declining. It’s a language that trusts me with the dangerous but powerful tools. I look at Python and see a language that has deemed me needing safety scissors and barring me from glue in case I’d eat it. (I look at Ruby and wonder why you would invent new syntax when there was perfectly good syntax lying around to nick.)

          Perhaps unsurprisingly, I’m a fan of C++, too.

    • I’ve found this to be the case with a lot of things–I started learning how to program with PASCAL. Yes, PASCAL. Which actually isn’t all that difficult of a programming language for a newbie. When I moved on to C++ (which I only scraped the surface of), I already knew basic terminology like what a function or operator was, so it was really easy to pick up the different syntax and say “oh, this does that”.

      Later on, when I was doing programming at work (I was a clerk, and wound up writing my own database applications and report functions in Access), it was easy, because I had the rudiments down, at least.

      So, yeah, if you really, truly, know nothing about how programming works, find the easiest, simplest language you can find, even if everyone and their brother complains it’s a crap language. It’ll give you the grounding you need to at least say things like “oh, so this is a function that it takes some variables, does something with them, then returns a result”. It will save you a lot of pain.

      And once you’re past that baby-food stage, you can start learning the things that looked indescribably complex. They’ll still be complex, but you’ll be able to tell what parts of it you can just ignore/leave as default, and what parts you actually care about for whatever you’re working on at the moment.

      And you might actually be able to READ the help documentation, which is the primary thing you need to get anywhere.

      • Alexander The 1st says:

        And you might actually be able to READ the help documentation, which is the primary thing you need to get anywhere.

        Presuming the documentation actually tells you anything you don’t already know about what it does, or is up to date, etc.

        • Well, I was talking about the low-level stuff that I do. 90% of my programming knowledge consists of “okay, now I need to do X. I will type 300 words into the help index that might lead to something about X. Oh, here’s a function I’ve never heard of. I pass it variable hmm, ffmm, and mmafh. Okayyyyy . . .” *tries out the function* “Hey, it worked. Awesome.”

          It works fairly well for me and my simple needs. For more complex problems you will probably need better documentation.

      • Natalie Bueno Vasquez says:

        Booyah, Pascal. I had intro to intro to Computer Science in ’88 (if it weren’t for the machine coder I’d feel like a dinosaur). My high-school BASIC was deemed insufficient for a CS major, so I took the baby food. I was bored out of my skull, so the instructor had me do the projects in FORTRAN as well.

        I was there during a time of tinkering with the program. CS had gone from a bastard stepchild of the Math department, to a bastard brother of Electrical Engineering, to its own department in the College of Engineering. So along with the coding, you learned at the gate level what all those little black boxes with the blue smoke in them were doing. And you learned the complex Boolean equations that made it all possible.

        All that being said, I wouldn’t call that good prep for writing software. I’d call that a good grounding in understanding what’s going on. It wasn’t until the Senior Project course that we had a problem to solve, and that’s where all the “break it down” stuff started to make sense.

        I think there’s too much to know at this point – you can’t point at 10 things and say “This is Computer Science!” Just like Engineering has split into Industrial, Chemical, Mechanical, Civil, etc, Computer Science/Engineering will need to do the same thing. Or get absorbed into the other Engineering disciplines. The pure theory may devolve into “computer science” or be reabsorbed by Math.

        But yeah, if someone wants to “learn how to program”, I think the thing to do is ask what problem they’re trying to solve. Pointing to this or that website or book may help, but may not be what’s best.

    • Steve says:

      On the contrary, I think C/C++ is the best place to start, in order to get a basic understanding of what memory is, how pointers work, etc.

      Once you know that, *then* you can move on to “friendlier” languages who hide all that nitty-gritty, and you will a) appreciate everything they do for you and b) have a clue wtf is happening when it goes wrong.

      • Kdansky says:

        Next up:

        Learning how to drive an F1 car is the best way to learn to drive. Because if you can drive an F1 car, a slow street car will surely not be an issue any more.

        Should you learn about pointers, references, memory, heap, stack and templates at some point? Damn yes! But don’t start there.

        • Daimbert says:

          A better analogy might be: learn to drive on a standard car instead of an automatic. Pointers and memory are a pain, but in small programs they’re manageable and you learn how to use them, so that you don’t just ignore them and screw things up.

  9. DancePuppets says:

    I wonder how much of this is down to people learning to code within academia. In physics we learn to code rather than any software engineering as the only thing we care about is that the program produces results that are self-consistent and that when known values are fed in it outputs something that makes sense. This means that programs coded by physicists are, in general, very ugly, dirty ways of doing a job, are generally slow, incompatible across multiple platforms, hard to use and impossible to maintain (never go into a physics department and look at the code Shamus, I think you might rage a bit). Within academia this seems to be the general approach to programming so it would make sense if students studying computing were taught in very much the same way.

    • Darkness says:

      One of the funniest bugs I ever got to hear of was from a friend that did performance analysis on massively parallel systems. They ran a unix variant and this customers code would unexpectedly come to a screeching halt every now and then. Then it would run like the blazes for a little longer only to grind to another halt. My friend was doing the profiling on it and found this:

      When getting the time in the fortran program the scientist used
      system(“date > /tmp/timexxxx”) and then parsed the resulting file.
      Multiple nodes all calling system which caused a fork which called a system command which caused another fork. Followed by every single node creating and opening files in the system node /tmp directory.

      Nope, didn’t know what gettimeofday did.
      This way had always worked.

  10. Anon says:

    I suggest you to read:
    Teach Yourself Programming in Ten Years
    by Peter Norvig (Director of Research @ Google)

    • Jeff says:

      …Google hires rocket scientists. Holy moly.

      • Kyte says:

        iD Software was founded by a rocket scientist!

        • Alexander The 1st says:

          Well, to be fair, rocket science is kind of dead right now (Last space shuttle launch for NASA, anyone?)- they have to get a job somewhere…

          • Veloxyll says:

            Since the shuttle is retired now, one would expect the demand for rocket scientists to go UP, since if NASA wants to launch rockets made in America they will need a new design. Plus there are other places in the world where they’re developing rockets :P

            And given the space shuttle has been shuttling for a long time, it would likely have needed rocket engineers to just keep things working, rather than scientists!

  11. Samopsa says:

    I did the first year of computer science here in The Netherlands, at university (2005). Two courses, both about 150 hours, taught object-oriented programming using java as a code. So no syntax (that was up to yourself to find), but how to construct logical function and such, including recursion etc. Another two courses focused on designing software, one using class diagrams to use for your object-oriented program. We used eclipse I believe, which can use a class diagram as basis for your programming.

    So, in short: you learn how to make programs, the coding (syntax etc) is seen as something easy and logical, and not much time is spent on that part.

    Obviously, lots of beginner errors are in the syntax and not knowing what tools are available, but those are ironed out during coding sessions with help of teachers and older students.

    edit: I switched studies later to chemical engineering, and now it’s the other way around: you need to program some stuff, but nobody has even heard about object-oriented programming, and everybody sees programming as a glorified calculator. People who learn programming from another academic source besides computer science will probably suck at it.

  12. psivamp says:

    In my experience (two classes at my university), universities don’t so much teach you the basics syntax and grammar of a language as filter out those who don’t already know and can’t learn from the overpriced book they assigned you.

    It was really disappointing as someone who already knew how to write code to go to lecture three days a week and watch our instructor either bore and confuse or mislead the other students. At the end of the course, we rewrote a primitive version of PacMan over two weeks. After the end of classes, people were still IMing me trying to get the first week’s portion of the project to work properly.

    Now, these are first-year classes and I haven’t and probably won’t take any higher-level classes because they’re outside my major and I don’t have time, but at this basic level our curriculum failed utterly. I pointed my fellow students to Sams books because they do a good job of teaching you to code — provided you can learn from a book and think in the necessary fashion.

    Edit: I can code in a couple languages, but I wouldn’t really say that I can develop or program.

  13. ccesarano says:

    I’m curious about learning C# these days, though it pretty much limits you exclusively to Microsoft machines.

    It is funny, though, that in my job we have so many files being used by so many programmers, and we all have different ways of writing code. Often enough I’ve found myself taking five lines of code and squishing them into one line. It’s not so readable, but it requires less thinking and effort on the computer’s part (and when you are treating Javascript in IE like an Object Oriented programming language, that is precious).

    I do miss the days when I’d just develop a website by myself with my own code and no one else’s.

    • Simon Buchan says:

      Mono is crazy well developed, if you want to use C# cross-platform. It can even compile against and load MS-compiled assemblies, not to mention a whole bunch of crazy features like a eval loop and compiling to native code.

      If you’re worried about file size for Javascript, use a minifier, it can do it far better than you. Myself, I’ve found Javascript much nicer to use when you treat it like a functional language rather than trying to force classes onto it. Prototypes are useless :(.

    • some random dood says:

      Arrrgghhh! I *hate* hearing this stuff! “Often enough I’ve found myself taking five lines of code and squishing them into one line. It’s not so readable, but it requires less thinking and effort on the computer’s part…”. Premature optimisation – did you actually *check* that the code in question is slow and needed to be optimised, or was it simply thinking “I am a clever ****, so I’ll just do this – and *of course* I’ll always remember what this compressed stuff does, and anyone else coming behind me will see what it does obviously!” As you were talking about javascript performance, I bet you didn’t even comment the stuff because comments slow down interpreted languages…
      Please reconsider your methodology – and go back and actually time the difference that the optimisation made in reality. Not just in say 10,000 loops over the unit in question, but over several runs of the entire software in typical usage – normally the “clever” stuff turns out to be totally unneeded, and clear, commented code performs acceptably fast enough with the advantage for maintainability as well.

      • Kdansky says:

        Beaten to it. Never ever* cram five lines into one if readability suffers. Do it if it improves readability.

        *Exceptions: For experts only. If you are not sure if you belong into this category, then you don’t belong into this category. And if you think you know everything, you also do not belong into this category.

        • Alex the Elder says:

          /signed

          I have a habit of doing exactly the reverse of what ccesarano does, though I stop short of adding comments, as many programmers seem to view adding inline comments as an act of war (and god help you if you try to start writing actual documentation).

      • ccesarano says:

        I actually do comment stuff if it seems confusing. However, lines are at a premium, and the general consensus around here is “if it can be done in one line, then do it in one line”.

        Which is pretty much how I learned about ? : being a short version of an if/else statement. Of course, since it isn’t taught in a widespread fashion, a lot of people don’t recognize it. In the end, however, it’s much better to include (once you know what you’re looking at). That’s the sort of thing I’m talking about replacing.

        • Kyte says:

          I’m yet to see a single platform incapable of dealing with too-long files. (Ok, not wholly true. Both the JVM and the CLR choke on overlong methods, but we’re talking like >64k bytes per method) Moreover, refactoring code to multiple functions and/or files is absolutely trivial. There’s no reason to try and minimize LOC. If you wanna reduce the download size of your JS, that’s what minifiers‘re for.

          • Johannes Luber says:

            Small correction: The CLR does not suffer from this 64k limitation. I’ve been involved with ANTLR, a compiler generator, and I’ve never seen anyone complaining about such a limit except for Java users who had the misfortune that the generated code ended up too long.

        • kikito says:

          Don’t add comments to confusing stuff. Rewrite the confusing stuff until it’s not confusing any more.

    • Garden Ninja says:

      I’m curious about learning C# these days, though it pretty much limits you exclusively to Microsoft machines.

      C# is an ECMA standard, and there is Mono, so it’s possible to write cross platform if you stick to avoid Microsoft specific APIs (anything under the Microsoft.* namespace tree; anything under System.* should be safe). We’re a MS shop at work, and I don’t use C# for my personal projects so I don’t know how practical it is, but I know that at least the Banshee music player uses it.

      It’s not so readable, but it requires less thinking and effort on the computer’s part (and when you are treating Javascript in IE like an Object Oriented programming language, that is precious).

      I have to take issue with this. That is absolutely the wrong way to look at things. By combining those 5 lines into 1, you have, by your own admission, made it harder to read, thereby making it harder to maintain, and programmer time is far more important than computer time. JS is interpreted and therefore kind of slow, and typically lacks a decent optimizer. However, changes like combining lines (presumably you mean removing assignments to temp variables, or something similar) are only going to produce minuscule performance gains. If performance is really a problem, then there are better places to look for larger gains. Attack the large performance areas first, then, if it’s still not good enough, worry about the smaller ones.

      • krellen says:

        There’s also no guarantee that turning five lines into one actually saves the computer any time, except maybe on compile. If the two solutions generate the same result, it’s likely the machine code for both is similar enough to be the same anyway.

        • True enough for a compiled language, but for an interpreted language like JavaScript the compile time has to be factored in every time that the page is loaded (at least)

          I probably still wouldn’t compact the five lines into one unless I measurably had bad performance for that code

          • Garden Ninja says:

            To expand on what Krellen and phobiandarkroom said, I suppose I could have been more correct by saying “produce, at best, minuscule performance gains”, but I was thinking in terms of JS specifically; that’s what the comment about lack of an optimizer was referring to. In compiled languages, that have an optimizer, temp variables and the like are probably going to be optimized away. C++, Java, C# etc can do this. Something like Haskell, which gives even strong guarantees about the code can, in theory, do even more (see the work on Supercompilation). Something like Python, which is compiled to bytecode before interpretation could do some optimization also, though I don’t know whether it does.

            In wholly-interpreted languages, without an optimizer, assignments will take a small measure of time. The point was just that that bit of time is so small, even in something like JS, that it isn’t worth worrying about. At all. If you are at the point where you are worrying about sub-millisecond gains in your JS app, you are better off rewriting the dang thing (or parts of it) in something faster.

            • Simon Buchan says:

              Python (at least, standard “CPython”) caches the bytecode of imported modules (but not the entry script) on the first load, but there’s no real optimization. Most of the performance effort of CPython has gone into making the interpreter faster. PyPy is supposed to be a pretty heavily optimizing Python implementation, I hear?

    • Duffy says:

      For windows stuff C# is awesome. It’s like C++ and Java had a baby with very few of the cluttering or weird rules of either.

      • 4th Dimension says:

        Yup. You want to produce a window NOW:

        Form Window=new Form(“Window title”);
        Window.Show();

        you want to process 100 objects parallely (multithreading)?

        Parallel.ForEach(ArrayOfObjects, ProcessingFunction);

    • TehShrike says:

      “Programs should be written for people to read, and only incidentally for machines to execute.”

      “Any fool can write code that a computer can understand. Good programmers write code that humans can understand.” — Martin Fowler

      http://stackoverflow.com/questions/522828/is-code-for-computers-or-for-people

  14. Guðmundur says:

    I have always thought of programming languages being tools rather than programming itself while programming is about problem solving. For instance if you write a novel the language you use can differ but you will most likely keep the same plot no matter what language used. One of my courses at university actually had us start with creating algorithms which I found appropriate, since problem solving is more relevant than syntax, and then moved onto C++. Although at college I got the kind of education where it was more about doing stuff and less thinking about stuff, which I always regretted.

    And if you think college is expensive, here in Iceland college is 24.000 for one (maybe two) semester while university (at least the one I attend) is 162.000 for one semester.

    • Alex the Elder says:

      That sounds like exactly the correct way to go about things. I would have benefited immensely from a course like that. Hell, I would STILL benefit immensely from a course like that. :-/

    • Peter H. Coffin says:

      For for currency-impaired US audience, the second figure is about US$1400 per semester. University of Wisconsin’s flagship campus charges state residents $4200 per semester, and out-of-state students $12000.

  15. Jordi says:

    I think that unless you’re actually studying Software Engineering, a lot of the programming courses tend to just try and teach you the basics of programming. When I was taught C++ and I asked about why we weren’t taught anything about header files and project organization, the answer was that that stuff was pretty specific to C++ and they just wanted to teach me the basics of programming. They were very explicitly not trying to train programmers or software engineers, but computer scientists.

    Most practical things would have to be learned in practice, and that is why stuff like profiling and source control never came up. I think that is a huge shame (although it did of course free up space for other courses), because that would have been massively useful for me today.

    I do think that pointing someone who wants to learn programming/C++ to a tutorial like “Teach Yourself C++ in 21 Days” is a good way to go. After all, this is how a lot of (self-taught) people start. However, you need to accompany that advice with the warning that it is actually going to take a lot longer than 21 days to know anything more than the barest basics.

  16. Stranger says:

    I took “Introduction to Ansi C” at my college. I got a B+ in the course, but I don’t recall much of the material now other than it was deadly outdated when I was taking it. Outdated in the sense of “this is a start of a foundation on how to code programs, but this particular language and way of expressing it is not in use this way today”.

    It’s akin to the difference, the vast distance, between these two courses: “English Composition I” and “Creative Writing: Short Story Writing”. Let alone the leap into “Creative Writing: Novellas” . . . the first in the list taught you how to write sentences which were technically, grammatically correct. The second one was about how to make a story in less than X words which was complete and self-contained.

    Novellas, the first thing the teacher said was the length varied from “longer than a short story” to “a little less than a novel”. This is like trying to define the difference between a creek, a stream, a river, or a bay. All of them are bodies of water, but the definitions are fluid.

    And trying to take Comp-Sci courses alongside Engineering courses was a *big* mistake on my part. There was insanely more work than I was ready for despite my advisor pretty much looking at it and going: “Well sure you can take Differential Equations and AC Circuits I concurrently, that’s how it’s set up in the program description.” (NB: Advisor was not from the engineering department.) So I had the lovely joy of taking a class stemming from the aforementioned Ansi C introduction alongside . . . both these classes. On top of needing to find a job to start working to move out of my parents’ house . . .

    I actually can look back and see the *month* my sanity snapped and I just abandoned college altogether. It’s a pity I don’t have the option of loading a previous saved game and trying again.

    • Alex the Elder says:

      This is like trying to define the difference between a creek, a stream, a river, or a bay. All of them are bodies of water, but the definitions are fluid.

      I see what you did there.

    • I know how you feel, I very stupidly went in for Computer Engineering in my First College Foray. What a disaster. Most of it was my fault for being such a useless . . . um . . . person, but a fair portion of the blame gets assigned to idiots who gave me incredibly bad advice or pushed me into stuff I could in no way handle.

      My 2nd and 3rd College Forays went no better. So I’ve decided formally that I am NOT DOING ANY MORE COLLEGE. If I need to learn something, I’m going to teach myself. It may be difficult and ugly and incomplete, but at least at the end, I can say that the stuff I’ve learned, I have LEARNED.

    • houser2112 says:

      “Well sure you can take Differential Equations and AC Circuits I concurrently, that’s how it’s set up in the program description.”

      It was worse for me when I studied EE at SUNY Buffalo:
      1st Sem: Calc I, Chem I, Physics I
      2nd Sem: Calc II, Chem II, Physics II
      3rd Sem: Calc III, Physics III, Circuits I
      4th Sem: DiffEq, Circuits II, Mechanics

      They set it up that way so all engineering disciplines have (more or less) the same first two years. It’s a very grueling couple of years, and I transferred to a more sane EE department at RIT.

  17. guiguiBob says:

    Learning design patterns and the importance of coding standards is much more important to becoming a good programmer than the language specifics. For me the laguage is a tool you use. Knowing what to do with it and how it will all fit together in the end is what teachers should focus. How to use iterative and control structures, how to handle Source control to manage the code produced by the team.

    The way a lot of teaching computer science is done is like we teach someone how to use a hammer and then when you arrive in the workplace, they hand you the plan of the house and expect you to build it. That’s if you are lucky to be handed a plan and not some vague description of what it’s supposed to look like in the end.

    I didn’t learn to be a good programmer until I met with a much more experienced programmer who taught me. Then I went after books that taught me the more important skills. Still much to learn but learning a new language can be done in 21 day. Learning to be a good programmer… I think it takes as much time as to learn how to be a good writer.

  18. Canthros says:

    Like CrushU, I took a couple quarters of Software Engineering while I was working on a CS degree (unlike CrushU, this was a decade or so ago). At least at the time, the focus was less on organizing code and projects and more on conceptual organization and SDLC. Lots of stuff about UML & Rational Rose and Waterfall. A teensy bit about Agile, I think, which was just emerging at the time.

    I’ve spent all but the first three months of my post-college working life employed by companies that don’t do software as their primary business.

    This has given me a couple observations:
    1. Software engineering is a relatively young discipline, and grew from the comparatively abstract background of applied math (where most other engineering disciplines have their background in the physical sciences). As a result, I think we’re still figuring out, internalizing, and disseminating a lot of the rules of software, and I’m not sure how many of those rules will be carried forward as the discipline matures, even if they’re important right now.
    2. The vast bulk of software engineering gets done (often badly) in a great many organizations that are otherwise completely unconcerned with either software or engineering. What I learned about software engineering process in college has been largely unapplied in real-world practice. Not for lack of desire, but for lack of organizational support. We’re still struggling with waterfall, here.

    As for places to start, Sommerville’s book, Software Engineering, was used as a text when I was in college (I’ll have to check my copy to see what’s in it), and The Mythical Man-Month probably is the best elaboration of the most-often-missed quirk of software project management of which I’m aware. The Pragmatic Programmer (which I’ve never managed to finish) also comes highly recommended, as does McConnell’s Writing Solid Code (which I did finish and liked, but is less about software design than programming practice). Steve Krug’s Don’t Make Me Think! may also be worth investigating, but is about web design in particular, rather than software design in general.

    ETA: that came out so much longer than I expected.

    • Canthros says:

      Tom Wilson’s comment below, mentions Code Complete, which is written by McConnell, which I have confused with Writing Solid Code, which is by Steve Maguire. IIRC, I’ve read both, but I couldn’t tell you which was about what. (I think I had the Maguire book in mind, but it’s been a decade since I read either.) Either or both is a good choice, but Writing Solid Code may be less applicable, given it is focused on C.

  19. Jabor says:

    Honestly, I think anyone going into it with the mindset of “learning C++” is already on the back foot.

    What you really want is to learn to program. Once you know how to program, picking up a given language is fairly trivial.

    (As long as it’s a fairly similar paradigm, of course – even if you’re a master of imperative programming it’s still going to take a bit of effort to learn Haskell or Prolog)

  20. Sem says:

    Well, I have to agree about your observations about school. (Note : I live in Belgium so my viewpoint only applies to the Belgian educational system but it echoes what Shamus says so I suspect that it is a general problem). I first tried for a master at University but failed on the math. University was half pure mathematics courses and half programming courses that where mathematics in disguise. That’s not exactly wrong but that’s not what writing software is about. IMHO, it’s like learning chemistry so that you can cook.

    Then I tried for a bachelor which exaggerated in the other direction : not enough math or basic grounding in logic. We had one math course but that was just a recap of high school and had no connection whatsoever to programming. The only course that was good in the theoretical aspect was database design that started with basic theory about the relational model. All other courses where basically learning the syntax of a programming language (I had Java, Cobol & XML).

    However, in both cases, no source control, no methodology (agile, xp, …). Nothing about controlling complexity in a software project (We had one design class but that was basically about parroting back what the teacher said. Deeper understanding wasn’t really present.)

    I read one essay (I think from Paul Graham but I’m not sure) that writing software is more like a craft and should be taught like one. In my experience, the master courses treated it like a science while the bachelor courses thought that learning by heart would work.

    Although, if you have to pick one of the two, a master is the better choice. If you can learn all the math, you can surely learn software design. If have a bit of inferiority complex in that regard. I think math is important to foster logic in general which is always a plus in software but my motivation to learn it is rather on the low side unfortunately.

    • Peter H. Coffin says:

      IMHO, it’s like learning chemistry so that you can cook.

      Amusingly, this is exactly how I cook. It’s all about buffering, leavening, controlling hydration and drying, protein and starch behavior, and balancing sugars, salts, etc.

      • Mephane says:

        Of course cooking is all about chemistry, what he was saying is you don’t have to set up a reaction equation, calculate the enthalpy, find out whether the reaction is exotherm or endotherm just in order to make pizza. Sure if you know the pure hard science behind it there may be a benefit in very specific circumstances, but more often than not it doesn’t bring you forward. Heh.

  21. Tom Wilson says:

    I like Code Complete for the practical side of how to put programs together without regard to the specific language you’re using. One of my favorite bits: “Favor read-time convenience over write-time convenience. Code is read far more times than it’s written…”

    • Alan De Smet says:

      I should re-read that; it’s been a while. I remember really, really liking it.

    • dman says:

      +1 on that book.
      I still re-read it occasionally. Although the examples are either language-agnostic pseudo-code or very dated, the book is about what to do, and how to do it – in general approaches, with good dollops of WHY as well as (somewhat dated) cited metrics on general practices.

      “Code Complete” IS the book that describes actual code practices and not just syntax.

      I still curse that version control and package deployment was skimmed over with a single exercise (each) in my second year university CS course – considering it is what I spent so much time getting myself and others up to speed with (eventually) in the real world.
      … yet I never wrote my own sort algorithm – a solved-problem task which feels like it dominated the first third of the first year. O_o

  22. Eddie says:

    I feel the need to point out that while the Holly Hop Drive had a very simple interface, it didn’t actually work as intended and had the end result of getting Lister pregnant.

  23. Factoid says:

    As a university graduate who majored in C++ and is guilty of most of the numbered items you mentioned I will say this: In Programming 101, when we did basically this exact Hello World program…not one person asked a single one of those questions. Most of them were too busy looking like a deer in headlights to even absorb the first piece of code.

    Also I’m pretty sure they still had use use iostream.h, even though you can omit the .h in that case…..so there’s that.

    But you’re absolutely right about C++ programming. It’s woefully inadequate the way it’s taught. I spent 4 years learning how to write console programs. I learned a lot of terrific theory. I learned how compilers work, how scripting languages are written, how data structures and vectors and algorithms all work…which is absolutely essential stuff, but never learned how to make ANY of it apply to a real-world situation.

    • Factoid says:

      Edit: I didn’t major in C++. I majored in Computer Science. Though sometimes it feels like I majored in C++. I don’t think I’ve written a line of C++ since I graduated, though.

    • Kyte says:

      I’m curious. My university has exposed us (to date) to C, C++, C# (& MS SQL), Java (& Oracle DB), PHP (& PostgreSQL), (plus MySQl), Python, Perl, Scheme & Prolog for various classes. (Namely, Data Structures, Information Retrieval/Databases & Programming Languages, for the 2, 3(+4) and 4 respective langs)
      In short, they tried their damnedest to throw us head-first into the “program anything” mindset. Is that really uncommon? I often see rants about how “java is not a good language to learn” or “I graduated learning C++” or etc., strongly implying they didn’t learn any other language. Is that so?

      PS: And apparently they’re also the exception when it comes to “real-world” projects, by having an entire course that can be summed up as “Get a client and make them a software. If it sells and it’s good, you pass.”

  24. Simon Buchan says:

    You learn how to program (not even Software Engineering, which is a *much* bigger task than just knowing how to split up your files or use source control) by being around better programmers. Code reviews especially are brilliant – obvious mistakes get caught earlier, and good design and neat tricks can get picked up. It also encourages readable code, something that everyone thinks is important, but never gets done.

    BEGIN NITPICKING MODE:

    A slightly fairer WNDCLASS-registration:

    // size is always first, default initialize the rest. IDI_APPLICATION is default
    WNDCLASSEX wc = { sizeof(wc) };
    wc.lpfnWndProc   = WndProc;
    wc.hInstance     = hInstance;
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    // Yeah, this is ugly. I normally want to skip WM_ERASEBKGND anyway, so I leave this default too.
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    so I leave this default.
    wc.lpszClassName = g_szClassName;
    RegisterClassEx(&wc);
    

    Even if you don’t want IDI_APPLICATION, there’s really no point using RegisterClassEx() if you load the same icon for hIcon and hIconSm: RegisterClass() defaults it for you. Ex() exists because LoadIcon() loads the system icon size SM_CXICON, SM_CYICON (get their values with GetSystemMetrics()), but the small icon size SM_CXSMICON, SM_CYSMICON is needed for headers. If you want to do that properly, you have to load the hIconSm with LoadImage(), giving the system small icon size SM_CXSMICON, SM_CYSMICON as the size. Yep, it’s pretty ugly. Use this:

    HICON LoadIconSm(HINSTANCE hInstance, LPCTSTR lpIconName) {
        return (HICON)LoadImage(hInstance, lpIconName, IMAGE_ICON,
                                GetSystemMetrics(SM_CXSMICON),
                                GetSystemMetrics(SM_CYSMICON),
                                hInstance ? 0 : LR_SHARED);
    }
    

    The reason the Windows API is uglier than the SDL API is pretty simple. It wants to support all the functionality of the OS as it can with as few bytes of code between you and it as possible, since it is the lowest possible level. Along with being designed in the days when saving a few dozen *bytes* could mean fitting another feature in, that means you get APIs designed to the machine, not the person. I used to wrap up CreateWindow() and friends, but I’ve needed to twiddle those knobs just often enough that I just smack it at the top of Init() now.

    I don’t really see how swapping “<iostream>” for “<stdio.h>” and “std::cout <<” for “printf(” “)” makes hello world that much easier for a newbie (regardless of how nice printf is vs. C++ streams for actual use). You don’t *have* to explain namespaces – just treat all the standard names like they just start with “std::”, which is all a namespace really is (in C++). Then before they start complain about having to type 5 chars for everything, let them know they can shorten names with “using” (and hopefully, when you start teaching the writing of header files, when *not* to use it).

    *whew*. Sorry for the text dump! I need to let off steam on stackoverflow more often :/.

    • Alex the Elder says:

      A better programmer who can stand to be around beginning programmers, even online, is a rare blessing. Even more so if he allows them to ask questions, and vastly more so if he answers them.

    • Blake says:

      “I don’t really see how swapping “” for “” and “std::cout <<” for “printf(” “)” makes hello world that much easier for a newbie (regardless of how nice printf is vs. C++ streams for actual use)."

      Then you're like most uni lecturers ever. Also: you're wrong.

      'std::cout <<' is bloody confusing. It took me a long time to find out that std::cout is an instance of an object created in another library somewhere with an overloaded << operator (the sort of thing that would probably get you fired/drawn and quartered if you wrote it yourself in a professional environment).

      printf("Text"); Is nice and easy, you say 'the stuff between the quotes gets passed into the function which prints things'.
      It works just like almost everything you're ever going to write and does what it says on the box.

      As for "#include ” instead of “#include “, it’s another case where the one with the “.h” is just like what you’re going to do, you can tell people it’ll copy in the contents of the file with the exact same name, you could even get them to #include the entire file path to make it extemely obvious whats going on.

      C++ has so much going on and it’s really easy to overload someone who’s busy trying to learn how to use a variable.

      • Alan De Smet says:

        To be fair, “#include <iostream>” behaves identically to “#include <stdio.h>”. The former looks for and textually includes a file called “iostream”, while the latter includes a file called “stdio.h”. It just happens that the C++ committee decided that the “.h” extension was deadweight and didn’t use it for C++. Of course in practice you’ll see lots of .hs, since most C++ programs use at least a little C, and most C++ programmers kept on using the .h for their own files since extensions for identification are handy.

  25. Nathon says:

    K&R introduces the tutorial bit (in which “hello, world” is introduced) with this:

    “…Our aim is to show the essential elements of the language in real programs, but without getting bogged down in details, rules, and exceptions. At this point, we are not trying to be complete or even precise (save that the examples are meant to be correct). We want to get you as quickly as possible to the point where you can write useful programs, and to do that we have to concentrate on the basics: variables and constants, arithmetic, control flow, functions, and the rudiments of input and output…”

    I would argue that there aren’t any books about particular programming languages that a new programmer should read. There are books that use a particular programming language to teach programming concepts (like SICP but once you’ve learned the concepts languages are pretty easy to pick up.

    Trying to learn to program from a book called “Learn C++ In 21 Days” is like trying to learn to fly fish from a book called “501 Fly Fishing Knots.” It will teach you skills that are necessary but not sufficient.

  26. The issue with the createwindow example is unfortunate but needed,
    MicroSoft simply can’t change it or they would break millions of programs (hardly an overstatement these days), including SDL.

    MicroSoft slowly but surely adds extended or new API’s that replace the old ones, but they will not remove old ones until their statistics says that no users uses a program that still uses the old API they wish to retire for good.

    And if MicroSoft does try to move things along artificially, then people complain that Windows is not compatible and sucks since their old crappy program that uses SDL v0.1 no longer works on Windows 7 for example, as opposed to using the latest SDL version and so on.

    Just to clarify things, there are Windows APIs where all the defaults are exactly what 90% of all programmers need, and the remaining 10% only need to tweak a few defaults to be satisfied.
    Usually these are more planned API sets or more future proof APIs (by accident or design), as it is very difficult to guess what all defaults should be before people have actually begun to use the API at all.

    Oh and please note that the SDL example is kinda deceptive as I believe that actually fires up DirectX as well and sets up a actual fullscreen or windowed DirectX screen. Maybe you should have found a Windowed DirectX example, but that would have doubled the length of your post Shamus so maybe not…

    There is a lot of wrappers out there, the “official” ones are ATL, MFC, think-I’m-missing-one, .Net/#Net/whatever/C#, and many specialized ones like SDL etc.

    On top of that each programmer tends to make their own wrappers with the wrapper, because what is the point of typing something more than once right?

    Which is something that irks me. A programmer that makes a wrapper that wraps some wrapping API that wraps a OS API.
    In situations like that I prefer to instead simply write a wrapping function that uses the OS API directly to reduce the reliance on a intermediary wrapper.

    Sometimes my own wrapper is used across several of my own programs, other times a wrapper is rather specific to a single project.
    And if any porting is ever needed just replace the OS specific code within that function and that’s it.
    This also makes it easier to take advantage of new API calls or changes that a new OS version might bring, making it rather cheap to let your program follow the OS progress over the years.

    I’m not dissing SDL or any other wrappers or middleware, I’m just saying that it’s even better when it doesn’t matter if you use SDL or or some other middleware, or OS API calls. If you code well enough it should be easy (even for a different coder) to rip out the GUI stuff and replace it with another without breaking the entire program.

    I have to agree with you wholeheartedly though Shamus when it comes to header files and such, it is often I see people post on the net asking for help to p/invoke something in .net get an answer and just do it, but have zero clue about the Win32 API or header files, no wonder so much software leaks memory or is unstable.

    People know how to make software, but they are not necessarily a programmer, creepy!

    • Nathon says:

      SDL’s utility goes beyond having a nicer interface than Microsoft’s. It’s also way easier to port SDL code to a different platform, since the real effort is already done for you. Wrapping a wrapper is sometimes the best way to go. Plus, this is initialization code so an extra function call has approximately zero impact on performance.

      • Oh I don’t argue with that. I love middleware done right.
        The issue is that it becomes a black box and you do not know what happens underneath. And if you are unlucky the middleware you use has bugs or issues on some systems or is rarely updated.
        If you know how things worked you could write a “proper” workaround or an alternative until the middleware catches up.

        What I’m saying is that there is (like Shamus says) a difference between knowing how to make programs and knowing how to actually program.

        There are “programmers” out there that barely grasps the concept of proper IF THEN ELSE ENDIF use.

        I can probably take any programming language and be able to use it, using just a text editor and a compiler for the language. (and the internet for referencing, without the internet I’d probably have given up programming… If you know how to search right you find good and bad examples)

        You also need a personal (native?) ability of logical programming, there is so much insane things people do when coding that it’s almost borderline insanity.

  27. Daemian Lucifer says:

    I love the simplicity of your kill all humans program.

    “Hey sexy mama.Wanna kill all humans?”

  28. Fat Tony says:

    Hey shamus one of your “Ads” leads to this “Totally NOT a scam” site:

    http://www.prizefun.com/

    From an ad that said: “You’ve received on new tweet”, I don’t even have twitter sooo, yeah. It looks like a little blue bird flying in place with a letter in it’s mouth incase this helps in anyway.

    No viruses or anything either it’s just an arsehole bait ‘n switch ad.
    (sorry i did take a screenshot but my clipboard feaked out when i tried to open it as an image and forgot it”

  29. William Newman says:

    A significant fraction of the knowledge you’re describing ends up being quite specific to a particular environment: the kind of material that used to be given out by the sysadmins at the university data center pertaining to their particular environment rather than taught by the professors about programming in general. It’s hard to give general advice about learning such specific knowledge.

    For the more general knowledge, Stroustrup’s _The C++ Programming Language_ has a fair amount of discussion of the kinds of issues you described. You might also point people at the _The Pragmatic Programmer_ (which I like better than _Code Complete_ that someone already mentioned in this discussion, although that’s OK too). And when one gets serious about the organization of C++ programs into separately compiled and maintained units, it’s a big subject: it’s a chapter or so in books like Vandevoorde and Josuttis _C++ Templates_, and it pervades the entire book in Lakos _Large-Scale C++ Software Design_.

    If someone asked me how to learn to program, I’d probably recommend first learning and practicing writing little programs in an environment which gives quick feedback (by among other things supporting “hello, world!” implemented in a single line of code), then learning something about algorithms and data structures (not enough to understand everything in _Introduction to Algorithms_, but at least enough to guess when there’s likely to be a known elegant solution and to guess where to look it up), and only after those two stages spending any effort on projects of more than a few hundred lines. Time spent thinking about the issues you describe is time well spent at any time in this process, but they only really start to be vital on projects of more than a hundred lines, and there’s a lot to learn — I think at least hundreds of hours of study and practice for most people — getting fluent with projects of only one hundred lines or so.

    For many kinds of programming, understanding how to represent data in a way that fits smoothly with the problem at hand is at least as important as the algorithms and algorithm-oriented data structures taught in something like _Introduction to Algorithms_. Alas, I don’t know any single text that really nails the basics of such problem-domain representation decisions the way that a good algorithms text nails the basics of implementation-domain representation decisions. (An example of the first kind of decision is when to use an is-a relationship instead of a has-a relationship. An example of the second kind of decision is when to use a hash table or a linked list or a vector or a priority queue.) Several of the books I mentioned do have a significant amount of discussion of it, though.

  30. RPharazon says:

    As a pilot (and an amateurish personal programmer), I find the programming education world’s lack of practical teaching of the field to be a bit mindboggling. If what all of you are saying is right, then you can go through an entire Bachelor’s degree in Computer Science, learning to code, but not apply it in a useful manner that allows you to make, say, something akin to Shamus’ project?

    That’s very, very strange.
    I mean, in my aviation diploma course, we learn a whole bunch of theory, but we also fly the planes themselves. And in the second year, we actually undergo a few classes about learning how to efficiently manage your crew and airplane. This is all practical knowledge that one will definitely use (and one needs) in pretty much any piloting job. That’s why I chose to do a university program, instead of just doing the standard “CPL + Ratings” sprint that so many flying clubs want you to do instead of taking aviation college courses.

    But it still boggles the mind as to the state of programming education.
    Here’s a little tip, that helped me learn Python with nothing more than a little patience and the Python documentation. For those with a mediocre mathematic mind or better, go to Project Euler. Work through the problems there. They teach you how to handle everything and how to make things work together, instead of simply teaching you theory. There’s everything from basic For loops to entire problems where you have to import a text file or two, translate it into something the program can use, rearrange it, and export it into another file, and submit the answer.

    It’s enough to get you a foundation of how to apply programming knowledge into real problems and real programs, and it’s even good as a teaching tool.

    Project Euler.

    • Nathon says:

      University CS graduates usually will have worked on one or two significant multi-coder projects. And they’ll have written hundreds of smaller solo programs. The problem is that they’re rarely required to do the kind of programming that they’ll do in the workplace. Computer Science is not what professional programmers do.

      The big things that don’t get taught enough in school are debugging (using actual debuggers) and how to read code (and write readable code). Most recent graduates I see (my past self included) will tend to favor compact and clever code over legible code. It’s worth optimizing for programmer time.

      • RPharazon says:

        Ah, fair enough. As for that readable code part, I’m not sure there’s an easy solution to that problem aside from forcing yourself, from the outset, to make readable code. Even if you’re self-taught, you’ll just end up making code that’s only readable by the present you. Friends and 5-months-after-I-make-a-program-Me can’t read my code, unless I put in big notes that explain everything.

        And at that point everyone complains because the notes can substantially increase the size of the source, or maybe people think it obtrusive. Whatever, if it saves me time later on.

        • Nathon says:

          That’s what makes it hard. It can still be done though.

        • psivamp says:

          On the other hand, bloating your source code with a five line explanation of what the heck you’re doing takes up almost no disk space, can be hidden in many IDEs and 5 months later can clue you in to what on earth that arcane loop was supposed to be doing — or what order these objects are sorted in the array you just defined.

          • Yup! With the speed and auto optimization of modern compilers and the memory and computing power of modern computers there is no reason to write overly tight code.
            Although I personally prefer oversimplified code than “clever and tight” code.

            The only tight code I write is in well, tight loops that repeats thousands of times, or code that need to return ASAP.

            Ideally the entire source of a project should be readable from the source (without comments), I only use comments when I need to really clarify something or point out a caveat.
            I also add a short comment to sections of code to make scrolling around and locating stuff easier.

            Then again I’m also one of those old farts that prefer the computer to do exactly as I tell it to do things. *grin*

            Hence why I prefer un-managed Win32 programming, if I allocate memory or a resource I also make sure to un-allocate it, and I prefer to not rely on garbage collectors. Good code should not need that safety net.

            I do not do unit testing as my code is made mostly in isolated chunks and are liberal in what it accept but strict in what it outputs. Sometimes I even make it strict on what it accepts and do proper error handling (internal, not end user errors) that makes sense.
            Profiling is rather nice to do, you often get surprised to find out what parts of your code is performed the most.
            You also tend to spot loops or parts of code that really shouldn’t be done that often.

            I also make sure to allocate and prepare data and values before going into a loop, thus the loop itself just does the datacrunching.
            I also avoid allocating memory more than necessary, I tend to allocate most at program start (work buffers etc), and minimize the need for allocation/de-allocation during running as much as possible.

            Sometimes I even rewrite a higher level language loop in ASM.
            Usually this is with extreme tight loops of just a few lines that does a lot of data processing repeatedly or incrementally, and using processor registers can sometimes speed that up a lot more.

            I also do my very best to ensure that a program is fully self-contained within it’s own folder, thus reducing dependencies to whatever the OS ships with.
            So besides the Install/uninstall part (so it can be un-installed from control panel) the programs folder could easily be copied from device to device or even to another computer and still work.

    • William Newman says:

      You write “That’s very, very strange. I mean, in my aviation diploma course, we learn a whole bunch of theory, but we also fly the planes themselves.”

      I’m not a huge fan of current CS education, I’m happy as a self-taught programmer (Ph. D. in Chemistry, no classes in programming since high school, and only about 2 semesters of programming instruction even there). However, the CS programs have (chosen) a difficult job in teaching people about the entire field. It’s a bit as though you were trained not to be a light aircraft pilot, but to get a BS in Vehicle Science. Unless you’re lucky, when you go to work and have to operate a forklift or a motorcycle or a bulldozer or a submarine or a zeppelin, it’s not going to closely resemble any of the vehicles that you have a lot of hands-on experience with. The kind of programming Shamus is writing about is different from simulating wavefunctions in quantum mechanics, or verifying the correctness of complex ICs, or writing flight control software, or writing a payroll system, or writing an optimizing compiler, or writing time-sensitive interrupt service routines for a microcontroller, or writing an system to cause Javascript running in web pages to play nicely through AJAX with a flexible system running back on the web server, or whatever. So when schools aim to prepare you not specifically for what Shamus is doing, but for all of this, the schools necessarily fall back to a certain level of generality.

    • Alan De Smet says:

      University programming has several challenges that make it hard to teach you how to “really” program.

      1. Some people are insistent that it’s Computer Science, not Computer Programming, and they won’t have their beautiful theory mussed up by actual implementation details. If you want Computer Programming, go to a technical college. These people are wankers.

      2. Even if they’re not wankers, many professors would prefer to focus on the theory side. After all, they did choose to go into academia.

      3. There is a hell of a lot of Computer Science to cover. A good undergraduate CS education is pretty crammed. It’s not (necessarily) as crammed as a typical engineering degree, but it’s enough to keep you busy even with only minimal practical aspects.

  31. Carra says:

    Code complete is a great start. It’s about programming, not the syntax of language X.

  32. Dev Null says:

    A fair point. And yet I’d argue that its very difficult to understand any kind of discussion of software engineering, without at least _some_ background in programming first. And by background, I really mean “some actual attempts to do things with code”, not “some one/book blathering content at me.” Which I think is where a lot of university CS courses fall down; they’re so desperate to cram everything into a 1 semester course that there’s never time to build something, then go back and look at what you built and see how it could have gone together better.

  33. J Greely says:

    The most entertaining moment in my incomplete CS education was a class that was nominally Systems Programming, but was actually Group Projects. We were divided into teams of four or five, and handed the job of creating a machine-language emulator, an assembler, and something else I don’t recall 26 years later (linker/loader, maybe?), all in Pascal, with accompanying user and developer documentation. We could divide up the tasks however we pleased, but all members had to sign off (literally) on each completed project. I ended up being the fifth member added to a group of four friends. This did not go well.

    For the first project, the emulator, I volunteered to write the developer docs, which made the others very happy. All they had to do was get their clean, modular, working code to me with enough lead time, and I’d write it up. I didn’t expect any problems; the pseudocode in the book was so clear that I couldn’t imagine anyone having serious trouble with it. In fact, that weekend, I was bored at my part-time job and wrote the whole thing myself, in Cobol.

    Three days before it was due, they caught me after class and said they were having trouble. I offered my assistance, and mentioned my weekend hack. “Can we turn yours in?”, they asked hopefully, missing the part about Cobol. Dejected, they went back to struggling. The night before it was due, they delivered the finished code to me. I spent the evening rearranging their spaghetti code into modules that I could document, and printed it all out for class.

    The next morning, they were thrilled with my work, and there was just one little snag: the guy who was writing the user documentation hadn’t shown up yet, and no one had any idea what he’d done. Two minutes before class, he showed up with a two-page “manual”, the first page of which was dominated by a giant smiley face drawn with a thick black magic marker.

    Things went downhill from there, but I’m sure the professor must have been delighted the day that I showed up five minutes before class and spent fifteen minutes publicly chewing them out for their total inability to follow a simple spec, and then stormed out. I think I got guest-lecturer credit for that day. :-)

    -j

    • Alexander The 1st says:

      The fact that you remember this 26 years later makes me scared to make a mistake while working with you – you sound like you’ll take that grudge to your grave. :p

      EDIT: But yeah, group projects where 4 people know each other and the 5th doesn’t as well never go smoothly.

      • J Greely says:

        It was the smiley face. Sometimes when I’m testing a thoroughly wrong-headed attempt at a bug fix, I’m grateful that at least the developer didn’t cover up his laziness with a magic marker.

        -j

  34. elias says:

    I don’t think “Hello World” is really intended for newbies. Sure, it tends to be the first thing they ever get shown, but for that purpose it’s pretty much useless in any language. To the extent that “Hello World” has any usefulness at all, it’s that it lets programmers get a vague idea at a glance how different a new language is from what they already know.

    • Ayegill says:

      +1. When you think about it, print “hello world”(which is python), doesn’t tell you more than the c++ example, and may even give you the wrong idea that all programming is similar to writing what you want the computer to do.

  35. Joe Cool says:

    Where should I go to learn programming? How about the book “Where I Should Go to Learn Programming”, by Shamus Young. It doesn’t teach anything about syntax or pointers. Instead, some of the topics introduced are how to:
    Create header files.
    Use external libraries (outside of the default libraries) in your own project.
    Deal with or consider cross-platform issues.
    Do anything, anything at all, with a windowed interface.
    Use profiling tools.
    Use source code control.

    What? A man can dream, can’t he?

  36. Zak McKracken says:

    I think learning _anything_ requires both theory and experience, and the latter cannot be taught, it has to be …. experienced?
    Imagine how someone drives who’s just got a driving licence, how not-quickly they react to unexpected situations, how bad theyr timing is, even just driving through a curve in a smooth arc without hitting the curb can be a difficult task.
    Same goes for pretty much any profession. You learn the basic stuff wherever it is that the basic stuff is learned, and the rest is learning on the job.
    So, for me the best way of learning pt program a specific language is having a project that demands this language, a good book on it, and someone I can ask if in doubt. That’s probably also what high school lessons are aiming to provide, although in a tight time frame, and with varying success.

    Regarding books: What’s your opinion on TAOCP?
    I have the suspicion that it’s more for people who develop programming languages rather than programmers, but I’ve not actually read it yet.

  37. Macca says:

    Just a quick heads up; I don’t know if anyone’s already mentioned this (though a quick ctrl+F suggests not) but you have a space between your less than signs in the Hello World program. Me and a friend thought that was weird so we tried it out just to make sure we weren’t just being dense (neither of us are exactly C++ programmers, but we both studied CS at university–and no, it didn’t teach me anything!), and sure enough it wouldn’t compile with the space. :)

    Felt inclined to edit to add more of my experience:
    I’m a web developer, whether I’m an actual programmer or not is entirely debatable but I went to university where we studied mainly Java. I learnt a lot of theory, including about MVC which did actually help a little bit when I started using object oriented PHP as opposed to the imperative style. I can’t however write much using Java. I probably couldn’t have written much using Java if I’d only taken my final exams yesterday. It took me ten years to really get my programming skills to the state they are in now and most of the useful things I know were self-taught, learned through working on real-life projects, or taught by genuine programmer friends. Now the main thing that stops me from picking up other languages is PRECISELY THE SYNTAX. But that wasn’t the case before now. :)

    • silver Harloe says:

      It’s not the syntax, it’s the libraries.

      From your experience, you could learn any language in a couple days. You would still spend years figuring out which libraries contained the bits you want pre-written, how to store your data so it’s easier to pass to and from the File interaction bits and whatnot. It’s the same for every language. The syntax is trivial – the idioms and best practices, which are almost always determined by the pre-installed and commonly available libraries, is the hard part.

      • Macca says:

        Also that, yup! Another conversation I was having the other day about my education and how little it actually taught me: I was queried about sorting algorithms, and explained that although I learnt about them in university I couldn’t remember the specifics by now. Then I was asked which method I would use in a program, and I just replied – “well, whatever function is already built in.”

        They love to teach algorithms in university but unless your job is reinventing the wheel for the 3809586th time, it’s useless.

        • Alan De Smet says:

          Yeah, generally speaking rolling your own sorting function is a waste of your time. It will almost certainly be slower and buggier than the library standard sorting function your language comes in. But… there is a value to understanding. It’s a lot easier to appreciate the expected and worst case Order of each sorting method when you’ve implemented at least a handful. Understanding the underpinnings so that you can make better educated decisions on a higher level is one of the key distinctions between a good computer science program at a university and a typical computer programming degree from a technical college.

      • Mephane says:

        The syntax is trivial – the idioms and best practices, which are almost always determined by the pre-installed and commonly available libraries, is the hard part.

        Quoted for truth. And that’s the very area where C++ is severely lacking. Sometimes for the mundanest task you have to find a 3rd party library or spend a day writing the code yourself (sometimes that is faster than getting that library to work). I remember writing my own base64 encoding/decoding function (basic stuff, base64 is used a lot when transmitting binary data on the internet) because the choice was

        a) a MFC function, which brought with it so many internal windows stuff that it basically broke other functionality and made the whole program suddenly non-portable
        b) a third party library that requires you a dozen DLLs just to link to the one which gives you the function (among hundreds of others), but that function requires 5 lines of C just to call it, plus C-style memory management for just doing the straightforward transformation array of raw bytes -> base64 string.

        Now whenever base64 comes up, I just include a single header, and just write base64::encode(source, dest).

        I bet it takes 2 minutes of googling to do achieve the same in C#. Yupp, instantly found: http://msdn.microsoft.com/en-us/library/dhx0d524.aspx

    • TehShrike says:

      Hey, I noticed that too! Glad I wasn’t the only one :-)

  38. DrMcCoy says:

    Slightly OT: “using namespace std” is in general a very bad idea. :P

  39. Anorak says:

    Hi everyone, just finished lurking after reading this blog for….a year? Ish? (Good job on everything, Shamus)

    I’d like to point out that taking “Computer Science” as a degree doesn’t always teach you how to code, at least it didn’t for me. I went to the University of Manchester, and unless you took something like the Software Engineering course, the Computer Science mostly contained…..science. And a lot of Maths.

    Yes, we were taught how to code, but what was far more common was being taught were more abstract concepts, that if you wanted you could then go and implement in code.

    I think my point is that Computer Science is not about programming. At least, it wasn’t for me.

    We did do a couple of Software Engineering modules, learned about Agile, Waterfall, Extreme, Scrum, etc, and UML. I ignored most of it. Now I’m working in a proper job, I wish I’d paid more attention.

    • Alan De Smet says:

      I think erring too hard into theory is an unfortunate direction that some CS departments go. It’s fine if your goal is to produce academics, but the majority of the students plan to work in industry. Theory is important, it’s the key distinction from a technical college, but it’s not everything. It’s like graduating with a degree in Chemistry or Chemical Engineering, but having no idea how to perform a titration.

      Also, I find it shameful whenever I encounter a graduate student who can’t write a Hello World program.

      • Anorak says:

        You’ve got a point: leaning too hard toward pure theory produces people who can’t code. There’s a great article on Coding Horror, despairing over the number of programmers who can’t complete the (Exceedingly simple) Fizz Buzz test.

        I exaggerated in my previous post, though. I spent a very large chunk of first year learning Java (mandatory), and a good chunk of 2nd year on c/c++. But when it came to pick your own modules, there was a great scope for pure theory. I like to think I took a balanced approach, but like I said : I really should have paid more attention to the Software Engineering stuff.

        • WJS says:

          Heh. I looked up the Fizz Buzz, my reaction was… interesting.
          “…Is this a trick question? It can’t be as simple as it looks… I know I’ve seen something like that before… that prime sieve I needed for a past project?” etc.
          …That probably says something about my personal level of paranoia, now that I think about it.

      • Zak McKracken says:

        Then again, the aim of computer science isn’t necessarily to “produce” programmers.
        It’s more about logic and understanding how stuff works, and in turn coming up with new ways to make stuff work. Many people I know who studied CS (or as it is called around here, “informatics”) go on to get jobs that are more about processing and organizing information and designing processes than “just” coding. And that can be anything from chip design to production management, from algorithm design (yep, there it is, coding) to development of business models.
        Also, not many people around here actually study pure CS, most have some flavour leaning towards science and numerics, simulation, economy, systems engineering or something.

        The first thing my favourite CS teacher at school did was turn the computers off and teach us boolean algebra. Then have us design logical circuits with just “and”, “or”, “not” and some storage cells in between. In the end we had a programmable calculator. That was an achievement, I tell you! And though I’ll never have to build a calculator, it not only feels good to know how stuff works, it also teaches you a way of thinking, and that’s the actual benefit. You don’t do push-ups in order to be better at push-ups*. You do it for fitness, and that’s a useful thing under many aspects, even if you don’t go on to become a professional athlete.

        * except if you’re training for a push-up competition of course! Still that might not be the best career choice.

      • Ander the Halfling Rogue says:

        Does not knowing how to write a Hello World program really happen much?

    • Natalie Bueno Vasquez says:

      …now I’m working in a proper job, I wish I’d paid more attention.

      That’s true of anyone, any degree, any time. ;)

  40. bickerdyke says:

    Where to go to learn programming…..

    I would dare to suggest the way I learned it….

    C64, CBM Basic V2

    when you’re stuck with that for 5 years (including a quick and fruitless stab at assembler), even simple things like local variables or functions seem godsent.

    And I still wish I had the chance somewhere at Uni, to do something simple with punchcards.

    • Zak McKracken says:

      I think learning anything the “historical” way is a really cool thing.
      That’s also why I like the simple “hello world” program a lot more than the C++ one.
      Actually, I think a lot of stuff should be taught that way. You will understand many things better if you know what was before them and which problems they’re meant to adress. Also it will in most disciplines give you a nice gradient from simple to complicated. Like learning to play videogames :)

  41. silver Harloe says:

    What you learn in an undergraduate CS program is how to talk about computers in theory. It’s right there in the title of the major: Computer Science, not Computer Programming. The professors study computers and teach how to study computers. We even had a professor (though he was a guru that undergraduates didn’t get to get near) who opined that if you were actually coding on a real computer, you weren’t learning science, you were just learning to hack things together. Partly this was a holdover from the days when you couldn’t recompile and retest in a few seconds, and had to spend more time being concerned about what you were going to compile before you wasted the computers time – and partly this was a perfectly valid (from his point of view) observation that studying programming is not the same thing as programming.

    To be fair, in my CS curriculum (UT from 1988-1992) I took a course called Software Engineering in which the programming project wasn’t just “a group project” – it was a project started by other people in previous semesters, which would continue after we left. Each team was given a list of bugs to fix and new features to add. We didn’t get to pick the language or environment or hardware. We had to figure out the previous peoples’ code without their help (unless they left any documentation) and then had limited time to fix any incomprehensibility issues because we still had real bugs to fix and features to add. In a word, for a semester, it was just like having a programming job.

    Still, I get the impression this was an exceptional course. The problem is the “jobs world” places too much faith in degrees when what we really need to make more good programmers are programming apprenticeships. Which is not to say I learned nothing of use in my university classes – without them I probably would not have done any Lisp (and I use concepts from functional programming all over), not learned to think about algorithmic complexity until much later in life, and probably never have learned to write a real parser (which I use snippets of occasionally). I also learned some history, which is occasionally useful in deciphering old libraries. Oh, and university was the only place I ever had to write assembly code and learn how a CPU actually functions, which has been invaluable even though I “only” program in abstractions way “above” the CPU level.

    As to Shamus’ assertion that it’s a problem that classes don’t teach how to open windows, I would point out that I’ve been programming since 1980, professionally since 1993, and I’ve never done any windows programming at all :)

    • Alex the Elder says:

      Apprenticeships would be a far better fit than degree programs for just about everybody who isn’t shooting for a career in academia. And really, a degree program could be viewed as an apprenticeship for being a professional academic – perhaps therein lies the problem…

  42. Max says:

    I guess it depends where you go to learn. In my first semester of college for Software engineering, we had one course where we learned how to program. The rest of the courses covered a lot of different things but I guess you could say they were how to write software.

    We learned things like general rules for naming variables, how to write useful comments so other programmers can understand, roughly how large a program should be before splitting it into multiple files etc. We also learned things like pseudocode and flowcharts, to plan out exactly how the software will work, before even writing any code. And we also learned a lot of other stuff, all without writing any code, and wasn’t specific to any programming language.

    Since you and other people comment that universities rely too much on just reading books on syntax and people think they can program, I should mention that each semester we have about two books we have to buy, most courses are taught without books, but usually based on slideshows or other methods, that draw heavily on the professors’ personal experience in the field.

    I’ve been told that my college has the best software engineering program in Ontario(and arguably the best in Canada)so maybe the things I mentioned might have something to do with that.

    Also, people went to University and never learned create header files? They should demand their money back. In the first year I’ve done a few of the things on your numbered list, and there’s still a few years left so we may yet cover them all.

    • Felblood says:

      A lot of the problem in American Colleges is that we still have the same programming teachers as we did when my other studied programming.

      This is a major factor that leads to the real problem. Most accreditation leagues give out a two year degree on “Data structures and workflow,” which is required for any courses that would allow them to produce a complete program, and expect students to spend two years learning how to instantiate variables and talk about programming, before they get into a school where they can learn anything having to do with windows, TCP/IP, user interfaces, graphics, or sound.

      What are these two-year students good for, other than being allow to learn how to write programs that actually produce OUTPUT?

      Yes, they can write console applications that print “hello world” and Fibonacci’s triangle. Some schools will provide some very cursory notes on importing libraries in the second year, so that students might have a prayer of being able to get some work debugging applications written by real programmers.

      However, all that two-year investment gets you is a language (or maybe two) that can read the basic syntax of, an understanding of general programming terms like arrays, classes, headers and pointers, and the privilege of studying for two more years to get a degree someone might actually hire you for.

      If you already have everything, but the last item, those two years might be better spent reading some internet tutorials on the stuff that actually interests you, and not accruing 9+ thousand dollars of debt.

  43. Amarsir says:

    I’m not much younger than Shamus and taught myself coding when I was young. I even took some local Community College classes while in High School. But between the era and the learning method, I never learned any of the OOP approach to coding. (In fact I had quite bad habits because much of what I’d learned had been about resource efficiency not code reusability.)

    Only years after school and many bad lines later did I learn that I was viewing things wrong. I was going through Advanced PHP Programming by George Schlossnagle when he discusses something called “Design Patterns.” I’d never heard the phrase and the abstractness of the concept probably makes it harder to teach, but once I “got” that it changed everything.

    However, to this day I think it’s hard to learn best practices, which is what I spend the most time worrying about. For example, how would you handle a database table that churns through rows so fast (adding and deleting again) that it stays small but ID numbers assigned to each row get too big to store? (PK exceeds range in tech-speak.) I asked this the other day and got 6 different answers, none completely convinced. Sure there are usually multiple approaches to an issue. But I can’t believe this doesn’t come up enough that someone hasn’t calculated a best answer.

    • silver Harloe says:

      Too big for the DB to store, or too big for your external program to store?

      If it’s your external program, I’d say you should just treat the IDs as strings in code even though they’re unsigned bigint in the DB. If you need to check the IDs for correctness in code, you can always just check that it’s a string of numbers (/^\d+$/ if you have a regexp library :) )

      If it’s the DB running out of IDs, then I’d make a cron job to copy the data without IDs to a new table (“create table like table_X”), drop the original, and rename the new to the original, and schedule it for however often is necessary (ideally at a time you can halt the programs editing the table for a couple minutes)

    • Kyte says:

      Given your situation, I’d say you probably need to change your PK from an autoincrement (which you’re running out of too quickly) to a composite key based on whatever unique attributes each row has.
      The most common case are the middle tables for Many-to-Many relationships. The autoincrement PK is used as a speed optimization, since they’re laid out sequentially, but it’s perfectly legal to have the PK be composed of (table_1_FK, table_2_FK), which you’ll never run out of.
      Alternatively, GUIDs. HUGE number space, fixed size. Some databases even accept it as a native type!

    • Amarsir says:

      Both valid answers from silver Harloe and Kyte, but demonstrating my point that there isn’t a shared knowledge on this. My other conversation also got into index sizes and the speed thereof, which is more complex and esoteric than most people would want to think about. Maybe this isn’t the best example for a problem everyone deals with, but I think it shows that when it comes to techniques, we still end up recreating the wheel a lot.

      • Kyte says:

        Well, that’s why we’ve got race tires, offroad tires, normal “city-driving” tires, chains & special iced-road tires, etc. Sometimes a plain wheel just won’t cut it. ;)

  44. Rayen` says:

    All of this depresses me. It seems more and more these days that if you want to learn anything you have to take interest in it and study youself starting at a young age. “Teach yourself programming in ten years”, really? i don’t have ten years. and even if i did, do i really want to start my first entry level job in programming in my late thirties? And say i want to write some code to modify a game i’m playing now (*minecraft) How many years before i can learn to do the one thing i want to do. If i have to wait the full ten then what are my chances of still playing that game, or more specifically someone already having the mod?

    Sad fact of life i see here is; if you want to program and you don’t already know, you can’t learn…

    • Macca says:

      You sure can learn! Just don’t learn through the ‘traditional’ methods of books and courses. Learn by doing. Dive in, and participate in programming communities. I learnt in ten years, yes, from a young age, but it wasn’t an intensive effort. It was an occasional hobby that turned into a career. Of course you have to take an interest in it, but with determination, the right resources (real-life projects to delve into and solid advice from real programmers) and some free time you can do it in much less. I do find that you need a natural aptitude for logical thinking, but if programming interests you, you probably have that. :)

    • DrMcCoy says:

      “more and more these days”? What the hell are you talking about?

      It’s not like a few hundred years back, you could just take up a plane and call yourself a carpenter, or take up a chisel and call yourself a sculptor, or take up a brush and call yourself a painter.
      You had to actually go and learn your craft. For years and years. And more often than not, you did start young with the learning, yes. That’s normal.

      Learning anything to a degree that’s presentable takes years of work and dedication; there is no instant gratification.

      • silver Harloe says:

        Beginners always had to learn from experienced people. We had a better system for that before we extended adolescence five years and stopped apprenticing people, and instead indoctrinated them to a system which says nothing that can’t be expressed in 45 minutes before the bell interrupts you is worth learning. And we wonder why people have no attention span – we spend 12 years teaching them to never pay attention to anything too long!

        • DrMcCoy says:

          Except that the basics (reading/writing, maths, general historical overview, general science principles, etc.) are completely unfeasible to teach on a 1:1 (or 1:3) basis. (On the flipside, 30+ people per class is of course also asinine and one of the major problems with public education today)

          And we do (in Germany, at least, but I doubt it’s different in, say, the US) still have apprenticeships and internships where people can learn the specifics of a certain trade.

          Your idiotic and generalizing rant against the Evil Indoctrinating School System (TM) nonwithstanding, the education system was and is a driving force for widespread access to knowledge and as such a building block of a civilized/enlightened country.

          • Shamus says:

            My wife has taught our children these subjects on a 1:1 basis. Silver Harloe is not being idiotic, (although perhaps more aggressive than the subject warrants) only proposing something very, very different than what we grew up with.

            We’ve always sent people to schools because that’s where the information was. Now the information is in every single house, everywhere the networks reach. If there is one message I’d like to give to everyone in the education debate, it’s that we should respect the education choices made by others. “Optimal education”, like “optimal sort algorithm” is not a fixed procedure, but one that varies depending on the inclination of the child, dedication of the teacher, condition of the local public school, home situation, and learning materials available.

            Didn’t we just have this debate a couple of weeks ago? I could swear we did?

            • DrMcCoy says:

              My wife has taught our children these subjects on a 1:1 basis

              Yes, and your wife is working from a privileged position there. Not everyone has the means to do that, by far. That’s what I’m getting at, it’s not feasible for the whole of the population.

              Now the information is in every single house, everywhere the networks reach

              You still need a…navigator. A teacher is, or should be at least, more than just a big infodump.

              it’s that we should respect the education choices made by others

              Depends. If the children get the short end of the stick, I’m not one for dishing out respect. Of course, since I grew up in a society where public education is mandatory, and where I heard a lot of horrorstories from overseas about religious kooks indoctrinating their children using homeschooling, I might be biased in my opinion about where that short end starts.

              In general, I’m very sceptical that homeschooling is a workable alternative for the general population and I see its dangers of being abused by parents to shut their children in during a critical moment of their lives, effectively ruining their chances of ever equal opportunities in their lives.
              This is also why I’m getting so damn depressed when I see the dismal state of the public education system, both here and abroad.
              “But the information is out there on the net” doesn’t help one bit without guides to help find and sort out the information.

              Didn’t we just have this debate a couple of weeks ago?

              I wouldn’t know. I don’t read most of the discussion threads, at least not in full.

          • silver Harloe says:

            I thought I was agreeing with you, Dr McCoy :)

            Though I was also advocating against bells. Not against school, not against people teaching things like reading/writing in more than 1:1 scale, just against bells :)

            • DrMcCoy says:

              Yeah, sorry, you just triggered my “public school are evuuuul” senses. General disdain for the public education system is one of the (many :P) things that get my goat pretty easily. :P

              • silver Harloe says:

                Oh, I don’t mind the existence of school, just some of the concepts like:

                * counting people as slow-for-life if they learn to read at their own pace (one child learns to read at 3, another learns at 8. by the time they are 12, you can’t tell which is which, except in American Public Schools, the latter child has been stigmatized for life).

                * bells. like it or not, breaking the day into mandatory interruptions teaches a lesson in and of itself, and that lesson is “nothing is worth spending any real time on”. Some people learn to break themselves of this lesson, some people do not.

                * age-sorting children – in an ideal world, older children would participate in the education of younger children. there’s an amazing amount of learning that happens when you teach. also, when younger children see what their elders are doing, they try to emulate that. now they are taught to live in a continuous separation from past and future, and so never really have anyone to emulate.

                * turning a blind eye to bullying – maybe this is just the American public education experience, but teachers generally let the jocks do whatever, but come down hard if any of their victims try to fight back. the lesson is clear: some people are superior.

                But there exist schools that get around these problems, and I’m not against them. In America, they’re all necessarily private schools, alas.

                • Will says:

                  the lesson is clear: some people are superior.

                  Although it sucks, this is actually a lesson everyone really needs to learn. Or, more generally “The world is not fair.” A lot of my friends and peers have run into trouble in the past because they believed the nonsense about the world being a fair place often taught to children in western society. I learned the hard way that the world is not fair and while i wouldn’t wish that particular experience on anyone, the lesson is absolutely vital.

                  The main problem with bullying however, is most bullying these days is verbal, which means it’s next to impossible to prove it so it ends up being a huge ‘he says, she says’ shouting match. I can’t speak for the US, but down here a lot of bullying gets past the teachers simply because they never see it happening.

                  • Mephane says:

                    I learned the hard way that the world is not fair and while i wouldn’t wish that particular experience on anyone, the lesson is absolutely vital.

                    Well then the lesson it not just “the world ain’t fair”. The lesson from bullying at school is “might is right, don’t even try to change it, accept it, keep your head down, don’t speak out loud when the wrong people might be listening, and don’t think people might ever actually help each other when in need, and never fight back when injustice occurs”.

                    Sure, this lesson may save you a lot of hassle in your life, while continuing the status quo that actually made this lesson somewhat neccessary. I believe in progress instead of merely managing the status quo indefinitely. And the one place for progress is the children. If teach them to duck and cover instead of trying to change what is just not right, we won’t get anywhere soon in this regard.

                    • Will says:

                      You’re exxagurating a bit there.

                    • Felblood says:

                      Here’s what I learned on the playground.

                      1. When you’re bloody and beaten, most people will point and laugh, until an authority figure approaches.

                      2. Once the crowd disperses, authority has no interest in bleeding children lying on the ground.

                      3. The only person on the playground worth knowing, is the one who comes to help you to the nurse, after the crowd has been distracted by some new thing.

                      Decades later, that person will remember you on sight, while the bullies will forget you entirely after a couple of years of homeschooling (Parental concern over violence and it’s impact on my psychology: Post Traumatic stress and borderline schizophrenia).

                      Final Lesson: Cruelty is real and you must be ready to endure it, or break, but ultimately, embracing it will leave you empty; Courage and kindness exist too, and by embracing them, you help others to endure cruelty, and make yourself a more fulfilled person.

                      EDIT: This is not intended as a defense of how elementary playgrounds are run here. These same lessons could be learned by holocaust survivors, but that doesn’t make a concentration camp a good place for kids.

                      Before you call me on my Nazi comparison, remember that I was beaten daily until I WENT INSANE. I’m only mostly recovered, even decades later.

                • Zak McKracken says:

                  I think your concerns are valid. I don’t however, think they are linked to the concept of schools, just to your experience of their negative sides:
                  counting people as slow-for-life
                  If you leave school, your marks have relevance only until you’re in whatever is the next part of your carreer (apprenticeship, university, whatever).
                  The fact that someone judges a person by prejudices based on innaccurate observations from years ago … well that’s a human thing, I guess. I hate it passionately, but it’s everywhere in society, not just in schools
                  age-sorting children
                  “Post doc wanted. Requied qualification: PhD degree in Biology or Biochemistry, at least [x] publications in high-ranked journals, age below 30”.
                  Same thing. In lieu of good criteria, people are judged on bad criteria. Age is one of them.
                  There are, by the way, some schools around here who introduced mixed-age classes. Also, in my class the age difference within my class was more than one year, and I did know people who skipped one or even two years in school, although everyone else hitting puberty two years before you is no nice experience.
                  turning a blind eye to bullying
                  now … how’s that connected to schools? I was being bullied long before school, and after school, too. Also during school, of course, but at least sometimes there were teachers putting a damper on it.
                  Again, this is a general problem with society that you just happen to associate with schools. People turning a blind eye on injustice and discrimination in society is a very very common thing. There are good (read: evil!) examples for that on both sides of the ocean, the single most placative certainly in Germany. Others, certainly less intensive but longer lasting, also in the USA. That is completely not bound to schools. It is something that happens if many people are in one place.

  45. Jabrwock says:

    It’s too bad Hypercard is effectively no longer around. It was considered one of the closest programming languages to English you could find.

    Great teaching tool. The student can intuit most of what the code does just by reading it. Allowed you to concentrate on the concepts instead of trying to teach concepts while simultaneously fighting teaching syntax.

    I agree with most of the items on your list of what’s missing from educational programs. With my BSc in Comp Sci, we did cover 1, 3, 4, and 6, although not all in the same class. Headers were covered in my C class, Windowed and cross-platform development was part of our GUI class (native windows vs Java windows). And 6 was only learned as a concept in tandem with a general knowledge of IDEs.

    Most of it was concepts, to be fleshed out by apprenticeship and experience in the real world. For example we learned how DBs in general worked, it was up to us to apply that to learning a particular implementation.

    • J Greely says:

      Hypercard had the second-worst programming language Apple has ever shipped; there’s nothing English-like about “get line one of card field short name of the target”.

      -j

      • silver Harloe says:

        and worse, all the code was stuck on each card with no global search functionality. was a real pain to find where some variable was referenced because you had to open every card individually :/

        • Jabrwock says:

          I never said it was a good powerful programming language. Just that it was great for introducing a beginner to the concepts of programming without having to simultaneously fight syntax confusion at the same time.

      • Jabrwock says:

        Seriously? “get line one of card field ‘name'” is so “un-english” that you can’t figure out what it means?

        Try showing that to a beginner. Then show them the equivalent in C or C++, or even BASIC.

        Then tell me which one confuses the user faster.

  46. Zlan says:

    When ever I click on the online link thing for c++ free read Norton says that there are 20 computer threats. Is this because there are things it doesn’t recognize or adds or what? I really want to read the page but I’m not tell I know it’s safe.

  47. Mr. Son says:

    A while back (maybe a few weeks? I wrote it on the calendar, but don’t want to go check) I started trying to learn C++ with that ‘in 21 days’ guide you linked. After struggling to find a compiler, OPEN it (I seriously couldn’t figure out how to open the program until I found a youtube tutorial where the guy starts it up to show you how to do Nifty Thing in it), and start a new project… I learned that typing the code EXACTLY as displayed made the compiler slightly unhappy, and trying to break it in the way the guide told me to (which was described one way, then shown another) made it quite grumpy.

    After almost giving up, I found this guide through my google-related dark arts. It was so much more useful to me. Starting with it recommending a compiler (and name-dropping a few more, for the adventurous), then proceeding to explain how to set it up to start practicing. It’s been great for me so far, with a few additional google-summoned supplements.

    I’ve also found these somewhat useful, as well:
    http://cpp-tutorial.cpp4u.com/index.html
    http://www.cplusplus.com/doc/tutorial/
    http://web.student.tuwien.ac.at/~e0226430/tutorial/operators.xhtml

    Of course, ALL of these fall into the same hole you mentioned. They teach you how to hammer two pieces of wood together and fasten a screw, then go “okay, you’re a carpenter. Keep practicing until you can build a house.” If you’re lucky, they’ll tell you to look at some other people’s houses to get some ideas, which actually gives you something resembling a jumping off point.

    To be honest! I haven’t read that first one (my favorite) through yet. I got to a certain point, stopped, and went “y’know, with this much, I think I could write a shoddy text adventure.”, and went off to do just that. Thought it might help me digest what I’ve learned so far before I go for another course.
    (BTW, if by some miracle of chance… Anyone might be willing to take a look at my ‘bubble gum and prayer’ partially-written (barely-started, really) game and give the newbie some advice? …I could upload it somewhere and drop a link later. Oh god! I just reviewed it briefly, and now I feel like I’ll die if anyone looks at it! …Must leave the invitation up, though. Be strong…)

    PS. Oh, yes, one question for you. Are the curly brackets at the edges of my vision normal? They’ve been fading in and out all week, and it can get a little distracting sometimes.

    PPS. Sorry for the rampant incoherence. I have many excuses, few of them anything close to reasonable. If you’d like, I can go slink back to the lurker corner with my tail between my legs and never come out again.

    • Simon Buchan says:

      Sure! I love reading code. I’m also a self-important snob that loves hearing his own opionions*, so I’ll have plenty of feedback!

      It sounds like you’re doing exactly the right things – start writing code, look for answers, asking for help – so you should be fine.

      * This is a self-depreciatory way to say I like helping, or at least that I try to avoid being rude :)

      • Mr. Son says:

        Alright, I’ve got it up at http://www.mediafire.com/?ja4dtosd3o4nkcw

        I’ve included the main.cpp and a few of my ‘personal supplement’ files that I use to keep track of what I’m doing.

        I apologize in advance if looking at this code ends up causing you physical pain.

        ETA: The link in my name goes to my livejournal, where I’ve been blogging about my game project. A little like Shamus’ game project blogging, except with less competence.

        • Simon Buchan says:

          Well it’s 1AM on a work day here, so I can’t get *too* far into it right now. :)

          It looks like you could save a bit of that repetition by using arrays. Something like:

          int visit[6][6][10];
          // Instead of visit110, visit111, ...
          // visit[1][1][0], ...
          // Arrays allow values from 0 up to but *not* including
          // their size, so I used '6' above so you can still use 1-5.
          
          // Instead of loc_char:
          int x;
          int y;
          int sub;
          // So now, visit[x][y][sub]++ is always adding to the *current* location!
          // You can get loc_char back eg. for dothing(),
          // with x * 100 + y * 10 + sub
          
          // Function pointers are variables that hold functions!
          // Unfortunately, their syntax is aweful, without 'typedef'
          // this would look like:
          // void (*prompt[5][5][10])();
          typedef void loc_func_type();
          loc_func_type* loc_func[5][5][10];
          
          // Try out things like...
          //leave_func* leave[5][5][10];
          //look_func* look[5][5][10];
          
          int main()
          {
              // Although C++ *won't* initialize variables you declare
              // inside functions, it *will* initialize global variables,
              // so you can skip initializing visit. It's a good idea
              // to get your initial state to be zeros!
          
              x = 3;
              y = 1;
              sub = 0;
          
              // Initialize the loc_funcs.
              // no (), we want to get the function, not call it.
              loc_func[0][0][0] = loc_lost;
              loc_func[1][1][0] = loc_cowhouse;
              // ...
          
              do
              {
                  if (gameprogress == 0)
                  {
                      // ...
                  }
                  else
                  {
                      // If we didn't set a prompt function for our
                      // current location, we are lost!
                      if (!loc_func[x][y][sub])
                          x = y = sub = 0; // trick to set all 3 to 0
                      // And now the () shows up, call the
                      // function from where we stored it!
                      loc_func[x][y][sub]();
                      // visit the current location!
                      visit[x][y][sub]++;
                      // Do the thing!
                      dothing();
                  }
              } while (gameprogress > -1);
              // ...
          }
          

          Then I’d recommend splitting up figuring out what the user typed, and doing what he asked or complaining. Adding functions to replace copy-pasted code, eg:

          string prompt(string msg)
          {
              cout << msg <> result;
              cin.ignore();
              return result;
          }
          
          quitgame = prompt("Do you really want to leave town? [YES/NO]");
          

          Later you can try other, more complex tricks to simplify your code – eg keeping location data together with a structs, using pointers to remember the current location instead of using [x][y][sub] all the time, and so on. I wouldn’t try using classes yet, there’s a lot of philosophy to learn before you can use them right, not to mention they mean you have to learn memory management!

          Also, I can post further comments on your blog, if you want.

          Finally, don’t worry, programming gets less boring the better you get at it!

          • Mr. Son says:

            Thanks for the response! I’ll give it more than my initial skim once I’m more awake, but I can already tell it has some useful stuff inside. I’ll look into arrays; I haven’t really learned anything about those, yet.

            And I wouldn’t mind you moving comments to my livejournal if you’re okay with that. Keep ’em here if you prefer it, but either way, even what you’ve said already ought to help me out. Thanks a ton!

  48. anna says:

    Style and Design are taught by at least *some* college programs – my program taught them, with an emphasis on readability and documentation. As far as non-expensive references go, The Art of Unix Programming is a pretty good book on programming philosophy, but its emphasis is mostly a little higher-level than what you’re asking about. It is also more focused on writing *tools*, and even more specifically *command-line tools*, so some of what it has to say isn’t all that applicable to something like game development (although a surprising amount of it *is* applicable).

  49. Alan De Smet says:

    If you can afford the time and money, there is a value to a good Computer Science undergraduate program. You’ll accumulate good theory much faster than trying to self teach or learning as you go. Too much theory is as bad as too little, but a solid grounding pays off all over. Concepts like big O notation help identify what is actually slow about your program and tend to pay off way more than simple spot optimizations. You may never write a compiler, operating system, or database, but learning about them makes it easier to interact with them. To grab a random example that I’ve encountered repeatedly: why is calling read(fd,buf,1) in a loop a terrible idea? Your operating systems course will tell you. And it turns out that lots of programs implement simple parsers (same as compilers), juggle multiple tasks at the same time (same as an operating system), or store data is a form that is fast to read and write (same as a database).

    Your mileage may vary.

    • Tizzy says:

      My CS professor friends tell me that good theoretical grounding is very handy to pick up new languages painlessly, which is a must if you want a career as a programmer that will last more than a decade.

      On the other hand, few academics I know ever have to maintain large projects, especially projects shared among many programmers. So even though project management courses do exist, the professors themselves may not be always aware of how crucial those skills are.

      Then again, there is only so much that a one or two-semester course can teach you when we are talking here about lifestyle changes…

  50. DrMcCoy says:

    Thinking about the topic a bit, one main source for many “software engineering” type principles — after you acquired the basics of programming — is reading other people’s code.

    So my advice would be: go for the look out for a wide variety of open source projects; download the sources and read them. Also read their general code guideline on their website/wiki/docs, if available. You will see certain pattern repeated and certain “best practices” highlighted multiple times.

    If you feel daring and found a project that really interests you, contribute a few patches for small, missing functionality (often highlighted on a bug / feature request tracker, or on separate wiki-/webpages, especially if the project also takes part in the GSoC program). If you’re unclear about the specific requirements, ask on the projects’ mailing list or their IRC channel, they’re usually always happy to have more contributors.

  51. Adamantyr says:

    In my CS degree, I got next to nothing for software engineering. In my graphics class, my Star Trek game was basically one gigantic file because I couldn’t grok how to do header files properly, having zero guidance in the area. And the teacher gave me an A+ anyway… his lab also had zero source control; the general theory among the students was as a Russian CS professor, he probably had never coded a single line in his life.

    I’ve got the same C++ book on my shelf… I found the books moderately useful for telling me what made C++ different from C, but a total waste where actually managing a software project was concerned. Experience, as always, is far more valuable than the degree.

    I stared programming in BASIC when I was 10, and on my trusty TI-99/4a, that was actually a decent platform to learn the nuances of programming with a cushion from the realities of the machine. And an imperial language is the best thing for a kid to start with; you start talking about source files and compiling verses real-time, the kid’s going to go outside to play instead. How ANYONE even gets into programming now I have no idea… Apparently these days most don’t take an interest until college-level, which is a shame.

  52. Skeeve The Impossible says:

    They’re all dead Dave

  53. SatansBestBuddy says:

    Said it before, will say it again.

    YOU. NEED. TO. WRITE. THE. BOOK. ON. THIS.

    There are very, very few people who both write novels and write code, and even fewer you can do both well.

    You can do both well, which means you are probably one of maybe a dozen people on this planet who can write this book. (in English, I’m sure there’s a super writer/coder guy over in Germany who could school your ass on this, but that’s another language so he doesn’t count >.>)

    Yes, it will take a ton of time, yes, it will take a ton of research, yes, it will need to be revised a hundred times over by colleagues who have years of experience who noticed you left out that one thing that must be in there and by newbies who are gonna complain about how much trouble they have with the first page irregardless of how clear and concise you make it.

    But I think, no, I KNOW it will be worthwhile.

    Do it.

  54. John says:

    It sounds like you have your next book idea right there. Now you just have to finish your first one…

  55. Hurrah for you, Shamus! I hate seeing C++ used as an introduction.

    As for the real stuff, I learned most of it in the library. Good textbooks will cover abstraction and separation of concerns, which are getting at the good stuff. I recommend How to Design Programs, free online at htdp.org, and also Liskov and Guttag’s out-of-print classed Abstraction and Specification in Program Development. (Don’t buy the new Java edition; the original is much better.)

    Finally, some of the classics are, well, classic. I learned a lot from Glenford Myers’s book Composite/Structured Design. Constantine and Yourdon wrote a good book on design, too.

    Finally, I suggest avoiding the classic “gang of four” book on design patterns. It is mostly ways of working around things in C++ that are broken. The rest is lengthy explications of how experienced programmers solve simple problems, with lots of shiny terminology. Good if you like that sort of thing, I guess.

    One last thing: practice. For about 10,000 hours. But do remember that sometimes if you spend two weeks hacking you can save a whole afternoon that you would otherwise have had to spend in the library.

  56. JPH says:

    Completely unrelated: Do you still use the email address shamus@shamusyoung.com? ‘Cause I remember you saying something awhile ago about that address getting a ton of spam.

  57. Luke Maciak says:

    Shamus, I happen to have a Masters degree in Computer science, and I can tell you that college is a good place to start learning how to write software. Granted if you take just one course, you will learn nothing but syntax. Most CS curriculum far above and beyond that. In fact, most students will cover the stuff you were talking about above in their second or third semester.

    To wit, at my University the curriculum included the following:

    – 2 courses of introductory programming courses to teach you syntax of chosen language. It was initially C++, but later they switched it to Java because C made students cry. It was a joke C++ is both the name of the course and the average grade in the course. But I digress. First course was usually just the basics. Second one was advanced stuff – you basically take a blunt object and try beat inheritance and polymorphism concepts into them until they get them instinctively.
    – Data structures course in which they made sure you know about hashing, and can tell your trees from your graphs, know how to traverse them optimally, and etc…
    – Discrete Math course in which you learned about your truth tables, logic, sets and how to do formal proofs
    – Algorithms course which you learned about… Well algorithms and how to profile. It also introduced you to the enchanting world of bakers, barbers and traveling salesmen. Also more proofs. You would get an automatic A if you prove that P=NP. Heh…
    – A course in assembly language to show you how things look underneath, how to grok binary and hex dups, how to decompile binaries, and how to use debuggers
    – A theory of digital machines course in which you learned about logical gates, designed pseudo circuits to see how things look from hardware/engineering perspective.
    – Two courses on Software Engineering which took you through software design process (gathering requirements, design, implementation, testing, etc…). Also it was your first introduction to the soul crushing reality of real world software design: gather requirements, spend weeks drawing UML diagrams, start implementation, realize design is shit, start over – repeat at least 20 times before it’s done.
    – One course called “Process and Design” which was essentially a rundown of all the funky stuff like Agile, scrum and whatever else was fashionable at the time
    – Four database courses (two were graduate level). The first taught you SQL, and how to write database driven software. Second was more about the theoretical stuff like relational algebra and actual database design. The other two were pretty much nintendo-hard version of the above, plus a lot of theory about query profiling, file structure and etc… Databases are serious business.
    – Two Systems Software courses. First one taught you how to write an assembler and linker. Second taught you how to write a compiler, and design your own languages using formal grammar notation, and/or tools like yak.
    – A course on image processing. Pretty much an entire course of this.
    – A course on parallel processing where you got to mess around with a 20 odd CPU cluster and write parallelepiped software.
    – A survey coruse of programming languages in which you actually got to write code in few dozen different funky languages including ADA, COBOL, FORTRAN, Prolog, Lisp, etc. It pretty much went like “thank god fortran is rare these days, COBOL really sucks every bit as much as you have heard, lisp is awesome in a mind-bending way and every other language is pretty much the same shit with slightly different syntax.

    There were bunch of other courses I am forgetting, but I guess the gist of this is that if you do graduate with a CS degree you will probably have at least some idea how to write software.

    In my undergrad career I wrote a multi-threaded Game of Life, a shopping cart application, my own flat file driven database engine with limited SQL support, a image processing library, a custom shell, a text editor, an app that simulated protein binding, a set of scripts to read, and analyze human genome sequence files and bunch of other functional projects. All in all I was exposed to a wide variety of projects, and I learned a lot.

    I currently teach a class there, and so I get to see what students are doing these days. I believe that these days the final project in Java 2 course was to write a sudoku game, and the software engineering students were building a visualization software that would simulate a collision of two or more galaxies.

    So here is my advice to your readers: if you are still in high school, or are just starting a college career then taking a few CS course is a great place to start. If you like it, become a CS major and take lots of electives withing in your major even if you don’t need them to graduate. That’s the best way to do it. You will learn more than just syntax, and you will write some real software at some point. It will suck ass, because you will be on tight deadlines but that’s just how it works in the real world too.

    This is especially important if you think you will want to write software for living. While having a CS degree is not always necessary to land a programming job, you will always be competing with folks who have them.

    Other than that, if you can’t afford college… Read a lot and write a lot. Pick a language (don’t pick C++ – it sucks as a first language). Pick something that’s either popular in the industry (Java) or sexy right now (ruby, python, etc…). It does not matter. Pick one, and stick with it. Read tutorials, and write small programs. Then bigger ones. Work your way through all the language features you can grasp. Then buy an advanced programming book and try to learn object oriented programming concepts.

    Subscribe to programming blogs, and message boards. Read articles about software engineering. If you don’t understand something, look it up. Buy some books and read them – software engineering, design patterns – that kind of stuff.

  58. Moonmonster says:

    1) *generally* college-educated people come out with less terrible code, with a little prompting and review.

    2) The best way to learn Software Engineering, as opposed to programming, is to get a job at a company with smart people and a pervasive code-review culture. In other words, get someone smart to point you in the right direction and explain why a particular software architecture is better or worse.

  59. miroz says:

    I think that the best thing you can do to teach yourself how to write software is to work in a team. Do a small project like a simple game, web or windows application in a team of four.

    There are so much more thing to consider when working in a team:
    – Is my code readable to others? Encourages good code.
    – How can we share source code? Learn how to use source control.
    – How can we fit different pieces together? Encourages modularity.

    Also, knowledge exchange is priceless. Even before they start coding, all members of a team will be smarter. Teamwork is hard by itself, as it forces us programmers to socialize and require some other skills like communication and cooperation but those skills are sometimes more valuable then any knowledge in programming language.

    To rephrase a commenter above: Do it with smart people, smarter then you.

  60. Adam P says:

    I’m not a programmer, so I don’t know what a header file is. I read the Wikipedia article on it, but it didn’t shed any useful light on the subject. What’s a header file?

  61. Daimbert says:

    It was a long time ago, but in my Computer Science degree I had two courses in Software Design, one of which where actually writing the code was completely optional. We didn’t cover source control, but that’s probably a good thing since in small projects you’ll never see the point of it and every company uses a different method for it; it’s easiest just to learn it then.

    As for books, I liked “Practical C++ Programming”, which included some notes on debugging and optimization.

    • WJS says:

      “[I]n small projects you’ll never see the point of [source control]”
      Uh, what? While I don’t use source control on all my 6-line shell scripts, anything large enough to even call a “project” goes under version control, it’s insane not to.

  62. Factoid says:

    This post just reminded me of an excellent set of pint glasses I was given as a birthday present.

    They say:

    #include beer.h

    I think wordpress comments are eating my lessthan greatherthans.

    • WJS says:

      If you review incoming comments, Shamus, how about adding how to do literal <> (&lt; and &gt;) to the suggestions above the comment box? Seems like something that people struggle with fairly frequently…

1 2

Leave a Reply

Comments are moderated and may not be posted immediately. Required fields are marked *

*
*

Thanks for joining the discussion. Be nice, don't post angry, and enjoy yourself. This is supposed to be fun.

You can enclose spoilers in <strike> tags like so:
<strike>Darth Vader is Luke's father!</strike>

You can make things italics like this:
Can you imagine having Darth Vader as your <i>father</i>?

You can make things bold like this:
I'm <b>very</b> glad Darth Vader isn't my father.

You can make links like this:
I'm reading about <a href="http://en.wikipedia.org/wiki/Darth_Vader">Darth Vader</a> on Wikipedia!

You can quote someone like this:
Darth Vader said <blockquote>Luke, I am your father.</blockquote>