Andy Canfield
Information Management Systems

A Professional Autobiography Of Andy Canfield

Do you remember what you were doing forty-five years ago? I don't. But that's how long I have been programming computers - forty-five years. I thought I'd better write it down before I forget completely. This is the result. This is the long version.

The University of California at Berkeley

I graduated from High School in June of 1966 and went to the University of California. There I was introduced to computers. They had a CDC 6400. You sat at a keypunch machine and punched cards, then gave them to the operator. A few hours later you got your cards back along with a printout. Printouts then were eleven and a half inches high and sixteen inches wide, continuous forms, with blue horizontal bars.

The concept of "turn-around time" was dominant then. Turn-around time is the time from when you submitted your program until you got the output back. Today turn-around time is measured in seconds; back then it was measured in hours.

One result of the long turn-around time was that, when you did get the output back, you tried to find every possible bug. Unlike today, when you see an error and fix the bug and try again, back then you would spend minutes, maybe even hours, hunting for clues to other bugs to fix. Your overall programming speed was determined not by how many lines you could code, but by how few bugs you could code.

I dropped out of school for a while, then re-entered. I graduated in June of 1972 with a Bachelor's Degree in Computer Science.

National Inventory Service

While I was attending the University of California at Berkeley, I was a regular at the "odd jobs" desk of the employment center there. Potential employers would call this desk, saying that they had a few hours or a few days' work for some student. Most of the jobs paid minimum wage. I picked up a lot of pocket money there.

One type of job I got regularly was cleaning people's bathrooms. A wealthy lady up in the hills of Berkeley would call down to the odd-job desk to send some guy up to clean the bathroom. I would often get the job. Many students would refuse such work, but I took it. It paid minimum wage; something like a dollar and a quarter per hour. It would take me three or four or five hours; I was not quick. But I got the job done, and I got the job done well. When I was finished, that bathroom was clean; top, bottom, sides, undersides, all of it.

Another regular was National Inventory Service. NIS would go out to a customer's premises and take an inventory. Grocery stores would use them to check what was actually on the shelf. There was an airline parts depot which called them in once a year to determine their actual stock on hand. NIS liked my work, and would ask for me by name. They said that I was slow, but when they put me on a table they knew that they were getting an accurate count for that table.

National Inventory Service guaranteed the accuracy of their work; they guaranteed that their results were within one quarter of one percent. Privately, the boss admitted that there was no way they could be that exact. The trick was that the customer had no idea what his actual inventory was, so the customer had no way of knowing how far off we were. Only once did they ever have to pay off on that guarantee; in that case the customer had gotten two or three inventories, and ours was off. So the company didn't get paid for that day's work.

Then National Inventory Service decided to develop an inventory control system for Ford auto dealerships. It was to be computerized. For a start they had two customers. The master inventory records were on punched cards. There were two thousand cards to a box, five boxes to a carton. The larger customer's inventory was two cartons of cards; the smaller customer's was about three and a half boxes. They hired me temporarily to run the IBM punched card sorting machine that was used to sort these cards. They had a programmer that had written the application in a language called RPG (Report Program Generator). It ran on an IBM 360/20. This was in 1969.

National Inventory Service asked me to stay on permanently. By that time I had dropped out of college, so I said "yes". A short time later their programmer disappeared. One Friday he worked normally, Monday morning he never came in. Never came in again. So I was left with the full programming job.

