mac programming for dummies (1999)

Over the years, I’ve accumulated a few computer books, some of which sit on the top shelf of the bookcase behind my desk.

Picture of my bookshelf with computer books

Cormen et al. – the canonical text for an undergraduate algorithms course. Bob Metcalfe’s PhD dissertation on packet switching. Brian Kernighan’s memoir about developing Unix at Bell Labs. The Soul of a New Machine, which won the Pulitzer for nonfiction in 1982.

And, of course, Mac Programming for Dummies.

Picture of the cover of Mac Programming for Dummies

Although For Dummies books are still published today, they were much more prominent in the late 90s. Every bookstore had bookshelves full of them, rows and rows of yellow covers. For most topics you might think of, there was a “for dummies” book about it: Calculus for Dummies, Beekeeping for Dummies, Wicca and Witchcraft for Dummies, and even Success for Dummies. They were always written in a conversational, humorous, and reassuring tone.

So when, at the age of thirteen, I decided to build a computer game,1 the promises on the cover of Mac Programming for Dummies appealed to me. Maybe it really was possible to teach C programming on the Macintosh in less than 400 pages of “Plain English.”

I borrowed the book from the Santa Clara Public Library. I don’t remember why I picked it – there were surely other programming books available. Perhaps the screenshots seemed closest to what I wanted to create, all those beautiful windows, menus, and graphics of the System 7 era.

Picture of a screenshot in the book showing a menu item “Move Circle” and a window with a circle

The book traveled with me on a family vacation. Since I didn’t have access to a computer during the trip, I wrote programs by hand onto lined notebook paper. I didn’t know if they would work or not. (When I returned home and tried to compile them, I discovered that most of them did not.)

With hindsight, I realize that a book like Mac Programming for Dummies was unlikely to lay a solid conceptual foundation for computer programming. Yet as I learned more over the years – and struggled through the thousands of compiler errors and seemingly-inexplicable crashes every new C programmer faces – I came to believe that MPFD was especially inept at explaining the C programming language. I was mildly bitter about this for decades.

Recently, I decided to revisit the book, to see if it was really as bad as I remembered. After all, I formed these opinions in middle and high school, before I had any formal training. So I bought a used copy and reread it.

Unnecessary technical details

In the first few pages, the author, Dan Sydow, describes the goals of the book:

How can I make the claim that anyone can learn, with minimal effort, to write a Macintosh program just by reading this much-smaller-than-a-breadbox-sized book? It’s possible because I:

Yes, you read that correctly: “Spare you unnecessary technical details” is repeated three times. I’m not sure if it’s a joke or a typographic error.

What does Sydow consider unnecessary technical detail? A representative example occurs on page 187, when describing passing the value “-1” as the third parameter to the Toolbox function GetNewWindow:

No, I’m not going to explain what the heck (WindowPtr)-1L means. Trust me. You don’t want to know! Just make sure to type it correctly. Include the parentheses, a minus sign, the number one, and an uppercase letter L.

Fair enough. Given the ground the book needs to cover in less than 400 pages – what a compiler is, the C programming language, the Macintosh Toolbox API – it’s a reasonable strategy to explain just enough for a layperson to get the gist of the code examples.

CodeWarrior, ResEdit

The first few chapters about source code and compilation are clear, accurate, and accessible to a non-technical audience. I remember being quite excited to realize that the process for writing software was very similar to writing an essay in WordPerfect or painting a picture in MacPaint. A compiler was just a new kind of program to learn.

Screenshot of Metrowerks CodeWarrior folder

Sydow next presents Metrowerks CodeWarrior, which at the time was the dominant IDE for Macintosh development.2 Then a chapter on ResEdit, the program for manipulating the “resource fork” of a Macintosh application – images, sounds, menus, windows, etc. So far so good; I finally understood how my friend’s older brother had replaced the sounds in Glider3 with Ren yelling, “you eediot!”4

Screenshot of the ResEdit splash screen, with a pixelated Jack-in-the-Box from the top of a computer

Pointers, memory management

As I tried to move beyond the example programs to build a “real” computer game, I found myself incapable of solving seemingly simple problems. For example, how to represent a multiple game objects without knowing the number of objects in advance? And why did my programs keep crashing, often bringing down the operating system with it?

No wonder I was confused – MPFD never attempts to explain C memory management at all. Every variable in the example programs is either stack-allocated or allocated by a Macintosh Toolbox function. The word “pointer” never appears in the text. There are no calls to malloc or free.

At one point, Sydow states that some functions require an & before a parameter, but leaves the reasons as a mystery: “I can’t give you any set rule as to when a parameter requires the ampersand. You have to make sure that you match your source code with that in this book.” It’s a defensible approach given a non-technical audience, but it left me with no way to understand or debug common mistakes like passing pointer parameters in the wrong order or dereferencing a NULL pointer.

I found one other hint about memory management, in this example near the end of the book:

WindowPtr theWindow;
theWindow = GetNewWindow( 128, nil, (WindowPtr)-1L );

Sydow notes that the second parameter, nil, is “used to reserve memory for the window” but glosses over the details:

Reserving memory is a tricky business, so it’s good that you have the option of letting the Mac do it for you. If this second parameter has the value of nil, the Toolbox figures out where the new window should be stored… The nil value is used mostly for parameters that have something to do with memory. You don’t have to determine when it’s okay to use nil – I’ll let you know.

Memory management is, indeed, “tricky business” and arguably one of the most challenging parts of C programming. I can understand why he decided to avoid the topic. Still, it’s kind of impressive to write an entire book about C without covering memory management!

Function definitions, control flow, return values

