Miniminalism: Philosophy, Tradition or Lunacy?

Thanks to cpantesters I'm doing something that amazes me -- as I write C, it is taken and tested for me on all sorts of different systems. This is a stern test of my ability to write portable C code, and, in general I'm quite pleased with how I've done. So far only one mistake can clearly be laid at my door.

That mistake doesn't put me in a good light -- mistakes seldom do. But we learn more from mistakes than from successes. In this case, the mistake exposes a habit of mine that programmers of the modern school will find a bit lunatic. And perhaps it will give me a good way to point out how that lunacy shaped your training as well, no matter how recent it was.

The cpantesters do wonderful things, but they can't be all things to all people. In their feedback to C programmers who cause segment violations, they make the oracle at Delphi look like the neighborhood gossip. What the C programmer who lets his pointers stray sees is almost nothing -- the prove utility will report every test after the segment violation as a failure, without further explanation. It's not even explicitly stated that the problem is a segment violation, but I've learned to suspect that is what is happening whenever prove gives me the silent treatment.

I could always contact the cpantester and ask him for a stack trace, or even send him additional tests to run. But he's a volunteer and my C programming mishaps will not necessarily be his highest priority. He may be especially disinclined to give the issue a priority if he suspects that I have not done my homework. It behooved me to try to solve the problem on my own first.

I got lucky. Rereading my recent changes, I noted where doing a fairly complex calculation might save 4 bytes in a memory allocation. Problem was, I'd seen this the first time and decided I could save 5 bytes. Oops.

On most systems, malloc() was rounding up the allocation. But on a strict few, I was given exactly the allocation I asked for and made to pay the price of my folly.

I replaced the calculation with a simpler one. Cpantesters reports for my fix are in and they run 100% clean. The simpler calculation for the malloc() buffer allocates, worst case, 4 bytes too many. From the optimization standpoint, it may even be better because it saves a few CPU cycles. Not that either way it makes a difference that could be measured.

At this point, a number of my readers will have decided that I'm a lunatic. Why was I going out of my way to save 4 lousy bytes? Without directly addressing the charge of lunacy, I would draw the candid reader's attention to my training. Nobody is drilling young programmers on the importance of saving 4 bytes any more, but the spirit of minimalism that inspired my misjudgement is more than alive today. It's dominant.

I started programming in 1970, remote time-sharing on a PDP-8. As a user, I had available a virtual PDP-8 in its minimal configuration. That was 4096 12-bit words: 6K in modern terms. When you work in a memory that small, you sweat the details.

Though I didn't think so at the time, in giving me those 6K virtual bytes, the operating system was being generous. The typical configuration of a PDP-8 for the educational market was 36K bytes of memory, both physical and virtual. This was expected to serve around 20 time-shared users.

It was the generation that learned to program on this kind of hardware which created the concepts of programming language, development environment and operating system which are dominant today. As often as not they created not just our current concepts, but the actual technology we are using.

Perhaps one example will inspire the reader to think of others. LISP remains influential. Its spirit was the flame that kindled a long series of single-paradigm languages. But given the size of the machines available in 1958, how many paradigms could a language have implemented? When we study and emulate LISP, we are studying and emulating deep ideas. To an equal extent, however, when we study and emulate LISP, we are studying the art of saving every byte as if it were our last.

4 Comments

Actually you can know when a program dies with a segfault. prove will say Wstat: 11 in the summary.

Hi Jeffrey

1970! I wrote my first Fortran code in 1971, so compared to me you're ancient :-)).

It was many years afterwards before I could truly say I knew slightly more than nothing...

But thanx for a thoughtful post. I feel the best programmers are those who go through such processes and can still step outside them and say - Hey! I was taught such-and-such, for certain reasons which seemed reasonable at the time, but I can see how do things differently now.

So, you saved 4 bytes, wasted time, learned things.

Which is most important? The learning, right?

I have learned a lot since first finding Perl. One of those things is that there are always more than one right way to do something. Which version of right depends on your requirements.

There are still times today when you will find that you have only 16K RAM and 4 bytes is a lot. 6 extra cycles to save 4 bytes is useful. There is no single method for writing code or building systems, nor is there only one right way. The reason that a mechanic generally has big tool boxes is because they need many tools. Software engineering is no different.

About Jeffrey Kegler

user-pic I blog about Perl, with a focus on parsing and Marpa, my parsing algorithm based on Jay Earley's.