Abbreviations are Hard, My Journey to Cadence
By the end of October 1994, we had a rudimentary demonstration of a outpatient scheduling application written for Windows. It was no more than 1% of Cadence functionality and little to none of the code we’d written survived to become part of the final application. How did we get there? Great question!
My green tea has steeped at 160F/71C for 270 seconds, it’s time to write.
At the beginning of October, I transferred to Cadence full time as a software developer. Cadence is Epic’s outpatient appointment scheduling system. If you’ve made an appointment with a healthcare organization using Epic, there’s a reasonably decent chance that Cadence was used for your appointment.
To debunk a tiny piece of recurring fake news: Epic does do comprehensive data integrations and has for 30+ years including integrating with scheduling systems that aren’t written by Epic.
I joined an existing Cadence developer that had been at Epic about a year longer than I. A few things had to happen before we began doing any real coding though. First, we excitedly installed our fresh copies of Microsoft Visual Basic 3.0. (Ok, I was excited, I don’t know that he was as much as I). For all the terrible jokes and complaints that have been made over the years about Visual Basic, especially earlier editions, the jokes were often based on opinion rather than fact. Building small utilities and applications with VB 3.0 to 6.0 was always remarkably easy. You could do circles around the common competition at the time: C and native Windows APIs. The true challenge was that it had few rules and had few if any programming guidelines. So, everything goes (and lots of things went wild).
Training?
After tinkering around with Visual Basic for a day or so, we were able to align our schedules with something that happened very infrequently — a few customers were going to be at Epic to learn how to enhance EpicCare and to code in Visual Basic. We were asked to attend so that we could gain some insight into how to program into Visual Basic and how EpicCare was constructed. The training took place in the old Rosewood conference room over a few days. There were two customers and two of us, and a few different EpicCare staff did the training.
Upon training completion, we provided some honest feedback and a few days later, the other developer and I both found ourselves in Carl’s office. Ugh.
He scolded us for our critical and honest feedback. I’m not going to sugar coat the feedback we gave: the training was poor. Not only did the developers not communicate well to the customers, they failed routinely to explain things in a coherent way that any of us could understand. I know these Epic developers didn’t do training frequently (or even have much customer interaction), but it was a substandard event. The only thing that was clear to us was that the two EpicCare developers had limited knowledge about how Visual Basic worked or why they’d made the architecture decisions they’d made. It was a slapped together system that had definitely prioritized product over medium to long-term architecture choices. It wasn’t a sustainable design.
We were instructed by Carl to take the EpicCare code and use it. That choice hurt. He’d also established a “demo” deadline with our TL.
This feedback sucked. The irony of the feedback, like our feedback had been, was that it wasn’t meaningfully actionable. My best summary is: “be more Midwest Nice.” Certainly, providing constructive and critical feedback is preferred whenever possible. But, the training was so broken that there was no way to just “fix a few things.” It’s also difficult to provide effective criticism when you can’t leverage other more positive similar training experiences. (The training I’d taken for other Epic systems and APIs had been very good up to this point, but that wasn’t a particularly valuable comparison).
We got to work in spite of this morale setback. After we had some time to review their code more away from the EpicCare developers, we found further evidence that the code was based on more than a handful of misconceptions of how Visual Basic 3 code could be structured and used. In hindsight, it is obvious to me that the team had nearly zero awareness of how Windows actually worked and how Visual Basic worked on top of Windows.
By no means would I have claimed to be an expert in Windows software development at the time.
Back in the Windows for Workgroups 3.11 days, there wasn’t as much documentation available for “Windows Internals.” Even so, there were some decent books available for Windows programmers in C. Specifically, Programming Windows by Charles Petzold are classics and have been read by hundreds of thousands of Windows programmers and date back to 1988. The great things about those books wasn’t that they were entirely reader-friendly, but they did explain the Windows operating system and its operations, from hWND
s to message queues and beyond. Visual Basic had to operate with the same restrictions as any other Windows application, so knowledge of general Windows programming would have applied to Visual Basic programming quite nicely. But the team hadn’t done that. In fact, some of the early choices they made later caused many technical and resource issues.
Deadlines
I fully appreciate the deadlines that were established for us and originally the EpicCare team. A beautifully designed and architected product may never ship or may be so delayed that competition has an opportunity to gain traction minimizing sales. It’s a dance. A balance. But, the effort to ship ship ship caused no shortage of issues later. These issues then rippled to other Epic applications that found their footing by copying the original EpicCare code (and some of the new Cadence GUI code).
During the month of October while we began hacking together a basic scheduling workflow, I learned more about Cadence from other team members; well, I think all four of them. On the surface, Cadence seems straightforward and like it would be ripe for disruption by some innovative software startup. But, the beauty of Cadence isn’t particularly in what is seen by and end-user as much as what it does behind the scenes. In fact, the general surface simplicity of Cadence is what makes it generally have a decent user experience and makes it straightforward to learn. (The general issue with workflows that are appointment related isn’t specifically about the booking of the appointment, it’s the data collection for the appointment that bog the workflow down, from collection of a copay to updating insurance, answering routine screening questions, etc.). There’s a lot of what we usually called “business logic” to run Cadence behind the scenes. There are potentially hundreds of conflicts, scheduling templates/rules, availability issues, patient preferences, etc. that all must be applied rapidly so that an appointment slot can be located and confirmed with the patient.
”Oh, my computer is being slow today” was never something we expected an appointment scheduler to need to mumble to a patient. The underlying algorithms and user interface needed to be FAST. When booking hundreds of appointments during a shift, waiting for the computer is a tragic experience. The Cadence terminal-based UI (I’ll likely refer to it as Cadence Text) was snappy and predictable.
Predictable
One frustrating aspect about many terminal and GUI applications is that they don’t respond well to type-ahead. If the application happens to have a key pressed buffer and the user is typing while the application is blocked (during computation), does the application drop keystrokes? Many applications are inconsistent. So many that I know it’s uncommon to type-ahead. Mobile apps don’t even provide a way to do that on a virtual keyboard.
It was a thrill to watch a proficient Cadence user book an appointment. It was often so fast you’d wonder if they’d even done the right thing. They learned the shortcuts, they knew what prompts would be displayed and how to react to them. The only real waiting was to verbally read appointment options to the patient. We had a mission for Cadence GUI: Make type-ahead a real thing that works. Type-ahead is far easier to do on a terminal than it is in a modern application — this fact would haunt my nights over the decades as Epic moved platforms and upgraded operating systems.
As we started with the EpicCare code, we began to delete all of the EpicCare-specific modules, both in the Visual Basic code and on the MUMPS server. It didn’t take too many days before we had a working connection to the MUMPS server and Chronicles. I plan on talking more about that in a complete post, so I won’t get into it now. It’s an interesting topic, especially to learn about the progress of how communication from non-terminal-captive applications worked over the years. There were some good and bad stops along the way.
Unfortunately, I don’t fully remember which workflows we attempted to demonstrate for the end-of-October reveal. However, I suspect that it was two things primarily: the main patient overview screen (like showing the patient’s demographics and future appointments), and a basic “make appointment” form. That functionality would have demoed well.
Oops
I’m confident that one of the earliest forms I authored was the appointment entry form. Why? Because of what I didn’t know at the time. Apparently, the accepted abbreviation for appointment is appt
. I did not know that. When creating a user interface in Visual Basic 3, the developer would create what is called a “Form” file, ending with the file extension frm
.
This wasn’t a huge deal by any means, but in my defense I may have chosen the file name before I settled on the VB name
:
Let the record show, as you can see from the screen shot:
8.3 Character File name limitations
As Windows 3.11 (and earlier) were still running on Microsoft DOS, Windows inherited the limitations of the DOS file system. The limits were that a file name could be up to 8 characters long, and the file extension no more than 3.
Demonstration and more Deadlines
I know that we successfully demonstrated a few very basic workflows by the end of October and that success was immediately turned into a new Thanksgiving deadline. My more mature self sees these as pointless development marches with deadlines that reflected zero knowledge of how much time building the next set of features would take. The worst type of project management.
And yet, off we went for the next deadline.
I’ll talk more specifically in a later blog post about some of the Visual Basic issues in the those years that we encountered when doing development and eventually what we tried to do about it.