Syntax, Semantics, Micronesian cults and Novice Programmers

Syntax, Semantics, Micronesian cults and Novice Programmers

Rate This
  • Comments 48

I've had this idea in me for a long time now that I've been struggling with getting out into the blog space.  It has to do with the future of programming, declarative languages, Microsoft's language and tools strategy, pedagogic factors for novice and experienced programmers, and a bunch of other stuff.  All these things are interrelated in some fairly complex ways.  I've come to the realization that I simply do not have time to organize these thoughts into one enormous essay that all hangs together and makes sense.  I'm going to do what blogs do best -- write a bunch of (comparatively!) short articles each exploring one aspect of this idea.  If I'm redundant and prolix, so be it.

Today I want to blog a bit about novice programmers.  In future essays, I'll try to tie that into some ideas about the future of pedagogic languages and languages in general. 

Novice programmers reading this: I'd appreciate your feedback on whether this makes sense or it's a bunch of useless theoretical posturing.

Experienced programmers reading this:  I'd appreciate your feedback on what you think are the vital concepts that you had to grasp when you were learning to program, and what you stress when you mentor new programmers.

An intern at another company wrote me recently to say "I am working on a project for an internship that has lead me to some scripting in vbscript.  Basically I don't know what I am doing and I was hoping you could help."  The writer then included a chunk of script and a feature request.  I've gotten requests like this many times over the years; there are a lot of novice programmers who use script, for the obvious reason that we designed it to be appealing to novices.

Well, as I wrote last Thursday, there are times when you want to teach an intern to fish, and times when you want to give them a fish.  I could give you the line of code that implements the feature you want.  And then I could become the feature request server for every intern who doesn't know what they're doing…  nope.  Not going to happen.  Sorry.  Down that road lies cargo cult programming, and believe me, you want to avoid that road.

What's cargo cult programming?  Let me digress for a moment.  The idea comes from a true story, which I will briefly summarize:

During the Second World War, the Americans set up airstrips on various tiny islands in the Pacific.  After the war was over and the Americans went home, the natives did a perfectly sensible thing -- they dressed themselves up as ground traffic controllers and waved those sticks around.  They mistook cause and effect -- they assumed that the guys waving the sticks were the ones making the planes full of supplies appear, and that if only they could get it right, they could pull the same trick.  From our perspective, we know that it's the other way around -- the guys with the sticks are there because the planes need them to land.  No planes, no guys. 

The cargo cultists had the unimportant surface elements right, but did not see enough of the whole picture to succeed. They understood the form but not the content.  There are lots of cargo cult programmers -- programmers who understand what the code does, but not how it does it.  Therefore, they cannot make meaningful changes to the program.  They tend to proceed by making random changes, testing, and changing again until they manage to come up with something that works. 