I had vivid memories of struggling to understand how control flow jumps to and returns from helper functions. For years, I assumed that MPFD omitted these explanations, but rereading the book I discovered the truth was a bit more complicated. Early on, Sydow writes, “A program can consist of just a few functions, or hundreds. Don’t worry. The programs in this book contain just a single function.” For almost every example in the book this holds true; only the entry point void main(void) is defined.

Yet by page 311 the examples have gotten long enough that Sydow can’t resist defining a few helper functions to keep things organized (OpenWindow, HandleAppleMenu, HandleFileMenu). This example is followed by a page and a half explaining how control flow works in a function call. So there was an explanation in the text; I just had difficulty understanding it because I was new to programming and had only a single example to follow.

Of course, there is a lot more one could write about function invocation: the stack, variable scope, recursion. None of these are required to understand the example code, however, so it’s reasonable to exclude these topics as “unnecessary technical details.”

Less forgivable is the explanation on page 187 of function return values, which is simply wrong:

If a function doesn’t have an equal sign (the assignment operator) in a call to it, it doesn’t have a return value. For example, a call to MoveTo doesn’t return a value:

MoveTo( 30, 50 );

If a function does include an assignment operator, then it does return a value.

theWindow = GetNewWindow( 128, nil, (WindowPtr)-1L );

Whether a function returns a value has nothing to do with whether the caller assigns the return value to a variable. (Reading charitably, perhaps he meant that function calls in the example code always assign return values, although it’s unclear from the text.) Sydow can’t explain it more accurately, however, because at this point in the book the reader hasn’t seen any function definitions. The book would have been improved with the addition of an earlier section covering function definitions, return values, and parameters.

Header files, compiler errors

I remember spending hours troubleshooting compiler errors about undefined identifiers. Somehow, I figured out how to #include the correct header files to make the examples work. For years, I believed this was an egregious mistake that had somehow been missed during technical editing.

It’s true that MPFD never mentions the C preprocessor, #include directives, or header files. Yet the more I thought about it, the more incredible it seemed that MPFD had somehow published three editions with broken example programs. So I fired up an emulator, installed Mac OS 9 and CodeWarrior, and opened the projects included on the CD.

Contrary to my memory, all of the examples compiled flawlessly without a single #include directive:

Screenshot of CodeWarrior with source code for WindowWorks.c

Screenshot of a new window in Mac OS 9 created by running the WindowWorks program

How did this work? Searching through the CodeWarrior UI, I eventually found a settings dialog with a field for something called a “Prefix File”:

Screenshot of the CodeWarrior settings for the WindowWorks project, with a text field “Prefix File” set to “MacHeaders.h”

Deleting “MacHeaders.h” from that field and recompiling5 resulted in the “undefined identifier” errors I remembered from 25 years ago:

Screenshot of CodeWarrior compiler errors showing “undefined identifier”

This was still a bit mysterious, but searching the built-in CodeWarrior documentation, I found a hint:

prefix file

A header file that is automatically included in all source files; the file from which data or program instructions are copied, specified in the language settings panel, and often a precompiled header.

The prefix file “MacHeaders.h” was apparently a header file provided by CodeWarrior that included all of the Macintosh Toolbox headers.6 And the template for creating Macintosh projects configured this prefix file by default, so it was implicitly included everywhere.

So I’ll admit that my memory was wrong. The example programs did work without #include due to a feature in CodeWarrior that I didn’t understand and accidentally broke somehow. Classic user error.

But it worked, and I had created it

By the time I returned Mac Programming for Dummies to the library, I had indeed built my own Macintosh program. The last few chapters show how to run an event loop, draw to a window, and create simple animations:

I adapted this into a computer game, or at least a tech demo for what could plausibly have become a game. The files were lost long ago, but I still remember the program clearly. There was a window, with an image of a squirrel in a flying saucer I had drawn. Arrow keys would trigger an event handler, which would move the squirrel’s position one pixel, paint the background white, then redraw the squirrel.

Yes, it flickered on every keypress. But it worked, and I had created it.

So I keep Mac Programming for Dummies on my shelf now as a reminder. Of frustration, confusion, and persistence. Of excitement, of creation, of personal computing.

And a reminder, also, to never take myself too seriously, because no matter how much I’ve learned in the last 25 years, this statement will always be true: I first learned to program from a book written for dummies.


  1. A few years earlier, my dad had introduced me to Logo, the educational programming language where you give instructions to a cursor (called a “turtle”) to draw shapes. I learned a lot from this, but as I watched the turtle crawl slowly across the screen, I felt constrained. By 1999, I was ready to leave the sandbox and learn a real programming language, so I could create the kinds of games I admired. ↩︎

  2. It may be hard to believe, but at the time developer tools were very expensive. CodeWarrior cost hundreds of dollars, without adjusting for inflation. MPFD included a “lite” version of CodeWarrior on the CD for free, with the ability to create a new project deliberately removed. I believe Apple’s developer tool, called “MPW” for “Macintosh Programmer’s Workshop” may have been free, but CodeWarrior was much more widely used. It wasn’t until Mac OS X arrived in the early 2000’s that developers had access to free, high-quality tools – specifically an IDE called “Project Builder,” which eventually evolved into XCode. ↩︎

  3. John Calhoun, the creator of Glider, went on to enjoy a a long career at Apple↩︎

  4. From Ren and Stimpy, of course! ↩︎

  5. Oddly, compilation would sometimes succeed even without a prefix file, likely due to caching. Updating the project settings seemed to clear the cache. ↩︎

  6. CodeWarrior could include the entire Mac OS API by default because there were only a few thousand functions. The symbols weren’t even given a common prefix (some examples: SetRect, GetWindow, InitFonts, FlushEvents), so you had to be careful to avoid redefining them. ↩︎