I remember that every card had a date field on it. To save space, the field was only five characters - the last digit of the year, then the two digit month, then the two digit day of the month. So, for example, November 15, 1969 was encoded as "91115". This was the design I inherited from the previous programmer. It looked OK when we started it, in November, 1969. It worked well in December, 1969. Then, when "91231" was followed by "00101", It hurt. Suddenly sorting the cards got more complicated. I had experience with a "decade bug" of 1969/1970 thirty years before the "millenium bug" of 1999/2000. (By the way, the millenium bug wasn't really a millenium bug; it was a century bug.)

Most the work was in RPG, but there was some work in Assembler and some in COBOL. They wanted me to write a COBOL program to read a master tape and an update tape and produce a new master tape. The problem was that they only bought two tape drives. I worked in COBOL, and in assembler, and learned how to read from and write to the same tape on a single tape drive. Everybody I knew said it was impossible. Eventually Ford said that they could send us a whole new master tape every month, so we didn't need to process an update tape, and the whole update task was dropped. But it was my first experience with doing something "impossible".

In January of 1970 the company rented a computer from IBM. This was an IBM 360/20 Model 3. It had a room of it's own. It consisted of three pieces, each about the size of your desk. Being IBM, they were all blue. The central processing unit was, of course, central. To the right was the Multi-Function Card Machine (MFCM), the most sophisticated punched card manipulator anyone has ever marketed. To the left was the printer. In another room were three keypunch machines. The whole setup RENTED for one thousand five hundred dollars per month.

The IBM 360 did not have an operating system. Programs existed in stacks of punched cards. I remember that the RPG compiler was about 1,500 cards, whereas the assembler was only about 300 cards. When you wanted to compile a program, you put the compiler deck into hopper #1, and the punched cards of your source code into hopper #2, and a whole bunch of blank cards behind that, also in hopper #2. The dials on the CPU unit were set for "0080" (hex). Push the blue button labeled "LOAD". This caused the CPU to read the first card from hopper 1 into the memory address set by the dials, and jump to that address. The first card had better be a program, because it would be executed. The first card was, typically, an absolute loader that would read the next few cards into memory into the storage locations punched onto those cards. These next few cards were often a relocating loader, which would read the first phase of the compiler into memory and jump to it. The first phase of the compiler would then read your source code and study it and store information about it in memory. Then it would read the second phase of the compiler into memory, which would study it some more. Finally, the compiler used the blank cards in hopper #2 to punch out an object deck of cards.

So in 1970 the IBM 360/20 started by reading the first card from the first hopper into a fixed memory address, and jumping to it. Today, in 2013, your computer starts by reading the first sector from the first hard disk into a fixed memory address, and jumping to it. Some fundamental things never change.

On the 360/20, to run your program, you would put the three cards of the absolute loader into hopper #1, then the object deck of your program. After that you could put other data cards into hopper #1, and other cards into hopper #2. Typically we would have the master file in hopper #1, and transaction records in hopper #2, one card for each received shipment or sale. The transactions were all sorted by part number, as were the master file records. After each batch of transactions for one part number there would be a blank card. The program would read the master record, then read the transactions. When it got to the blank card, it would punch out a new master record and toss the existing master record into a different pocket. There were five output pockets on the MFCM ("Multi-Function Card Machine"). Each input hopper held about one thousand cards, and each output hopper held about one thousand cards. Considering that the master file was ten or twenty thousand punched cards, running a program meant feeding cards into the hoppers, taking the cards out of the pockets, and trying very very hard not to drop them, and not to get mixed up about what to do with the stack of cards in your hand.

In those days there were reel-to-reel tape drives, and there were hard disks, but they were expensive. So we saved money by using only punched cards.

I am one of the few people you would ever meet who has actually programmed in machine language. Not assembly language, but actual machine language. Suppose I wanted to copy cards to the printer. IBM distributed a special card that you could put at the start of your deck of cards, and then put the whole thing in hopper #1 and push the "LOAD" button. The CPU would read the first card, the card from IBM, and that card contained a program to read all the other cards and print each one.

I could write in assembler language, but I always had to have these special cards before and after my program card, so I had a three card deck in front of the cards I wanted to list. I learned how IBM did it in one card, and I learned how to program in machine language so that I, too, could write one-card programs.

To create a one-card machine language program for the IBM 360/20, You first had to writ the program, on paper, in assembler language. It would look something like this:


There, that's pretty crude, eh? Of course, the actual assembler language looks a bit different, but to anyone who knew assembler language, that is what it meant. Then I had to translate each assembler instruction into actual hexadecimal machine "op-codes" and fill in the addresses:

0080: 45 01 00 01
0084: 47 FF FD
0087: 44 11 00 01
008B: 47 FF FD
008E: 30 FF EF

(I can't remember the exact hex values, but that gives you the idea). That means that the card must have, punched on it, these characters (in hex):

45 01 00 01 47 FF FD 44 11 00 01 47 FF FD 30 FF EF

So I would sit down at a keypunch machine and look at the code table to see what was a 45 hex. It was, perhaps, the character '$'. So I would punch a '$'. The next character is a 01 hex, and to this I must hold down the multi-punch key and type '-', '4', and '9'. Then the third character, then the fourth, etc.

Eventually I would come out with a single punched card whose column punches, in hex, were the desired machine language program. Put that card into hopper # 1, put the data cards behind it, punch the "LOAD" button, and away you go. If I did everything right, it would work. If not, welcome to debugging.

That was my first computer - the first computer which I was in charge of, the first computer I had full and exclusive use of, the first computer I had to turn on in the morning, the first computer I had to turn off in the evening. An IBM 360/20. Oh yes - it had eight kilobytes of RAM. No monitor, no keyboard, no hard disk, and certainly no mouse (mice hadn't been invented yet.)

1970 was our big opportunity with this inventory system. We had hopes of getting contracts from all the Ford dealership parts departments on the west coast of the United States. Unfortunately, the first half of 1970 saw a big slump in automobile sales. Nobody was buying cars, the dealerships were short of money. At the beginning of summer National Inventory Service went bankrupt. The people who worked at National Inventory Service of Berkeley, California, USA were re-organized as Mission Control of Hayward, California. The computer, the office, the debts, were left behind. With no computer and no program they no longer needed a programmer. So I was out of a job.

Stanford University

While attending Berkeley I decided that a programmer who merely knew how to program was less marketable than a programmer who knew what to program. Having gotten a Bachelor's Degree in Computer Science, I spent a year at Stanford University in Palo Alto, California, U.S.A.. I got a Master's Degree in Operations Research in 1973. But since the degree was awarded at the end of the summer of 1973, the actual diploma - the certificate - was issued in June of 1974.


In the autumn of 1973 I was hired by Systan of Los Altos, California. Systan was a transportation consulting firm. Sad to say, Systan no longer exists.

At the time Systan had work both inside and outside the United States. At the time the UNDP was giving money away to third world countries in order to build more highways. But to get the money to build highways, you had to have a national transportation plan. No problem! The UNDP was also giving away money to create national transport plans. Systan was a major player in carrying out these plans. When the highway network got complex enough to require computer analysis, they brought me in.

In the winter of 1973/74 I worked on the Saudi Arabian National Transport Plan. If your memory goes back that far, you remember that the oil embargo was active at that time. We were extensively investigated before being allowed into the country. Saudi Arabia had the most severe visa application I have encountered to this day. For one thing, they wanted to know every address you have ever lived at. Think about it: how many apartments did you have when you were attending college? They also wanted to know every organization you were ever a member of. An irony was that United States law prohibited us from discriminating against anyone just because he was Jewish; however no such law applied to the Saudi government, and you knew that they weren't going to grant a work visa to any Jewish person. So, in theory, if you were Jewish, the company had to hire you for the job even though they knew that Saudi Arabia would never let you in.

I did programming for the project; mostly in FORTRAN. I learned a lot about practical programming. I remember one lesson well. I had a FORTRAN program that accumulated results in a very large two-dimensional matrix. The small test matrix worked fine, but a full-sized matrix was too big to fit in memory. So I spent a month creating a set of assembler-language subroutines to implement a sparse matrix. That is, there was a function to set the value at any specified row and column, and another function to get the value at any specified row and column. The trick was that the assembler routines only stored the non-zero cells, as a triple ( row, column, value ). By not storing the cells that were zero, the whole sparse matrix fit into memory. After everything was running smoothly, I learned that I did not need to do that: by punching ",PARTITION=GIANT" on my job card I would have been given more RAM and the original program would have worked immediately. The lesson was - always look for the easy way out; before you build your own truck, ask if you can borrow a pushcart.

After Saudi Arabia I worked on extending Systan's existing simulation of a container port. I was stationed for a while in Seattle, Washington, USA where we were modeling the container port there, and later went to Jakarta, Indonesia where we simulated the port of Tanjung Priok.

The next year - July 1975 to June 1976 - I worked on the transportation plan for Central America. The office was in San Salvador, El Salvador, and the computer was in San Jose, Costa Rica. Back in those days there was no Internet and virtually no timesharing. To use the computer I would get on an airplane in San Salvador and fly to San Jose. The computer was in a college there, and we could only use it at night. I'd check in to the hotel, have dinner, and take a cab out to the college. I would work all night, and at dawn take another cab back to the hotel. The computer was one of the "real" 360 models, maybe a 40 or 50, running PCP. IBM in those days had TOS (Tape Operating System), DOS (Disk Operating System), PCP (Primary Control Program), MFS (Multiprocessing with Fixed Partitions) and MVS (Multiprocessing with Variable Partitions). PCP was like the smallest of the full "OS" versions; to an application it looked like a full OS but PCP could only do one thing at a time. But I could do it all alone - guard, warden, programmer, operator, everything. After a few months another programmer joined us, and he and I would work all night together.

There was another guy, too; a local fellow who was just learning about computers. The three of us would fly down and fly back a few days later. While we were in Costa Rica there was no communication with El Salvador; phone calls were just too expensive back then. I remember one night we flew down and the San Jose airport was all socked in with fog. The pilot had to fly on to Panama. They took all the passengers in a bus to a big hotel. At the hotel I bought a postcard of Panama. I wrote "Having a great time, glad you're not here." We all three signed it and sent it to my boss. At 4AM we were awakened to go out to the airport and fly to Costa Rica. A few days later my boss flew down to Costa Rica; he sure wondered what we doing in the wrong country!

After Central America I worked in Systan's California office for a few years. The only other time they sent me overseas was for three months to Portugal.

In California I used the Stanford Timesharing System to extend our regionwide transportation system simulation model we had. It was the first time I had ever used a timesharing system. To sit at a keyboard, looking at a screen and writing code and testing code, that was incredible. Turn-around time went from hours to minutes. Hurray!

I wrote a game, a 3-D tic-tac-toe game played on a 4 by 4 by 4 cube; once it got good enough to beat me, I randomized it's intelligence level and it's aggression level so you never knew when you started it what you would be faced with. Sometimes it was lean and mean, sometimes it was soft and timid. Sometimes it was easy to win, sometimes impossible. But whatever it was, it kept the same personality as long as you kept it running, game after game. Then you quit. When you restarted the program the next time, it would have a new personality.

It was on a Systan project that I encountered the worst programming language of all time. This was called UMTA Specification Language ("USL") (UMTA itself is an acronym for Urban Mass Transportation Agency).

USL had three features that made it incredibly bad. The first bad feature is that subsidiary clauses are indicated solely by indentation. This results in code that looks like this:

    if it is raining in Spain
      if you are on the plain
        you get wet
        you stay dry

Programmers indent their code like this, but always there is something else, like braces, to control the conditional clauses. USL did away with these other indicators, and relied solely on the indentation. That sounds like a good idea. But suppose that the subsidiary clause (like "you get wet" in the above example) is not one line, but two and a half pages of stuff. It's awfully hard to figure out whether the "else" clause is exactly under the first "if" or the second "if". A programmer, when indenting the "else", can easily get it off by one space, and change the whole structure of his program.

Programming languages use letters for variable names. Some languages use only capital letters, like FORTRAN. COBOL allows hyphens, C allows underscores, to break up variable names into words, like READ-ANOTHER-RECORD or READ_ANOTHER_RECORD. The creator of USL decided to allow blanks. A sequence of one blank would be allowed in a name. So "READ ANOTHER RECORD" could be a name. But then again, it could be three names. Or it could be two names; "READ ANOTHER" and "RECORD". Or it could be two names; "READ" and "ANOTHER RECORD". In his effort to make USL code readable by humans he made it darned impossible for a human to read it.

The worst aspect of USL, however, was that it was implemented as a macro language, generating FORTRAN code. As a consequence, whenever you wrote a line of USL code you had to program in three different languages. Suppose you wanted to write down something like "if new bus ident equals old bus ident". You had to consider all the ways that this might appear in USL language, e.g. "if ( NEW BUS IDENT EQUALS OLD BUS IDENT )". At the same time, you had to think about what macros would be involved; e.g. "NEW BUS IDENT" is one macro, "EQUALS" is another macro, and "OLD BUS IDENT" is a third macro. Finally you had to think about what FORTRAN code the macros would translate into; e.g. "NEW BUS IDENT" is "NBUSID" which is a REAL. If the bus ident is characters, these could only be stored in ANSI FORTRAN in integer or real values. But if the bus ident is five characters, that's too long for a single variable, and so "NEW BUS IDENT" would have to be two variables, and there's no way to define "EQUALS" to compare two variables on the left side with two variables on the right side. You're programming in three languages at once, concurrently. It was a nightmare.

We had, foolishly, agreed to use USL in the project. But, fortunately, the agreement also said that we would do the work on Stanford's IBM 370 timesharing computer. The creator of USL had only implemented it on a DEC computer. The contract called for UMTA to give us a version for the IBM 370. The creator of USL was an optimist, the 370 version of USL never worked, and we got off the hook. We were allowed to write it in ANSI FORTRAN, which was what USL would have generated anyway, but which was a whole lot easier to program, being only one language, not three.

Programming Languages

I once had a book which taught computer programming. The last chapter of the book talked about Automatic Programming. No longer would you have to write a program for your computer. Instead, you just wrote down the formulas that you wanted your computer to evaluate, and a package would translate these formulas into a program that would do the job. No more programming! The package that would translate the formulas was called FORTRAN. The book was printed in 1954.

The idea of not writing programs, of just telling the computer what you want it to do and letting the computer write the program, is a flawed myth that goes back at least half a century. It's always wrong. This is because

The art of programming is the art of saying exactly what you mean.

Any system of saying what you mean becomes a programming language. USL was sold to UMTA as a specification language, but it was indeed just another programming language, and not a very good one. FORTRAN is a programming language. So is C++. So is Java. So is Excel. So is Visual Basic. Some use text, some use drawings, some use sequential execution, some use parallel computations, but they are all ways of telling the computer what you want; they are all programming languages. Not all programming languages are equal. Some are better at one thing, some better at another. But all require you to slow down, and think, and say exactly what it is that you want.


I was working in Central America for a year. I was away from the Los Altos, California head office of Systan, in the heart of Silicon Valley. During that year, the guys at the Silicon Valley Computer Club invented the personal computer, including the Apple. Later, my boss got an Apple II and put it in the office and I learned that thing inside and out. He talked Hewlett Packard into giving us their CP/M computer (an HP-150 I think it was called) and I learned more on that. We had one or two other microcomputers around the place. I and another guy spent a year working on a "database" package; the sort of thing that DBASE eventually was master of. It was for CP/M, and it wasn't terribly good, but again I learned a heck of a lot. To make it work we had to invent our own overlay system.

I found I loved working on microcomputer software, and I wanted to get into the big time. So I got a job at Sorcim.

Lifeboat Associates had invented the spreadsheet for the Apple II; the program was called VisiCalc. They didn't bother to port it to CP/M. The leading spreadsheet package for CP/M was SuperCalc, from Sorcim.

By the way, in my posession today is a CP/M-86 boot diskette. Stick it in a new PC and it will boot CP/M Version 1.1 from 1983. Special wrapper code has been added to allow it to work with 1.44 MB diskettes; other than that it is the same exact code shipped by Digital Research in 1983. I downloaded it from the Internet. The fact that it still boots, it still runs, is an incredible testimony to upward compatability; code for the 8086 chip still runs on the latest Pentium.

I think they hired me partly for my knowledge of database systems, because they had a new database package almost ready for market. They hired me and let me experiment with it and they heard the bad news from me. It was way, way far from finished. The programmers were enthusiastic, not realistic. For example, in my review I said "The main menu has six items on it, and four of them do nothing at all, so how can they say it's ninety percent finished?" Sorcim set me on a new, different project and a short time later killed the database project.

I was project leader on a secret project to develop an integrated software package for computers that had only eight line LCD screens. We worked a year on it. It was released for the Sharp, and we were preparing to release for the Gavilan. Then one day we saw a new laptop computer with a 25 line LCD. The instant we saw it, we knew our project was dead; why run special software for eight line screens when you can run standard MS-DOS software for the full 25 line screen? But, once again, I learned a lot; about MS-DOS and the internal workings of PC computers.

Soon after I joined Sorcim, they had a special offer for their employees. The company would buy a computer for you. Because of the volume, the company would get a good discount from the vendor. The company would legally own the computer for the first year, so they got the value of the first year's depreciation. During that year you paid so-much a month, deducted from your salary. You could keep the computer at home. If you left during that year, you had to return the computer to the company. But if you stayed with the company that year, the computer was yours. The deductions added up to only one-half of the normal price for such a computer. It was a win-win situation for everyone. The employee got a computer out of it at a bargain. The company got employees to be more expert in the computers. The deal made employees very unlikely to quit during that year. The vendor got a big deal. Everybody won. I got an IBM PC, with 640 kilobytes of RAM, two diskette drives of 360 KB each, no hard disk, green and black monochrome monitor (no color), no graphics. I bought a 300 baud modem to go with it.

What does your code see when the user presses a key? On the IBM PC, that depended on what level your program grabbed it. At the top level you got things like "A" (hex 45) and Enter (hex 0D). For a function key, you got something like hex 00 followed by hex E1 (my hex numbers off; sorry about that, you get the idea). But at the absolutely lowest level you could take over the keyboard interrupt. If the user pressed a key, you would see something like hex 5C when it went down, then another 5C every so often, and finally a hex DC ( 5C + 80 ) when it went up. It was the first and, so far, the only computer I've ever known where you could tell exactly when a key went up. So I wrote an organ program for it. The keyboard row starting with "ASDF" were the white keys, and the black keys were the "QWER" row. At the advice of my sister, who played musical keyboards for years, the "S" key was middle "C". She said that if you could get down to B-flat ("Q" on my keyboard), you could play almost anything. It worked. Press down on "S", and middle C would play. Let go, and middle C would stop. "S DF SFSF" was the first line of the DO-RE-ME song ("Doe, a dear, a female dear"). The keys made the notes, and your fingers made the timing. It was live; I never build a record/playback facility into it. Unfortunately, no one has a copy of it. It was lost when I moved to Thailand.

One of the easily forgotten facts of the early PC days was that there was no generic MS-DOS. Microsoft would not sell MS-DOS to individuals. Microsoft sold MS-DOS to computer companies, who then tailored MS-DOS to their equipment and sold it to users. So there was IBM PC-DOS for IBM computers, and Compaq MS-DOS for Compaq computers, and Gavilan MS-DOS for Gavilan computers, and so on.

Sorcim needed to develop software that would run under MS-DOS on whatever machine the user owned. But what were the features of that MS-DOS? What could we count on being present? What was standard in all versions of MS-DOS, and what was unique to each individual computer company's adaptation? We could not know. Microsoft would not tell us. Not being a computer company, we did not buy the MS-DOS adaptation package from Microsoft. Microsoft did not publish any documentation for (generic) MS-DOS itself; each computer company was responsible for documenting it's own particular version.

Take two examples. On the one hand, the application program interface included operating system functions that our program should call in order to write a file. These had to be standard across all versions of MS-DOS, because if they were not then nothing would work. On the other hand, we knew that the MS-DOS "FORMAT" command varied from computer to computer depending on the particular diskette formats supported by that manufacturer. So our program could reliably write files to diskette, but our program could not reliably format that diskette.

The "PAR" project was to create software to run on eight-line LCD screens. One of the computers we were developing for was the Gavilan. The Gavilan had not yet been released to the public. I don't remember whether it was ever released. But we worked with their programmers to make sure that our code would work on their machine. We talked about this problem of a generic MS-DOS. At one point someone from Gavilan slipped us a copy of Microsoft's documentation that came with the adaptation package. That is, because Gavilan wanted to run MS-DOS, they bought an adaptation package from Microsoft. Microsoft delivered the code and documentation to them. The contract between Microsoft and Gavilan was very strict about keeping this material confidential. The people at Gavilan were prohibited from giving us a copy of the raw code or the documentation. We did not want or need the code, but we needed the documentation. We needed to know what was in the package so that we could know what features of MS-DOS we could count on to be present in every computer. So a nice guy at Gavilan gave us a copy of the documentation. We studied it carefully.

The IBM PC had started an industry. The Compaq computer company had proved that they could come out with a machine that was hardware compatible with the IBM PC. The Compaq computer was so compatible that it would boot, and run, IBM PC-DOS. Conversely, the Compaq MS-DOS was so compatible that it would boot and run on an IBM PC. This became the effective definition of "IBM PC compatible". If you machine would boot and run Compaq's MS-DOS, then your machine was a PC compatible. The Compaq DOS became the effective generic MS-DOS.

About MS-DOS version 3, Microsoft supported networking. Curiously enough, it was supposed to be implemented in version 3.0. But the code wasn't quite ready. Version 3.0 shipped with SHARE.EXE, which was needed for networking, but there was no networking support yet, so there was nothing for SHARE.EXE to do. SHARE.EXE would let you share files, but since you couldn't run two programs at the same time on only one computer, there was nothing for SHARE.EXE to share. Only in version 3.1 was networking released and SHARE.EXE got some work to do. The last Compaq MS-DOS version of the "3-line" was Compaq DOS Version 3.30. There was no MS-DOS version 4; rumor had it that version 4 had been released in Europe, but never in the US. So during that gap, Compaq DOS Version 3.30 was the effective generic MS-DOS. Many people ran it; many people who did not own a Compaq computer ran that operating system. You could build a generic PC from standard parts, but then you found a copy of Compaq DOS 3.30 and used that as your operating system. Companies were not so strict about copyright in those days. Compaq didn't care; they sold hardware, not software.

Finally, Microsoft released Microsoft MS-DOS version 5.0. It ran on IBM PC-compatible computers such as the IBM PC and the Compaq. It was the first time that Microsoft had sold MS-DOS through the retail market; the first time that anyone could buy a copy of an officially generic MS-DOS.

100% IBM PC compatible

I must confess to having a hand in one of the bits of history. We came up with the term "100% IBM PC compatible". Many companies made computers that they claimed were IBM PC compatible. But in many cases they had a different BIOS interface, or different screen hardware, or something else that worked differently. By adding the term "one hundred percent", we really said "Hey, our program runs on the IBM PC; if it doesn't run on your computer it's your problem, not ours." The addition of the "one hundred percent" sounded like there was a standards organization testing this hardware for IBM PC compatibility, but the phrase really absolved us of any responsibility for being able to support your (weird!) hardware.

8-bit traansparent

In these small computers (called "microcomputers" in those days) the memory was addressed as 8-bit bytes. That is, memory location 1234 was eight bits, and memory location 1235 was another eight bits. To get more bits, you had to use two or four or eight memory locations, for 16 or 32 or 64 bits. That is still true today.

But the standard character set was ASCII, and ASCII defined 128 characters, 7 bits in each. For example a bit pattern of 100 0001 (hex 41) was the character "A". That is still true today.

Hey, for every character in the machine, we have sone spare bit doing nothing! What can we use that spare bit for? Well, everybody used it for everything. Wordstar used the extra bit to indicate the end of a word; the the word "CAB" would be stored as

	C =        A =        B =
	0100 0011  0100 0001  1100 0010
(notice that the first bit of each character in the word is "0", except for the ending "B", which has a "1" bit there.)

When the IBM PC came out, IBM used the extra bit to define more characters. Some of them were the famous "box-drawing" characters which we could use to draw a single-line or double-line box around text (before the days of graphics). Some where used for western European languages. These were very useful, and, being on the IBM PC, they became sort of "standard". Except your screen looked pretty funny if your program used the IBM box-drawing characters but that monitor showed them as French vowels!

What gave us the most trouble, however, is that some software would mangle our characters. If we put the character 1100 0101 into a text file and opened that file with WordStar, WordStar would change it to 0100 0101 because WordStar didn't like the extra IBM characters. Or we might use the character 1000 1100 to show some graphic, but WordStart would change it to 0000 1100 which is end-of-line. Even sending such characters to another computer through dial-up modems could cause some bits to be lost. We hated that.

We adopted (invented?) the term "8-bit transparent". What does that mean? That means that my program gives your program eight bit bytes, ANY bits, any one of the 256 possible bytes, and your program DOES NOT ALTER the bits. Eight bits in, and EXACTLY the same eight bits out. Transparent to all eight bits. Otherwise it's like wearing a sign that says "kick me".

Unfortunately, the concept of being 8-bit transparent has disappeared from the computer culture. I'll give you an example: MySQL. Idealistically, I can write a program that feeds arbitrary 8-bit characters into the MySQL client library code, and store it on a MySQL server which faithfully records the 8-bit characters that it receives. When I read those records back, I should get the same 8-bit characters I sent. Right? Wrong!

Why? Because although we have carefully declared the MySQL database on the server to be 8-bit transparent, and the MySQL library client code to be 8-bit transparent, in MySQL the default CONNECTION between the client and the server is ISO-8859, which is ***NOT*** 8-bit transparent! Why the %$#@! they didn't designate the default connection as 'binary', 8-bit transparent, is beyond me. But although the client is sending good bites to the connection, the connection is MANGLING them to fit it's idea of a western European character set, then passing the mangled bytes on to the server which faithfully records and plays back exactly what this messed up connection gave it. If your original characters were 8-bit Thai characters, you are getting garbage back.

Today that is somewhat dated. Today everything is, or should be, in Unicode. But even today we have problems with Unicode. Unicode uses 24 bits per character; lots of room for all human languages and then some. But bytes are still 8 bits each, so there are different ways of encoding big Unicode characters into small bytes. Every once in a while I get burned on that. The one I hate is 16-bit encoding (UTF-16 or UCS2), which stores MOST Unicode characters in 16 bite and just garbles the rest as unimportant. That's the Unicode that Microsoft Windows uses; that's the Unicode that JavaScript uses. For most things I use UTF-8. But recently I had to pass data from PHP to JavaScript, and discovered that I had to convert UTF-8 to UCS-4, transmit the UCS-4 numbers, then convert them to UCS-2 at the JavaScript end. Ah, the simple days of 8-bit transparent!

Computer Associates International

While I was at Sorcim, the company ran into financial difficulty and was bought out by Computer Associates International Incorporated. This was my first experience working for a Fortune 500 company.

For a month or so they made me a manager, but I didn't like it, and they didn't like it, so we stopped. I enjoyed being a project leader, but I hated being a manager.

But I learned a lot being a manager for even so short a time. I learned how to handle managers. My people would come up to me and say "I've got nothing to do. Give me something to do." Well, frankly, if I had anything interesting to do I'd be doing it myself. I hated that when they asked for work. In later years, no longer a manager, I learned the trick. Always have something to do. Always have three or four things going on. Each task must be ongoing. Each task must be of undoubted benefit to the company. Each task must be feasible. So now, on those rare occasions when a supervisor or manager comes to me and says "What are you doing now?", I can say something like "I'm getting the new code ready for Farmer Accounting. Also, I'm experimenting with Thai Linux, which we will use for the buying program next year. Also, we're negotiating with the vendor for some new computers. And, of course, I will be meeting with that delegation next Wednesday.". He says "Erp" and walks away, knowing that I'm busy, knowing that I am not idle or lazy, convinced that I'm a valuable asset to the company. Being a failed manager was a very useful lesson.

We networked our computers using the 3Com system. I was the network administrator. Later, a young lady was hired to act as the network administrator. The most important thing I tried to teach her as that, as network administrator, you don't go home until the network works. Maybe you can go home at 4PM almost every day, but sometimes you can't go home until dawn. You're responsible. As a network administrator, you don't get to leave the office when the bell rings. You stay until it works.

At that time networks had "file servers". I invented "CPU servers"; powerful computers to which you could submit a job for execution. For example, it took almost an hour to compile our flagship product - SuperCalc - on one of our programming workstations. But a programmer could tell one of the CPU servers to do it, and get an executable program back in ten minutes. Naturally, in a CPU server, there was no human on the keyboard. So if an application hung it had to be killed. But how to detect? The most technically difficult part of the CPU server was detecting when a program was hung waiting for keyboard input. My special keyboard device driver code had to calibrate itself for the machine it was running on during the boot process. Then it could tell the difference between occasional checks for keys by an active program versus a program doing nothing but waiting for keyboard input.

Software piracy was a problem then, too. Sorcim had me develop the "Network Activator". We would sell a customer a ten copy license for SuperCalc, and each user had to have an activation disk. I wrote the program that created ten activation disks from the master disk we sent the customer. I developed it, and debugged it, and sent it to QA. My first program to actually go to the Quality Assurance department. They could only find one flaw in it. "When the program is running, and the user turns off the power to the computer, the program does the wrong thing." Not only is that on the boundary of ridiculous, but it turned out that I had considered that possibility, and the program could only do one thing or the other, and the choice I had made was the correct choice; the choice the QA department chose was in fact the wrong choice. But that stands as a classic of QA error reports: when the power dies the program does the wrong thing.

Eventually I did not like working for a huge company, and I quit to go to work for DocuPro.


DocuPro had one and only one product. The easiest way to describe it is as an extremely high end word processor. It was an object-oriented technical documentation development tool running under UNIX on Sun workstations. The customers needed high-accuracy documentation; they were typically airline manufacturers, that sort of thing. For example, positions on the page were measured in units of a millionth of an inch.

Everything in the (customer's) document was an object. There were paragraph objects and text objects and even a document object. These objects were stored in an object-oriented database that DocuPro had developed. I worked on the project to allow multiple workstations to edit one document at the same time. We had to deal with object locking and versioning.

(When I wrote the preceeding paragraph the idea of a document as a collection of objects was weird and radical. Today the world wide web runs on the "Document Object Model".)

It was at DocuPro that I realised that there are two types of locks - machine locks and user locks. A machine lock is the situation where one workstation is updating something, and it has to lock the object while it updates it. A user lock is the situation where a human has started editing an object, and other users have to be kept away from it until that user is finished. The technical distinction can be measured this way: From the time the lock is obtained, until the time the lock is released, is there any user interaction involved? If not, it is a machine lock, and we can guarantee that the machine lock will be released "soon", in a fraction of a second. If there is any user interaction between the lock and the unlock, then it is a user lock, and the user lock could be held for minutes, hours, or even days. The guy could have locked the object to edit it, then left for lunch, met a pretty girl, and won't be back until tomorrow.

The distinction is important because conventional software just recognized "lock", and if some other machine has the object locked you can specify how long you want to wait for the lock to be released. Instead, software needs to distinguish between a machine lock and a user lock. If the software is blocked by a machine lock, it should wait "forever" for the lock to clear; forever is expected to be a matter of milliseconds. If the software is blocked by a user lock, the program should give up immediately and report to the human user which (other) human user has the object locked. That way Charlie can walk over to Bob's cubicle and say "Hey, when are you going to be done working on page 3?" Years later, when I did the multi-workstation locking system I implemented user locks as distinct from the language's built-in "machine locks". No other system I know of supports user locks.

Today, of course, everyone uses SQL's 'transaction' capability. That means, roughly, that you go ahead and ignore the lock conflict, but the server keeps track of everyone's changes, and if, when you're done, you have an update problem, your entire transaction goes blooey.

DocuPro ran into financial difficulties, and was purchased by III.


We knew this company as "III" - e.g. AYE AYE AYE, three letters. The "I"-s stood for something, but I cannot remember what they stood for.

I started work at DocuPro in November of 1987. I was supposed to have received an annual review in November of 1988. But they kept putting it off. I was promised by my boss that any wage increase would be retroactive back to November of 1988, so I was not worried. III bought DocuPro in June of 1989. III reneged on this promise, but they did not tell me. I stayed on, expecting the retroactive pay. In July my boss had a staff meeting with all the programmers, and he said in public that all the pay increases would be retroactive. The III management heard about this and called him on the carpet, told him that retroactive wage increases where against company policy. They told him, but they did not tell me. I stayed on, relying upon the promise. Finally, in November of 1989, when my next annual review was due, my boss finally told me. I was, of course, rather pissed. For personal reasons, I was leaving the country, and so I didn't want to be bothered to sue them, but I am sure I would have won (action relying upon a promise) and probably could have won punitive damages. The actual money they cheated me out of was only three thousand dollars, so I walked away from it. Besides, suing your employer does not look good on a resume. Ironically, between the time I was cheated, and the time I quit a few months later, III fired my boss.


I had broken up with my wife, and my personal life was pretty bad. I contemplated suicide, but at the last minute decided to move to Thailand instead. On April 2, 1990 I boarded an airplane with a one-way ticket and three thousand dollars in my pockets, and have never regretted my choice.

Chulalongkorn University

What do you have to do to find work? Everything!

I arrived in Bangkok, Thailand in April 1990. To find work, I did everything. I walked the streets. Every time I walked past a building that looked like it would have a computer inside, I would go in and introduce myself and see what kind of stuff they had. I looked in the classified section of the newspaper. I looked in the news for likely companies. I asked everyone I met. Do everything, and eventually something clicks. But you never know what.

The hardest kind of work is selling. I have great respect, and pity, for sales people. They have to learn to take rejection. Ninety-nine percent of the contacts say "NO"; you do it because the other one percent are your lifeline. And looking for a job is just another form of sales. It's selling yourself. Ninety-nine percent of the possible clients you contact will say "NO"; you keep doing it because you need that other one percent to survive.

Joke: A guy walks into a bar. There's a fellow at one end of the bar, and a pretty lady at the other end. The new guy walks up the lady and says "I want to make love to you tonight." She slaps him in the face. He walks down to the other end of the bar and orders a drink. The fellow there says "You must get slapped a lot!" The new guy says "Yeah, about nine times out of ten." That's sales.

Exception: the lady at Sorcim who was the network administrator. She was fresh out of college, a Vietnamese refugee, a naturalized U.S. citizen, and single and pretty. As she graduated from college, she sent out TWO resumes, and got TWO job interviews, and received TWO job offers. She accepted one of them. I've never heard of anyone finding work so quickly.

One day I decided to walk into the computer science department of Chulalongkorn University. I figured they would know what computers were around, what companies had computers. They could tell me where to go. Instead, they offered me a job themselves, and I accepted. I became an "acharn", a professor. It was kind of silly, though. I could only speak English, and all classes were conducted in Thai. So I did research, and I gave two lectures on object oriented programming. I wrote up my lecture notes, and I heard several years later that someone was translating my lecture notes into Thai. But I never saw a copy.

Career Path

The world famous red light district in Bangkok is a street named "Patpong". My job at Chulalongkorn was North of Patpong; my apartment was South of Patpong. Every day I'd get off at five and walk home down Patpong. I was in no hurry, nobody was waiting for me at home. So I would sit on the curb and chat with the street people. I had no money; I could not afford to go into the go-go bars. So I would just sit and learn. This is what I learned:

  1. The lowest class hookers sold sex: "You want to screw me? OK, short time one thousand baht." (Warning - it's more expensive nowadays.)
  2. The higher class hookers sold their time: "You go to Pattaya? I go with you; I take care of you. Two thousand baht a day."
  3. The highest class hookers operated on a simple philosophy: Find somebody who's got money, and keep him happy. The money will take care of itself.

I decided to adopt that as my career strategy. It has worked for me for over 20 years now. You got money? I'll do whatever keeps you happy - write software, live in Banphai, install hardware, train data entry staff, whatever.

Action World Wide

I was at Chulalongkorn University for eight months. I became a regular at "BUG", the Bangkok User's Group. There I met John DeHaven, and John eventually hired me to work at Action World Wide.

I started at Action World Wide in the spring of 1991. The exact date was pretty fuzzy - I was spending an occasional day over there as early as December, but my contract with Chulalongkorn ran into March.

The Chung Family, headed by Mr. Wing Chung, owns a collection of companies, some of which are based in Thailand. The companies are cooperative and mutually friendly but financially independent. For twenty years I have tried to keep the Chung family happy.

Action World Wide was organized to develop a package of business software. The actual product, called NOMODAC (an acronym from "NO MOre DAmned ACcountants") was supposed to automate the accounting of a small business. But, eventually, it was a disaster. "Mean Bob", the guy doing the design, couldn't stop fiddling with it. He was doing it in HyperCard on an Apple Macintosh, and I learned a lot from helping him with that, but we never got around to cutting code.

HyperCard was way ahead of it's time. It was underappreciated, but was the germ of a great idea. It came out in the mid-1980's and ran on the Apple Macintosh. I'd seen it back at Sorcim. Your data was structured as a set of "cards", each card being displayable on the screen one card at a time. There were links between cards; something like this:

	Underline these words: "More Spagetti";
	If the user clicks on those words,
	take him to card #75.
Years later I realized that if you could have replaced "card #75" with "" you would have had the World Wide Web, five years before the World Wide Web was invented at CERN. At the time, I was too dumb to see it.

"Tall Bob" had set up a PC with two 100-megabyte hard disks (the largest around at that time) and installed SCO UNIX on it. It was an unusual experience because I was able to boot MS-DOS from diskette whenever I needed to. I had lots of problems with SCO UNIX. For example, we were trying to connect to another computer across town to get into the UUCP network for e-mail. But under UNIX I couldn't even test if the modem was wired to the port! I had to bring up MS-DOS and run a dumb terminal program to find out if the modem was plugged in or not! UNIX was great when it worked, but compared to MS-DOS it had nothing in the way of diagnostic tools. Of course we were in Bangkok, in the middle of nowhere; that might have contributed. Another problem was that SCO UNIX flatly refused to accept that there were time zones east of GMT. I even went so far as to recompile the kernel, and the source code had conditionals to refuse to accept minus seven as a time zone. Years later an expert told me "SCO UNIX was an excellent example of how to do everything exactly wrong."

The only reason we wanted to use UNIX was that we had this one computer and wanted to plug eight terminals into it. John had this idea of hiring eight programmers to work, concurrently, on the NOMODAC code. When NOMODAC became hopeless, I erased UNIX and installed MS-DOS on the machine.

For some reason or other we purchased a Sun workstation (UNIX again, but this time no problems) and a package called "Prokappa". This was a special language to develop software in. Prokappa was a fancy language, had all kinds of OOP and AI features.

The Chungs have another company named Adams International Ltd. This company taught Thai farmers how to grow oriental tobacco, bought it from them, blended it, and sold it for export. In this situation it is important to estimate the size of your crop each year. Well, the estimates were always personal, quirky, and optimistic. In a typical year the estimate started out high, and went down and down as the buying progressed. One memorable year the estimate was still going down during June and July even though the buying was finished in May. So these guys were not overestimating what they were going to buy, they were overestimating what they had already bought! Wing Chung hit the ceiling, and called on Action World Wide. We developed a program to estimate the crop size based on area planted and district-by-district yields in previous years. Prokappa was a massive overkill for this task; in later years I ported it to FoxPro.

Eventually it was obvious to everyone that Nomodac was going nowhere. The company killed the project. Well, you might even say that the owners killed the company, since Action World Wide ceased to exist when the project died. I was out on the street.

Fractal Software

(Tilleke & Gibbins)

Mean Bob was also doing work for Tilleke & Gibbins, the oldest law firm in Thailand. They wanted to create a management information system independent of the accounting department, and he got them to hire me for the job.

This, too, was a disaster. Partly it was for the same reason. The specifications never stabilized. This time I was cranking out code as fast as I could, but never could catch up to the design.

This is where I invented the term "fractal software". In case you don't know what a fractal is, let me give you an example. Imagine drawing a triangle. It might look like this:

Fractal 1

If the original triangle had three sides of length 9 centimeters each, then the original triangle had a total perimeter of 3 X 9 = 27 centimeters. Now, in the middle of each of those sides, put a point sticking out. If you put the point in the center, just right, then the new shape has four short sides exactly where the original triangle had one side. It will look like this:

Fractal 2

Each piece of a side is of length 9/3=3, and there are twelve sides for a total length of 12 * 9/3 = 36 centimeters. A longer perimeter than before. Now take each of those twelve sides and put a point on it sticking out. It looks like this:

Fractal 3

Each piece of a side is now of length 9/3/3 = 1, and there are 48 sides, for a total length of 48 centimeters. The perimeter has gotten longer yet.

Do it again. Do it again. Keep doing it. The area of the thing, although it gets bigger, never gets very big. It still fits on the paper. You can draw a circle around it and it will never get out of that circle. The area is bounded. But the perimeter gets longer and longer. As the shape gets more and more little bumps on it, the area remains less than one square meter, but the perimeter grows to kilometers, thousands of kilometers, even "light-years". The thing could sit on your desk; the boundary line, stretched out, would go to the nearest star.

Sometimes a software project develops like that. The task doesn't actually expand. The job still is bounded by one division of a company. But the design attempts to take in all possible special cases. Each special case is more code. The sides are code, the bumps are code, the bumps on the bumps are code. Each special case becomes a rule, and each rule has it's own special cases. Fractal software. Since the benefit is in how much it does (the area), and the cost is in lines of code (the perimeter), the benefit is limited but the cost goes to infinity. The only possible result is to kill the project with ill feeling. The question is how much money you will pour into the thing before you realize that it has gone fractal.

That is what happened at Tilleke & Gibbins. Eventually top management killed the project.

There was another reason why it died. It was supposed to be a management information system independent of the accounting department. Naturally the accounting department somewhat resented the intrusion on their territory, and duplication of their activity. But since it was largely a financial information system, in effect it was another accounting system. The top management didn't trust their own accounting reports, and so they set us up as enemies of the accounting department. Naturally we were resented and mislead and the ill feelings contributed to the collapse of the project.

A company is supposed to keep one set of books. There are stories about companies that keep two sets of books. One might even speculate on a company that kept one set of books for the tax department, another set of books for the primary stockholder, and a third set of books for the minority stockholders. That can happen. But I have seen a company that kept, in effect, and infinite set of books. Every number on every report was computed differently depending on who was expected to read that report. A person would be an employee for pension benefits and an outside consultant for tax purposes. A check from a customer would count as income on one piece of paper and assets on another. Every piece of paper that passed through the accounting department was a special case.

Don't ever try to automate a manual accounting system where the accountants have had ninety years to make their games infinitely complex. Buy a package, and make the accountants do things the way the package says. For a little money, you can buy a simple package. For a lot of money, you can buy a very complex package. But whatever package you buy will be finite, and have only a limited number of special cases. Never try to automate a manual accounting system where the accountants are world class expert lawyers. (Make that "world class expert liars".)

Tilleke and Gibbins had only one server which was running Novell Netware. The existing IT department, the ones who resented me, decided to replace the server over the Sonkran holiday. That year the Sonkran holiday was Tuesday, Wednesday, and Thursday. Monday the system was working normally. Tuesday they replaced the one small hard disk with two new larger hard disks, and installed the next version of Netware. All day Wednesday they tried to get the new setup to work. By Thursday morning they gave up and tried to revert to the old system. All day Thursday they tried to revert. All day Friday they tried to get the old system working again, but could not. On Friday the office was officially open for business, but the clerks had to do everything by hand.

The IT department must have had some success over the weekend, because they had the old system up and running on Monday.

Where was I? Sitting in the same room as the server, reading a book, available if they wanted me to help. Tuesday, Wednesday, Thursday, and Friday I just sat there. The local IT staffers were too proud to ask for help.

In retrospect they had two technical problems. The reason they could not get the new system working was that the second hard disk had a harware error; it was eventually had to be sent back to Singpore. The reason that they could not revert to the old system was that the new larger hard disks had changed the hard disk BIOS settings, so the server would no longer accept the smaller old hard disks. But upon reflection, their strategic error was that they tried to upgrade everything at the same time. They should have replaced the one hard disk; that would have worked. Then, when that was working, they should have upgraded the operating system; that would have worked. Then, when that was working, they should have added the second hard disk. That would have failed, but they could have run indefinitely with the new system and the bigger hard disk while the damaged hard disk was sent back for replacement. Instead, they tried to upgrade everything at once, and the one error caused everything to collapse.

But that is history. I was fired. By e-mail. As the project died. And, frankly, glad to be out of there.

Adams International Ltd.

The Chung family had the suspicion that the Action World Wide NOMODAC disaster wasn't my fault. So when Adams International wanted to set up a system to barcode the bales they buy from the farmers, they called on me to implement it. Karl Kunz designed it, and I programmed it and got it working.

Delivery was in stages, and payment was in stages, all spelled out in the agreement. It worked, and they liked it. Just before the last payment, Wing Chung asked me to stay on permanently. I accepted.

Adams International Ltd. teaches farmers in northeastern Thailand to grow oriental tobacco. Adams buys the bales of tobacco from the farmers and blends them in it's factory in Banphai. The blended tobacco is then sold on the international market. The whole process brings much needed money into one of the poorest areas of Thailand.

I worked at Adams International from 1996 until 2009. The computer support group originally consisted of two people: myself in charge of software, and Ping who took care of hardware. In the summer of 2002 we hired a third person, Wichit. This included the grunt work like keeping a list of every computer Adams International owns. Wichit took over the software support task, leaving me free to focus on development work.

When I came onboard at Adams, they were using MS-DOS programs such as CUWRITER and Lotus 1-2-3. I gave them Windows 3 and Microsoft Office Version 4.2. In 1998 I gave them Windows 98 and Office 97.

John DeHaven wrote a C program for Adams that Adams uses to buy tobacco from the farmers. The program involves recording bale grade and weight, adding up all the bales for a buying slip, deducting farmer debts, printing slips and barcode stickers and summary reports. I converted John's code to "better" code. I ported it to Linux. When we hired a new programmer (Ae), he took my code over and made it a lot more beautiful.

Adams sells agricultural supplies - for example, insecticides and fertilizers - to the farmers, on credit. I automated the system for keeping track of the farmers debts. It is called Farmer Accounting. It was originally written in FoxPro but I converted it to the C++ OOP system.

The company had a payroll program written in FoxPro by another programmer, and every year or two I had to update the social security rates. I wrote a new FoxPro payroll program to cover the employees in the factory.

The barcoding system I set up, under Karl's guidance, required me to write a program to control handheld barcode scanners. It involved a FoxPro program reading the scanner data into a set of DBASE-compatible tables. However, the batteries for the handheld scanners all died, and we couldn't buy any more at a reasonable price, so the handheld scanners were retired.

There were yearly modifications required to the FoxPro programs. As time went on this became more and more of a problem. FoxPro is a good language to get small programs working quickly, but it is not a good language to do large systems. Essentially all variables are global, names are restricted in length, there are too many interactions. Whenever I added a line of code anywhere, I had to think about what impact it might have on any other code anywhere else in the program. Even adding a "local" variable might break something else.

In many ways C++ is a terrible language. The syntax was inherited from C, and was never designed for object oriented programming. The language tries too to be efficient, letting mistakes destroy the program and forcing many complex language rules that exist only because simpler rules were less efficient twenty years ago. The language is very terse, making it quick to write but hard to read. I am very familiar with C++; I've coded in C or C++ for twenty years now. It is compiled; you can look at a source file and understand what it does without looking at every other source file in the system. And C++ is well known in Thailand (the most popular language seems to be Java but C/C++ is second, I think).

The National Electronics and Computer Technology Center (NECTEC) of Thailand gives a Fundamental IT Engineer Examination twice a year. The test comes from Japan; you can take it in Thai or English. I read about it in the newspaper and wondered if I still had what it takes. So I took the exam on October 21, 2000. The e-mail they sent me afterwards said "You have passed the ITEE exam. You have highest score: TOP for the examination." So now I've got a certificate from NECTEC for "Certified Information Technology Professional". I didn't pick up the e-mail in time to attend the ceremony; I was in the hospital with a broken let. Darn!

The Chung Family owns the majority of the stock of Adams International. Wing Chung ran it. I trust Wing. He never gives anyone bull about "That's company policy!" or "We have to make a profit for the stockholders!". Of course the company has policies, and of course the company must make a profit. But Wing never lets that be an excuse for evil. If Adams has screwed you out of a thousand baht, it means that Wing Chung has screwed you out of a thousand baht, and when you tell him, he'll reach into his own pocket and hand you a thousand baht. He does not duck responsibility. He does not allow the law to determine his moral standards. He won't cheat you, even if it's legal, even if he can get away with it. He's a good man. I trust him. I named my son after him; little "Wing Canfield".

I worked for Wing Chung for about ten years. On July 9, 2003, Wing Chung retired. I will not abandon Adams International. They use my code, they depend on me, they need me, and I care about the people of Adams International. But I want to be available to others.

Arakka Limited

Wing Chung helped provide the money to create Arakka. Alex Polgar at Bangkok Base provided the legal and business skills to incorporate Arakka. "Arakka" was a good name; in Thai it means "protection" and they say it is the word Thais use for "bodyguard". But, taken as three words, AH-RAK-KA, it means Uncle (Andy) loves legs. Ha ha. I hoped that Arakka would be good for me. Arakka had a web site at But Arakka was a debacle.

Why a debacle? Well, people have told me that I'm a good programmer. Karl gave me a sign that said "Super Programmer". But nobody ever said I was an entrepreneur. And my one experience as a manager was a flop. I love to code. But I could not run my company, and I never learned how, and I never got excited about running the company.

The Thai government, when dealing with corporations, naturally assumes that you are trying to cheat them. So the regulations regarding corporations are tedious, and often silly.

The penultimate frustration was the 3 percent rule. If I were to hire somebody to paint my room for 1000 baht, I would, of course, pay him 1000 baht. But if Arakka were to hire somebody to paint a room for 1000 baht, it was legally required to pay him only 970 baht, and fill out a form, and use the form to pay the Thai revenue department 30 baht, and give the guy a copy of the form so that he could file that form with his tax return and collect 30 baht from the Thai government. Never mind that Thai individuals are almost never required to file tax returnes; he still must sweet-talk the government tax people to get the other 30 baht from them. What a crock!

Well, it took me no time at all to figure out that I could pay the guy the whole 1000 baht that I promised him, and fill out the form, and throw away the copy for him, and file a copy with the Thai revenue department. That would cost me 1030 baht, but everyone would feel satisfied.

But the ultimate frustration, the one that broke the company, came at the end of our first fiscal year. I learned that Thailand has a law that, after the end of each fiscal year, the company has to hire a special accountant, one certified by the Thai government, to go over the books and certify that the books have been kept according to Thai legal standards for company books. My reaction was: "Books? We're supposed to have books?" Oops.

So the company went to sleep (became inactive). For a couple of years I filed the required monthly papers ("zero, zero, zero") with the revenue department and paid some accountant several thousand baht to look over the company "books" ("zero, zero, zero") to keep it legal. I looked into just closing down the company. In Thailand, if a company goes bell-up and has no money, you can terminate the company's existance. For 20,000 baht. If you're broke, you can pay 20,000 baht and die. Ha ha; go figure.

So today, there is no activity of Arakka. The domain name "" is gone and available. Curiously, the domain name "" is also available. The required Thai government paperwork has not been filed for several years. When and if I get the bright idea of being a business, I remember what a lousy job I did the last time I tried that. Then I hit myself over the head to forget it.

Adams Enterprises Ltd.

Adams Enterprises (AEL) knew about what I had done for Adams International (AIL), and wanted me to do something for them. The staff wanted a barcode system. They wanted to barcode their agricultural material so that they could just scan the barcodes when they shipped a bottle from one place to another. Simple, right?

What they did not realize was that a scanned barcode will update something on the computer. It updates a database. Before they could have barcodes, they needed a database. And they did not have a database. Everything was done by hand in Excel.

So I proceeded to set up a database for them. The usual stuff - data entry screens, reports, administration tasks, inquiries, that sort of thing. We call it "FASEMAT", for Farmers, Seeds, and Material. What was different about it was that I chose to do it as an intranet web site. The server runs Linux, the web pages are served up by Apache, the data is stored using MySQL, and the code that runs is PHP. It is what they call "LAMP", for Linux/Apache/MySQL/PHP, and I build it before I ever heard the acronym "LAMP".

I really think that web code is the way to go. The MS-DOS days had the trouble that the program had to be in control, with prompts, so the user could not go where he wanted to go and do what he wanted to do. The Windows system of menus interrupting the program sounds good, but it causes problems because the user can be in the middle of something and try to do something else at the same time. The web page client / server system works much better. By sending the user to specific pages, you can lead him through the process. But he can go off and do something else any time he wants to. Still he can do only one thing at a time. He can go off on a tangent, and never come back. He can go off on a tangent and come back later. He can open a new window (or tab) and go off on a tangent in that new window without messing up his context in the original window. Works like a charm.

Also, the web page approach requires a minimal footprint on any target computer. AIL purchased a major software package, (and they needed it), but the client only runs on Windows XP. Because FASEMAT is a browser-based system, the 'client', the browser, runs on all versions of Windows, it runs on all known versions of Linux, it runs on the Apple Mac. With a little adjustment we could get it to work on your mobile phone. You name any operating system today, and there's a browser there. Keep the pages simple, and the browser will be able to do the job. For this kind of in-house work horse, you don't need the latest most beautiful screens.

So browser-based software is the way to go today. Whether that be LAMP, or WIMP, or some other acronym, doesn't really matter. You write good code, and the site will work on any client.

Browser-based software is the way to go, today. Ten years from now, who knows? But today, it's the big thing, the new better way to do things. Browser-based client/server software is as revolutionary today as functional programming and object oriented programming were in their day. It changes how we make computers operate.

After a few years at Adams Enterprises, I had a squabble wih the CFO (Chief Financial Officer, or perhaps she is the "CFU") and left. I went to Laos. I like Laos. It is a nice, quiet, small country. They have a good culture and friendly people. But, unfortunatly, there is no money there. THere is the Lao government, which will only hire Lao citizens, and there are lots of NGOs, who bring their own staff from their home country. A foreigner in Laos doesn't get hired by anybody. So after two years of trying I gave up and went back to Thailand.

During the time I was in Laos I kept in touch with the Chung family. I helped maintain FASEMAT remotely.

During my lonely years I developed a package called OPAL. You can try it out yourself; go to and log in as user "demo" (password "omed"). OPAL is a management tool for an organic produce company. AEL had started up a division they call "Adams Organic Produce", and they needed management tools for it.


My contract with Adams Enterprises finishes on 31 August 2013. As of 1 September 2013 I'm out of a work.

I write software, and I stand by my software. If my program has a bug in it, I'll fix it, for free, regardless of contracts.

I have worked for the Chung family, in one way or another, for about twenty years. But those years are coming to an end. I have to feed my family. So I am looking for work. If I can help you, please contact me. Thank you.

Andy Canfield