(Incidentally, Richard Feynman wrote a great essay on cargo cult science.  Do a web search, you'll find it.)

Beginner programmers: do not go there! Programming courses for beginners often concentrate heavily on getting the syntax right.  By "syntax" I mean the actual letters and numbers that make up the program, as opposed to "semantics", which is the meaning of the program.  As an analogy, "syntax" is the set of grammar and spelling rules of English, "semantics" is what the sentences mean.  Now, obviously, you have to learn the syntax of the language -- unsyntactic programs simply do not run. But what they don't stress in these courses is that the syntax is the easy part.  The cargo cultists had the syntax -- the formal outward appearance -- of an airstrip down cold, but they sure got the semantics wrong.

To make some more analogies, it's like playing chess.  Anyone can learn how the pieces legally move.  Playing a game where the strategy makes sense is the hard (and interesting) part.  You need to have a very clear idea of the semantics of the problem you're trying to solve, then carefully implement those semantics.

Every VBScript statement has a meaning.  Understand what the meaning is.  Passing the right arguments in the right order will come with practice, but getting the meaning right requires thought.  You will eventually find that some programming languages have nice syntax and some have irritating syntax, but that it is largely irrelevant.  It doesn't matter whether I'm writing a program in VBScript, C, Modula3 or Algol68 -- all these languages have different syntaxes, but very similar semantics.  The semantics are the program.

You also need to understand and use abstraction.  High-level languages like VBScript already give you a huge amount of abstraction away from the underlying hardware and make it easy to do even more abstract things.

Beginner programmers often do not understand what abstraction is.  Here's a silly example.  Suppose you needed for some reason to compute 1 + 2 + 3 + .. + n for some integer n.  You could write a program like this:

n = InputBox("Enter an integer")

Sum = 0
For i = 1 To n
      Sum = Sum + i

MsgBox Sum

Now suppose you wanted to do this calculation many times.  You could replicate the middle four lines over and over again in your program, or you could abstract the lines into a named routine:

Function Sum(n)
      Sum = 0
      For i = 1 To n
            Sum = Sum + i
End Function

n = InputBox("Enter an integer")
MsgBox Sum(n)

That is convenient -- you can write up routines that make your code look cleaner because you have less duplication.  But convenience is not the real power of abstraction.  The power of abstraction is that the implementation is now irrelevant to the caller.  One day you realize that your sum function is inefficient, and you can use Gauss's formula instead.  You throw away your old implementation and replace it with the much faster:

Function Sum(n)
      Sum = n * (n + 1) / 2
End Function

The code which calls the function doesn't need to be changed.  If you had not abstracted this operation away, you'd have to change all the places in your code that used the old algorithm.

A study of the history of programming languages reveals that we've been moving steadily towards languages which support more and more powerful abstractions.  Machine language abstracts the electrical signals in the machine, allowing you to program with numbers.  Assembly language abstracts the numbers into instructions.  C abstracts the instructions into higher concepts like variables, functions and loops.  C++ abstracts even farther by allowing variables to refer to classes which contain both data and functions that act on the data.  XAML abstracts away the notion of a class by providing a declarative syntax for object relationships.

To sum up, Eric's advice for novice programmers is:

  • Don't be a cargo cultist -- understand the meaning and purpose of every line of code before you try to change it.
  • Understand abstraction, and use it appropriately.

The rest is just practice.

  • > yet some people might calmly think of that as black boxing

    Clearly there is a spectrum of behaviour here.

    On the one end are the gurus who understand the intended and actual behaviour of every usage of a particular programming construct -- the people who see through multiple layers of abstraction down to some underlying substrate like electrons, the hardware, the operating system, whatever is "basic" for a particular application.

    On the other end are the cargo cult programmers who don't understand the code except that they know that right now, it does what they want, sorta.

    The "black boxers" are somewhere in between. Of course everyone is a black box programmer at one time or another. I don't know how exactly GDI draws those circles, and nor do I care. I'm a GDI black boxer.

    But when I call a GDI method, you'd better believe that I know WHY I'm calling it, what every argument to the method means, what resources it consumes that need to be cleaned up later, all that stuff.

    In short: gurus understand how it works, whatit does and why it was designed that way. Black box programmers understand why they're using it and how to use it and what it does, but not how it works. Cargo Cult Programmers sort of understand what it does but not how it works or why it works -- they just know that it works.

    When I'm interviewing people, I'm looking at all those things. ("When would you use a delegate? What are delegates for? If delegates didn't exist, how would you implement them?" -- people who know what a delegate is for but can't come up with how they might work are people who haven't seen past the abstraction.)
  • I call cargo cultists "Mouse-ka-teers". Good spellers, every one (M-I-C... lol) It works well for copying code, but isn't necessarily a good thing to do when defining your own variables. One of the first things I learned as a programmer; spell it wrong so it doesn't match a reserved word. That was 30 years ago when a 64bit mainframe filled a big ice box of a room and you got your exercise lugging around cartons of punched cards.

    These days, I consider myself both an expert AND a novice when it comes to programming. In the micro world, things change so fast, I'll always be a beginner. Just when you think you've mastered some language, you wake up the next morning!

    But you're right about the semantics of programming. Once you understand the logic, using another language is just a matter of substitution. Sort of... At least for those primarily driven by innovation and creativity. Those truly fascinated by the art of programming. Us eggheads.

    I really enjoy reading your "blogs". I've read them all. You take such a lighthearted approach, it's easy to understand, and quite entertaining. So... get to work! Lets have another fabulous adventure!!!!
  • Don't be a
  • Debugging is at least twice as hard as programming. If your code is as clever as you can possibly make it, then by definition you're not smart enough to debug it.

    - Brian Kernighan
  • I was reading this post by Eric Lippert when I stumbled the statement that Software Engineering is an immature discipline. This triggered the stream of consciousness below: Software Engineering is an immature discipline. Is it? What does that mean? Does it mean software engineering is a new discipline? How long...
  • Hey, it makes sense to me but I don't really know if I am a novice programmer or an experienced programmer. I do know that my computer isn't made out of straw and I certainly don't type away on a keyboard constructed out of wood, so I guess I'm not a 'cargo cult programmer' either.

    I'm a self taught programmer with no qualifications and that's how I like it, it's fun and it keeps the coffee industry going. I think a more appropriate term for 'cargo cult programmers' would be 'google cult programmers'

    Good read, the cargo cult was even more interesting after I read about them.
  • PingBack from
  • My colleague Mike , in a comment in yesterday's entry , mentions "Mort". Who is this Mort guy? At Microsoft,

  • I agree with your sentiments, with an anecdote to boot.

    My first exposure to programming was with Microsoft QBasic. I was about 8, and had trolled Prodigy for scripts, and came across many neat looking games. I dissected them with a fine-tooth comb for several years, and got pretty good at hacking them up, adding additional menus, moving graphics around, etc. (I was never a good artist, so I left the DATA instructions alone...).

    I couldn't figure out why the numbers went from 0-F. I had no exposure to hex. With some guesswork, I usually managed to get what I was looking for. I didn't find out until college what a hexadecimal number was. I ran into similar problems with non-square matrix division, among other things. Throughout, I understood the syntax quite easily (even polymorphism, function overriding, and streams came simply--possibly I had a good teacher). However, without understanding the external concepts I was dealing with, I was lost.

    I'm a pretty well-versed programmer. No genius, but not a "Mort", as your term seems to be. I don't run into problems with languages as much as various toolkits, particularly (and unfortunately) Microsoft's .Net Framework. Microsoft could well take your advice when it comes to MSDN, in my opinion. I've found tons of information on how .Net works, but not much on the concepts that implement it: The reasons, design decisions, and descriptions that come with a thorough understanding, presented in a clear manner.

    In effect, I run into problems pretty regularly on my projects. More than once, I've implemented something that .Net already provides, but I never knew about.

    My point in this, is that "cargo cult" programming, in my experience, is not merely about understanding the semantics of your language, but a cohesive picture of the tools available to you--the semantics of your toolkit, so to speak.

  • Two additional quick notes about books: I am also pleased to announce the availability of the C# 3.0

  • Hi, I have this vbscript but I want it to make me a sandwich. Can you write the code for me? It should know what I like on my sandwiches. Thanks in advance.

  • Hi, I have this javascript but I want it to make me a milkshake. Can you write the code for me? It should know what I like on my sandwiches. Thanks in advance.

  • "They tend to proceed by making random changes, testing, and changing again until they manage to come up with something that works. "

    Please tell me that you are exaggerating to make your point.

    Of course I'm not. -- Eric

    It has been decades since I first taught myself to program and people like the above could not be called programmers of any sort. Maybe if exposed to a new type of programming language, I might peck around whilst learning it, but I would not consider myself able to program in it at that stage. Maybe you are being too kind to this type of person, to the detriment of all programmers, by tacking on the word programmers after cargo cult?

    There are lots of people who are paid to program computers who have no formal background in computer science and whose training is in the business domain, not in the programming language domain. Whether they meet your personal standards of what makes a Real Programmer is hardly relevant; they exist and their organizations buy tools from us.

    And even professional programmers -- even compiler writers -- sometimes act like cargo cult programmers. Every time I have to write a WMI script, that's how I proceed. I do some web searches, find some samples, and hammer on them until they work. I'm totally a cargo cult WMI programmer, because I write WMI scripts two or three times a year, tops. If I did it every day, I'd invest in understanding how the thing actually works, but I don't. -- Eric

    - Paddy.

Page 3 of 4 (48 items) 1234