Engineer that I am, I make a checklist, so I can check a box to record whether or not I've taken the pill. Yet I've found (the hard way) that the problem persists. Returning after an interruption, did I take the pill and not yet check off the box? Or did I check the box and not yet take the pill?
Thinking about how I might avoid this problem, I remembered that computers have a similar issue, and programmers have a way around it. It's called "Disable Interrupts", usually abbreviated in computer assembly languages by the mnemonic "DI".
To set the stage (I won't get too technical), computers process "interrupts", which usually announce some external event (such as the user striking a key on the keyboard). The computer saves the state of its CPU ("Central Processing Unit"), and executes a program to process the interrupt (e.g. see what key was struck). It then "dismisses" the interrupt, and returns to whatever it was doing.
There can be conflicts between things done by the main program and things done by the interrupt subroutine. It's a bit different from the pill problem - the computer won't lose track of where it was before the interrupt, as people do. But there can be points in the main program where allowing some half-done task to be interrupted can produce undesired effects. This is not a small matter. Just this problem caused a serious defect in the timeclock product that was being beta tested when I arrived at Kronos in April, 1979. It made the timeclock lock up, which caused a component to overheat and burn out, spewing smoke.
Problems due to a badly designed interrupt system are generally difficult to diagnose, because they are intermittent and infrequent. They only occur when the interrupt happens to come in during a critical time window in the main program, and those windows are short. Since Kronos was running a newly written program on newly designed hardware, it was not even clear whether the problem was in the software or the hardware. My solving this difficult problem was a major factor in my promotion to Vice President - Engineering, and the start of a nearly twenty-five year career at Kronos. This episode is described in my blog entry #0005, Coming to Kronos.
One solution is to be sure that certain critical operations in the main program are indivisible. Once started, these short stretches of program must not be interrupted until they have been completed. A simple way of doing this is to briefly disable all interrupts until the critical code has been executed. This is done by executing a "DI" ("Disable Interrupts") instruction at the start of the critical code, and then executing an "EI" ("Enable Interrupts") instruction at the end. The critical code must be kept short, though - you can't have interrupts disabled for a long time. If interrupt code is handling incoming characters on a communications line, for instance, if you disable interrupts for too long, you might miss a character.
What does this lesson mean for taking pills? My computer example gives one way to solve the problem: make the taking of the pill and checking it off an indivisible, non-interruptible operation. You can allow preparations to take the pill to be interrupted - get a glass of water, get the pill container, have the checklist on hand, etc. But the actual swallowing of the pill and the checking off that it has been done cannot be interrupted. I can envision holding the pill in my left hand, and holding a pencil over the checklist in my right hand. I could then swallow the pill and check off the list virtually simultaneously. If the phone rings, I've got to ignore it for long enough to accomplish either both operations, or neither. Ditto if my garage explodes. What I cannot allow is any interruption between taking the pill and checking it off (or, in the other order, between checking it off and taking the pill).
In the end, I have so much trouble not getting distracted (I guess I have a bit of A.D.H.D. Note 1), I actually do it a different way. I developed a different "algorithm" (procedure) for taking a pill and recording that I have done so. Instead of using two operations to take and record the pill, I use three:
1. Put a pill on the table
Doing it that way, if I get interrupted, I can always know where I was when I return from the interrupt. Look at the four possible states I could find myself in upon returning from an interrupt, on Sunday morning in the example below:
Actually, after putting so much thought into the above, I find there's an even easier way to keep track of which pills I have taken. It's the simple seven-day container shown below, which I've always used for my daily pills. These containers are available in any drugstore. For my daily pills, I refill the container every Sunday. For short-term prescriptions, I might need two or three seven-day containers, depending on what day of the week the prescription is started. But I always have extra containers on hand - I keep them to pre-fill when I travel. As you use the pills, you can always see at a glance what you have taken and what you have not.
The above ought to give you some insight into how a computer programmer thinks about even simple problems. Well, this computer programmer, anyway. The programmers reading this are probably contemplating my algorithm, and perhaps even debugging it. The non-programmers are probably thinking, "This guy is nuts."
There's another problem to which my programmer's brain has found a technological fix: remembering to take my daily medications at all. I really don't seem to be a creature of habit - I found that despite taking my pills regularly every single morning just after breakfast (some of them are best taken on a full stomach), I was still capable of accidentally skipping them entirely. Perhaps it's again my tendency towards A.D.H.D. - it doesn't take much to distract me from any routine that I might have. But I used to be able to eat my breakfast and then walk out the door without having remembered to take my pills.
No more. I solved that problem with the apparatus shown to the left. It's a small lamp, with a bulb that is turned on by a timer. Note that the rotating dial on the timer has only a single plastic peg in it, a red one that turns the lamp on. The black peg that turns the lamp off has been removed (it's actually taped to the top of the timer, in case I ever need it in the future). The timer turns the lamp on before I wake up, and I don't turn it off (manually) until I've taken my morning pills (and then, the next morning, it will be on again). The lamp becomes what programmers call a "flag" - a "TAKE YOUR PILLS" flag. The timer "sets" the flag once a day, and I "reset" it to indicate that the pills have been taken. Note 2 The lamp is near the door to the garage, so I can't leave the house without seeing it. Since setting this up, I've virtually never forgotten to take my pills.
Think of all we could get done if we could really "disable interrupts" from time to time.
Note 1: A.D.H.D. = "Attention Deficit & Hyperactivity Disorder". My mind is always jumping from this to that, and I'm easily distracted. This used to be called just "A.D.D.", but the "Hyperactivity" component is now generally included. It's a diagnosis usually applied to children. I wouldn't say I'm physically hyperactive, but perhaps my brain is. [return to text]
Note 2: The computer programmers of the Artificial Intelligence group at MIT had their own jargon. It spilled over into their everyday life. They ate a great deal of Chinese food, with which tea is always served, usually in stainless-steel pots with a hinged lid. When the pot was empty, someone would pop up the lid, which the programmers called "setting the tea flag" (to be more precise, "setting the teapot-is-empty flag"). The waiter would (asynchronously) see the top raised, and take it as a signal to replenish the tea.
Actually, the phrase used by members of MIT's Artificial Intelligence group was "AOS the tea flag". AOS (pronounced to rhyme with "house") was an assembly-language instruction for the PDP-10 computer that accomplished the operation "Add One and Skip (never)". It was the fastest instruction for adding one to a memory location, and it was frequently used to set program flags (not really good programming practice, as its working properly is dependent on the previous state of the flag).
I don't think I can write the above without people asking why a computer instruction would be called "Add One and Skip" when in fact it did NOT skip ("skip" means "skip the next instruction in sequence"). It's because the instruction was part of a family of instructions that might in fact skip, for instance "AOSGE", "Add One and Skip if the result is Greater than or Equal to zero". With no additional letters at the end of the mnemonic, though, the instruction never skipped. And yes, there was an "AOSA", "Add One and Skip Always". The PDP-10 had a very rich instruction set.
Click here to see a Jargon File describing some of our computer hacker language. If that link is not maintained in the future, just do a search on "MIT Stanford jargon" (without the quotes), and you'll find numerous copies. [return to text]