I’m Old, Part LXXXVIII: Debugging Techniques

Today, I fixed an issue in my code base. This, in and of itself, is not unusual. I do that most every day. What was different was that I analyzed the process and took mental notes on what I did and how to explain it out.

The issue was that my code base has a number of sample projects and while they build, several of them crash hard. This is suboptimal because chances are most clients of my code are going to ignore the copious documentation and go right for the samples. It’s best if they work.

How do you solve this problem:

Step 1: analyze the output and the errors and see what you can find

I did this and it was puzzling. I was getting a runtime error on a symbol reference while attempting to load a dynamic library and it was a symbol that I never used. I put together a mock program that allegedly did the same steps as my host program to load that library with the same arguments. It succeeded. I plunged into despair.

Step 2: Walk Away – No, Just Walk Away

Seriously – this is a good thing. I rarely fully let go of a problem and instead shift it to the back burner of my brain and very often, the solution will just occur to me later.

Step 3: Find a Place With Better Light

Here’s a joke: a person is out under a street light at night looking for something. An observer walks up and says, “hey, did you lose something?” The person says, “Yeah! I lost my car keys in that alley over there.” pointing at an unlit alley across the street. “Why are you looking over here?” “Well, the light’s better over here.”

After my time away from the machine, here was the conclusion I came to: I have close 1600 unit tests that pass. Most of them do more complicated things than this sample, but the process is identical. If I can hoist this sample into a failing unit test, then I can debug it a lot easier. In other words, move the problem into a place with more light. I did this. I pulled the entire sample into a unit test. It turned up an issue in my code, but this was not what I was seeing. I fixed that issue and had a passing unit test.

Step 4: Enter Elmo’s World

Sesame Street is a wonderful program for teaching the young. There are so many simple games they play to help build basic skills. One of them is called “One of These Things Is Not Like the Others”. This is a game where they put up multiple scenes and all are identical except one and you need to pick out the one that isn’t the same as the rest. This was exactly the game that I played with my code. I had a unit test that passed and a sample that failed. All I had to do was turn the sample code into the unit test. So I tracked compiler flags and environment variables from the unit test and shoved them blindly into the makefile for my sample. Success! The sample ran without a hitch – and in the process, I saw exactly what was missing. Was I done? Not quite.

Step 5: Cut Away Everything that Isn’t an Elephant

There’s an old saw about how you carve a statue of an elephant – you start with a big block of stone and remove all the stone that doesn’t look like an elephant. Easy!

This is what I did – I methodically went to the makefile and stepwise removed pieces that I added that didn’t affect the outcome. Why? Because this is sample code. If it were me, I would build the sample, run it, read the source code, then read the makefile. The makefile should be as simple as possible (but no simpler).

It also reminds me of a guy I know who as a teen had a transistor radio and he took it apart and saw a circuit board covered with resistors, capacitors, coils, and transistors. While the radio played, he clipped out individual components until the radio stopped playing, then soldered back the component that killed it. Eventually, he removed everything that wasn’t strictly necessary.

Same thing here. It’s also good to make sure that I understood everything that was going on in that issue so that it (hopefully) wouldn’t happen again.

Step 6: Document What You Did

I still need to do this. It would be nice if the makefile included not only the steps to build and run a given sample but information as to why it has each of the parts. I’ll do that tomorrow.

Can you find and fix any issue with these steps? No. But this is one approach you can take. I spoke to my spouse about this and she said, “wait, you made an algorithm for debugging an algorithm?” Essentially, yes.

I’m Old, Part LXXXVII: Just How Old Am I?

This is a 1980 news article from my home town’s fish wrapper, The Independent Press (now shuttered). I was just shy of 13 when it was written. Here’s the transcript (typos are mine, probably):

Only The Computer Knows For Sure

by Miriam Congdon

If home computers are the wave of the future, George Hawley and his sons are already living in the year 2000. The family computer, an Apple II, plus a motley assortment of accessory parts, sits in the upstairs hall of their New Providence home, absolutely commanding the attention of all who pass. Usually Pat, 15, or Steve, 13, keep Apple company.

Hawley is an engineer at Bell Labs which gives him a predisposition to things mechanical. He bought the computer last October, he says, “because it seemed like a neat idea”. Besides, Pat wanted to learn about computers. Now, nine months later, Hawley proudly asserts that Pat knows as much about microcomputers (small [illegible]es) as the people at Bell Labs – more, maybe.

Both boys write programs for the computer, which may explain why of the 1,000 or so programs in the Hawley household, most are games or designs. One – no name, yet – has a space ship flying through a galaxy; the object is to fire and hit the tiny moving stars.

There are, of course, games that they have bought. “Lemonade” is one: it tells the players what the weather is and how much the ingredients cost per glass; the players decide, quickly, what price to charge and how much to spend on advertising. The winner is the one who makes the most profit.

There’s chess, with six different levels of play, and a bowling game with three alleys. If the boys choose, they can call up a pattern that’s a dead ringer for Hopalong Cassidy, or one that merrily grows in geometric designs (terrific in color, they say, when it’s hooked up to the TV).

But the computer is not all play. George Hawley uses it for a number of household purposes, such as keeping track of expenses, by category. Last April he spent an hour and a half programming in a form 1040 tax return plus schedules, which he can use forever or until the IRS changes the whole thing.

A formula using loan principle and varying rates of interest tells Hawley how much he can afford to spend on a car; presumably, it leaves the color selection up to him. And every once in a while, he and Apple sit down and whiz through a work related project.

Hawley has over $2,000 tied up in the computer: $1300 for the basic unit (the simplest system costs $900), and lots more widgets (Hawley’s word). These include a disc drive machine to play the floppy discs that store the programs and the discs themselves. Programs for home use cost between $5 and $30. And of course Hawley and sons experiment with modifications to Apple – and the Hawley spends a lot of time fixing them.

What Apple II does, as it sits quietly in the hall, is only the tip of the iceberg. There are more sophisticated machines that can control utilities and appliances. Some can “talk” to their peers via a telephone hookup; in fact Hawley has a widget to do that, once get gets it fixed.

Dennis Tolley, co-owner of Stonehenge, a Summit company that sells small computers, suggests further uses: keeping household inventories for insurance purposes, keeping Christmas card lists, balancing checkbooks, filling recipes. Education is big in computer land: it’s more fun for a kid to lean multiplication tables or states and capitals from a computer. Getting a little more exotic — and expensive — it’s possible to buy into a news service or get the stock market report, right there at home. Think what that would do for your disposition.

As George Hawley says, “It regenerates itself. There are constantly new things to do with computers.”

Apparently, a lot of us will be learning that in the not-too-distant future. Hawley’s educated guess, bolstered by projections in the computer-oriented magazines he reads, is that in five years, one out of every 10 or 20 homes will have one; in 20 years, one out of every three.

But that’s just a guess. Only Apple II knows for sure, and (s)he isn’t telling.


  • The Apple in the picture is running Apple Invader by M. Hata.
  • The monitor is a piece of junk that my dad picked up at a computer fair one weekend. He thought it was torn out of an airline terminal.
  • The reference to the broken modem is that my dad also bought an acoustic coupler to hook up to a serial card. If it worked, it would have run at 110 baud. It never worked. We eventually bought a Hayes modem that ran at 300 baud.
  • We tried a number of mods to the machine. We tried an upper/lower case mod, but apparently the revision of the Apple made that impractical.
  • The chess game was Sargon II – a couple months ago, I tried to play this emulated version against an online chess engine, but it ended up hanging 4 moves in.
  • On the chair to the left of the computer is a TI Silent 700 terminal. Dad borrowed it from work and we managed to hook it up to the Apple to use as a printer. It uses rolls of thermal paper. We also used it to log into Bell Labs computers to play Adventure or Zork. We went through a lot of paper. My dad bought a case of it, which my mom (probably passive aggressively since the terminal took up the phone line) put on top of a radiator, ruining it. I wrote a paper on it my freshman year for English because I didn’t want to use a typewriter (my typing was awful), knew that my mom wasn’t keen on typing our papers anymore, and it was an excuse to use a computer. I printed it on the Silent 700 and my dad made copies so it wasn’t rolled up. The paper was returned to me with this comment “It looked better than I expected. C+.” No other comments except correcting grammar. We eventually replaced it with an Epson MX-80 which looked crappy, but a whole lot better.
  • Above my dad’s hand is the floppy drive – our second – the first went up in smoke in the first hour of use. Behind it is a wooden box my dad knocked together out of scrap wood to hold 5 1/4″ floppies.
  • I butterflies on the wall were ones that I had collected. I recognize a white admiral for sure and likely a red-spotted purple, but I’m less sure. The others I can guess from memory, but am not sure on.
  • The breakfront contained books of my mom’s. They were novels and art history books for the most part.
  • I was in the middle of a growth spurt and those jeans were getting into the flood water range.
  • The food to the left of the breakfront was my room. We called it “the blue room” even though at that point it was no longer blue. It was a sitting room with a (non-functioning) fireplace in one corner.
  • Clearly this was written at time when the world hadn’t yet agreed on disc or disk. Once that was settled we have moved on to the pronunciation of ‘gif’, which is still unsolved.
  • I feel like the writing is kind of smarmy. I get it – it’s a small town paper and Miriam got sent out on this beat to write up a “local man spent money on novelty” story, but still.
  • The article is factual to my memory – no mention of my oldest brother who was in college at this point.
  • Yes, my dad did his taxes on the Apple and it probably took him longer than if he did it by hand, but it’s the principal of the matter. He also wrote a program to do linear regression and one that let you enter points and would plot out a polygon and calculate its area. I remember him using this to verify his brother’s recently purchased lot of land was in fact the area that the realtor claimed it was (spoiler: it was)
  • My mom hated that machine. It had a very short-lived life in that location and moved around the house frequently. For a time it lived in the basement, about which my mom was no doubt thrilled, since she never went into the basement because she saw a mouse there once. My dad build a computer desk for it and it moved into a 3 season porch that my folks converted into a year-round living space. The problem was that it had electric baseboard heating that was off most of the time to save money. You had to plan way ahead to use it. In addition, the disk drive didn’t like the cold and needed some run time to get up to speed. I would go in, turn on the heat, turn on the computer, toggle a memory location ($COE9, IIRC) to turn on the motor. I left for 20 minutes and came back to a warmed up room and a warmed up disk drive.
  • My brother Pat and my Dad invented PowerPoint. Pat wrote a program in 1981 called ViewGraph Maker that let you put text and graphics onto the screen and print it out get run through a machine that turned black-and white pages into overhead transparencies. For my dad, this was a game changer. He did a lot of presentations at Bell Labs and if you wanted to present slides, you either had them made for you (cost, time), or you tried your best with pen and paper.
  • Stonehenge Computer was my home away from home. Dennis tolerated me. Mike Mahoney, his partner, on the other hand absolutely encouraged the local kids.
  • Hopalong Cassidy came with the Apple System disks.

I’m Old, Part LXXXVI: Cereal Bug Fixes

A pile of Cap'n Crunch with Crunchberries cereal

When I was a kid, I really enjoyed Cap’n Crunch cereal. I don’t know what it was about it that I enjoyed (these days I avoid food with added sugar) but it was worth the palate shredding at the time. Once in a while we’d get the variety with Crunchberries. This was a rare enough event that I would carefully eat around the Crunchberries leaving them behind so that at the end I had a bowl of Crunchberries in milk that was slowly turning pink. I did the same thing with Lucky Charms or any other cereal that had special kernels in it so I could enjoy them all at once with no effort.

To that end, I just submitted this PR to my project Binding Tools for Swift. It fixes a typo in an issue opened more than a month ago after one of my peers spotted it in a previous PR. It’s a no brainer fix – rename the method and Visual Studio takes care of the rest.

Why did I wait more than a month to do fix this? Two reasons: 1. I was hoping that the “good first issue” would entice someone else to have a go at fixing it to get their feet wet on the code base and 2. for the past month, I’ve been working on mostly challenging issues. Sometimes it’s nice to get work done, but still take a break.

This is the same as setting aside the Crunchberries. It’s a way of setting aside a reward. Sometimes the reward is a small one like this. Other times, it’s a refactoring that you know will make so many things better. Current Steve likes to set up nice things for Future Steve so that when Future Steve becomes Current Steve, he’ll be more likely to be forgiving of Past Steve’s mistakes.

Do you find ways of doing that? If so what?

I’m Old, Part LXXXV: Bug Decay

In the past 15 years, I’ve become a huge fan of unit tests. Whenever I start a new project, one of my first questions is “how can I unit test this?” And admittedly, many of my unit tests tend to be heavyweight and less unit and more macro.

For example, in working on Binding Tools for Swift, in order to test my code, I need tests that can write swift code, compile that swift code, run my tooling on it which generates an API, write C# code that exercises that API and prints out some useful indication that it ran. The actual test reads the output and compares it to an expected output. It’s not pretty, but it works. Or at least I have 1545 indications that it works so far.

From time to time, it’s been necessary to do a wide-reaching refactoring of the code base. It is at these times that I’m very happy that I have unit tests that exercise a wide range of my code. Recently, it became apparent that my old code for reflecting on compiled swift code, which is a custom build of the swift compiler, was not going to work as is. Fortunately, swift has added the ability to produce a text-only version of the front-facing API of the code: the swiftinterface file. This file contains a subset of the swift grammar, so I wrote a parser for it using ANTLR which generates (ostensibly) the same XML representation of reflection information as the compiler-based version. After a couple months of implementation and some basic testing (I have ~100 tests on the XML reflection code), I unleashed it on my whole test suite. I got about 800 failures.

After a day and a few PRs, I had that down to about 422 failures. After the next day, it was down to 212 failures. After the next day and more PRs, it was around 100. See the pattern? Every day I was reducing the failures by 1/2, which is akin to exponential decay. This is common enough that whenever I work on a refactoring like this, I start of up a spreadsheet with the number of failures over days. This does two things: confirmation bias of my hypothesis and more importantly it lets me see the progress over time.

Try it some time and see how you do.

Now let’s think about the why. What I think happens is that in reasonably factored code you get bottlenecks: places where there is a lot of code traffic. Code issues that affect bottlenecks are going to cause a lot of failures. Getting rid of an issue in a bottleneck will remove a large number of failures as well as opening up access to new failure bottlenecks (usually more removal of old than opening up of new). Eventually, when the bottlenecks have been cleaned out, you’re left with issues in the fringes.

That’s my story and I’m sticking with it.

Perils of Open Source Compilers

For my job, I work on Binding Tools for Swift. This is a suite of tools that does static analysis of compiled Swift modules and generates adapters in Swift and bindings in C#. In short, I make a Swift library look like its written in C#.

When I started on the project, I needed the ability to reflect on the front-facing interface of a Swift module. I couldn’t do this in Swift. The first reason is that there was no useful reflection in Swift, the second is that running reflection only gives you a view of the API from the point of view of the platform on which the reflection is being done.

Instead, I took advantage of the fact that Apple had kindly released their compiler as Open Source. I hooked into the command line arguments and wrote code that used their abstract syntax tree visitor to generate an XML document that represents the API.

There’s a problem with this, though. The compiler with reflection has to match what Apple ships. Why? Because if it doesn’t than we can’t consume the modules and if we use the custom compiler to compile Swift glue code, it won’t link with the original module. Fortunately, it was easy enough to do, since there was a branch with the release compiler.

I’m bringing my tools up to Swift 5.3 and discovered that this had changed. In looking at the shipping compiler, I got this information for the version:

Apple Swift version 5.3 (swiftlang-1200.0.29.2 clang-1200.0.30.1)
Target: x86_64-apple-darwin19.6.0

When I look at the custom compiler built from the release/5.3 branch, I get this for the version:

Swift version 5.3-dev (LLVM 6811d14c28, Swift 9cfbe5490b)
Target: x86_64-apple-darwin19.6.0

They’re no longer the same and as a result, there is a problem: I can’t consume libraries compiled by the system compiler and it can’t consume libraries compiled by my version of the compiler.

I have a workaround, I think, but let’s talk about why this change happened and it is a reflection of a really interesting conflict of interest in Open Source, especially with compilers. To be clear, I don’t know the actual reason why, but I have a pretty good guess.

I’ll direct you to the Turing Award Lecture, given by Ken Thompson. In the lecture he describes how you can create a Trojan Horse that can change the system compiler such that it injects a security flaw into the operating system on its next build.

From this knowledge, it is actually pretty dangerous to be able to make a compiler that has the same signature as the system compiler. Since I have the source to the compiler, I could make one that can inject security holes into compiled code and not be detected. The next step is to make a Trojan Horse that delivers the modified compiler into the system. If the spreads to the systems of developers or to build servers, then there’s a big problem.

On the other side of the coin, if I release code into Open Source, shouldn’t it be possible to build a bit-identical version of the released product? And if I can’t, is this truly Open Source? Otherwise the compiler I built is really just an artist’s interpretation.

Apple clearly chose to do this on the side of trust, and I get that. At the same time, I’ve been at best inconvenienced and at worst, I’m dead in the water. In a practical sense, it doesn’t matter since (1) I’m not really a customer of Apple so it’s not their job to make me happy (2) their actual priorities are creating a solid compiler that efficiently generates correct code.

The fix on my end is to take advantage of the ABI stability promise and turn on the flags “-enable-library-evolution” and “-emit-module-interface”. These at least allow the compilers to be able to talk to each other. It’s not exactly ideal from the point of view of people who are going to use Binding Tools for Swift, but it’s not nothing.

Remembering Mike Hawley

My brother Mike passed away early yesterday morning. It’s heartwarming to read all the kind words from people posted on social media. One common thing is that Mike often challenged you go the extra step in whatever you were doing. It could feel aggravating if you took in the context of, “hey – I just made this cool thing and it’s not good enough?” but what he was trying to do was say, “wow! That’s is really cool! I’m so excited by it that I can see the possibility that it holds.”

Mike has always had a great affect on me from the very beginning. One of my earliest memories was in kindergarten. We’d had an “assignment” to learn how to tie your shoes and I had forgotten to practice. I was in tears before school when I remembered and Mike patiently took the time to teach me.

Mike was an explorer for sure. As a kid, he routinely took bike trips to the limit of a kid’s range – some around 15 miles to Jockey Hollow. He was active in scouting and created the Kowabundee Chicken Patrol and went on camping adventures including down the Alagash river. In high school, he was part of a group of intellectual hell-raisers who published an underground newspaper, routinely absconded with “useful” chemicals and wrote a tome called “The Honors Physics Consortium Poetry and Songbook”. They printed several copies and went as far as making phony card catalog cards an embedded a copy in our local library where it was shelved until a fire destroyed the collection. In and after college, he and some friends planned trips to canoe down the Mistassini River in Quebec and then in a later year down the Yukon river in Alaska.

As has been mentioned, he was an accomplished pianist. He shared that trait with my mom. My mom thought everyone should have piano lessons and barring that, everyone within her reach. I lacked that particular talent. Interestingly enough, right around age 14 Mike was getting bored with piano. It was too easy, apparently. My mom caught on and introduced him to the music of Liszt. That woke Mike up and he brought Lizst’s piano works to his teacher, Heidi Grob, who had to tell him that she couldn’t teach him Liszt since she couldn’t play it. Keep in mind that not many people can play Liszt, but Mike was determined. Mom found him another teacher, John Quinn, who helped Mike reach further.

The downside to having a talented brother practicing piano at all hours is that it was hard to fall asleep while he practiced. Fair’s fair though – I play trumpet and I’m sure I drove him nuts with my practicing too. I didn’t realize how much of a heartbeat it was in our house until he went off to college and it was missing.

The three of us all worked in high school at Murray Hill Bell Labs (home of the transistor!). All of us were into coding and writing software. Mike made friends with people in the UNIX group and he learned C and did a bunch of work on data searching and retrieval. I recall him writing a tool called “hmm” that was the way of entering information. I remember most that I/O coverup – as it churned information, it would print “hmm” and a series of dots followed by “ok” when it finished. He worked on a scrolling calendar program for the Blit terminal – a smart terminal with a 68K processor and a legal sized screen. which led to him spending a year working at IRCAM in Paris on music composition software on an imported Blit. There was some discussion as what the proper pronoun should be for the Blit. I think they settled on feminine. Mike also played one part of a two piano piece for Pierre Boulez before returning. He described it as “your basic banging on the keyboard with cheeseburgers” and that he and the other pianist had a signal to jump to the end and play the last chord.

Mike continued his exploration and innovation for years. He built schools in Cambodia and named one after our mom. One of the things that was interesting about having an overlap in careers is that I kept running into people that knew Mike. Every place I worked, I bumped into someone who knew Mike in some capacity. And that was one of Mike’s aspects: it was almost as if he collected people. I recall a conversation with him that started off “I was having lunch last week with the Librarian of Congress…” for example. It wasn’t without it’s benefits, however.

When Adam Savage was doing his stage show “Brain Candy” with Michael Stevens, I knew that Mike and Adam were friends and I pinged Mike about the show in Worcester. Mike also knew the producer of the show, got a ticket and joined my son and I at the show and afterwards we met Adam (who is a lovely person).

The past couple of years, I’ve been trying to host Thanksgiving dinner because our families have drifted apart a bit. It’s not surprising: we all live very busy lives. This past year, we managed to all get together and it was a joy.

We had nearly all the Hawley men of my dad’s line in one place.

Mike was so happy to be there with Nika and his son Tycho and my dad was thrilled to see all of us together. I spent most of the day cooking (which I love), but I did find some time to snap some selfies.

No, there’s no family resemblance at all.

Where I’ll end this is that Mike hosted a dinner for close friends earlier that November for his anniversary with Nika. Again, I snapped a selfie.

Before the dinner, Mike introduced me to all these people that he knew in medicine, publishing, politics, industry, music, and software. Invariably, he would introduce me as his “smarter brother”, which I really appreciated. And if you’ve made it this far and if you’ve known Mike, you probably know that in addition to collecting people and introducing them to others, he could make you feel like the most important person in the room when he talked to you.

We lost a good one, yesterday.

The Mathematics of Contagion

This is something I wrote up for people I know on facebook to understand the mathematics of contagion and why you should care.

Let’s talk about covid-19 in the US from a strictly math point of view. I’m going to keep the math as simple as I can. This isn’t going to get any more complicated than high school math. This is going to be long, but it’s important to understand.

Stick with me.

Many things in life are proportional relationships. For example, if I’m putting together a set of hand outs for a conference and each hand out is 5 pages, I can find out how many sheets of paper I need by multiplying the number of pages (5) by the number of attendees. If someone decides to show up, add 5 pages. 2 people cancel, subtract 10 pages. This is also called a linear relationship because if you draw a graph with “number of people” on the x axis and “number of pages” on the y axis and fill in the points, they make a lovely straight line.

Disease propagation does not work that way. It’d be great if it did, but it doesn’t. Instead it follows a pattern called exponential. Here’s an illustration of one exponential relationship.

Let’s say I have a checkerboard which is 32 squares. I ask you to put 1 penny on the first square, 2 on the second, 4 on the third, 8 on the fourth and keep doubling for each square. By square 26, you’d need more than $1,000,000 in pennies. On the last square, you’d need a stack of $21,474,836.48 in pennies.

Let’s compare that to a proportional relationship. On the first square you put 5 pennies, 10 on the second, 15 on the third, etc. Doing this, on the last square you would have $1.60.

That’s some difference, right?

How do we represent that in a way we can calculate? Let’s figure it out.
Here are your days and their relationship to pennies:
1 : 1
2 : 2 * 1 = 2
3 : 2 * 2 * 1 = 4
4 : 2 * 2 * 2 * 1 = 8
8 : 2 * 2 * 2 * 2 * 1 = 16
Since we know that 2 * 2 is 2 squared or 22 and that 2 * 2 * 2 is 2 cubed or 23, we can simplify the table:
1 : 1
2 : 21 * 1 = 2
3 = 22 * 1 = 4
4 = 23 * 1 = 8
8 = 24 * 1 = 16
In general, the number of pennies on a given square is 2n * 1, where n is the number of the square on the checkerboard.

You can see that the number of pennies needed grows really fast. The good news is that COVID-19 doesn’t grow this fast. The bad news is that it is still an exponential relationship. The problem is almost the same as the pennies, but instead pennies it’s confirmed cases of COVID-19 and instead of squares, it’s days. The number we don’t have is called the base. In the penny problem, the base was 2 and I gave it to you. Can we figure out the base for COVID-19? Yes. Take the number of cases on any given day and divide it by the number of cases on the previous day. Why does this work? Remember with the pennies, I said multiply the previous number by 2. So if I have the equation:

x * prevday = nextday

I can solve for x:

x = nextday / prevday

I did just that for COVID-19. CNN (and several other sources) have been posting the number of positive tests each day. I put that into a spread sheet and did the calculation you see here for each day since March 1st. The result is not always consistent, so I calculated the trend and it comes out to about 1.3. That means to predict the number of cases tomorrow, multiply today’s cases by 1.3. That means that the number of cases doubles about every 2.5 days. We are on a pace to have 181,000 cases by the end of the month.

There are estimated to be 160,000 ventilators in the US.

See the problem? And even though not all of those 181,000 cases will need ventilators, just wait 10 days and you’ll have 2.8 million cases.

Now let’s talk about the death rate. The estimates vary a lot. The lowest is around 1.4% and the highest is 4%. The reason why this is such a wide range is that it depends on treatment and it depends on patient age. This means that by the end of the month, you can expect to see between 2240 and 6400 deaths in the US.

There’s good news and bad news. The good news is that COVID-19 will not spread without limit. The limit is the number of people available to be infected. If we had unlimited people, we would infect 330,000,000 people in by May 1st. But we don’t have unlimited people, so the curve can’t grow without limit. Also not every case requires hospitalization.

Further good news – this model is incomplete. The world is a sticky place with many more complications in it. For example, not every person who is infected will need to go to the hospital or even need ventilation. Not only that, once someone is infected, there is a good chance they will recover and the number of cases goes down.

The bad news is that we have a very real limit on the number of doctors, the number of hospital beds, the number of masks, the number of test kits and so on. If we don’t reduce the base, you will see growth to the point where our medical system can’t handle the number of cases it gets. This will get worse as people who work in hospitals get sick. At some point (and it’s going to happen soon), doctors are going to have to make decisions like “which patients will last without ventilation?” or “which patient will recover faster?” or “which patients do we have to let die because we don’t have the staffing or equipment to properly care for them?”

You should ask yourself, do you want you or someone close to you to be one of the patients on the short end of one of those decisions?

Let’s finish this with a call to action. What can you do? Wash your goddamn hands. Seriously. Soap and water wreaks havoc on COVID-19 and is dirt cheap. Keep away from groups and group activities and limit contact (reduce shopping). Feel sick? See if you can use telemedecine. Call your government and demand more testing.

For the curious – here’s my math, which I will try to keep updated.

Introducing Binding Tools for Swift

If you follow my blog, you’ve probably noticed two things: it’s been quiet here as of late and I haven’t spoken directly about what I’ve been working on since I joined Xamarin. Let’s change both of those things.

Today a vast majority of the APIs and libraries powering Apple’s ecosystem (iOS,macOS, tvOS, watchOS) come in the form of Objective-C libraries. Xamarin’s binding project support can expose these APIs in C# for use the same as any other managed library. The same infrastructure powers the platform assemblies, like Xamarin.iOS.dll.

A few years ago Apple introduced a new programming language called Swift, which has been under active development with a number of breaking changes over the years due to the evolution of the language. Swift by default has a very different runtime design than other languages. This makes calling Swift code exceptionally difficult from C# in most cases.

Solving this problem required writing a tool significantly more complex than our existing binding infrastructure. One advantage of Swift libraries, however, is that they contain enough information to automatically create a reasonable API mapping to C#. This means we can improve upon the experience of binding Objective-C by skipping the need for a user to define the interface in C# by hand.

After years of development and 1200 unit tests and tests on 3rd party libraries, we’re happy to announce that we’re open sourcing our work:

Current Status

Binding Tools for Swift currently works on most of the common cases for in Swift 5.0 code, but there are limitations that we are actively working on:

  • Project and MSBuild support to make it easier to use
  • Support for Protocols with Associated Types
  • Support for Swift 5.1
  • Support for non-escaping closures
  • Support for closures in bound generic types
  • Improving documentation and samples

There is also work that needs to be done to fully integrate BTfS into Visual Studio for Mac and bring it into a public preview.

Get Involved!

It’s been a lot of work and a lot of typing. I’m very happy with where the code is today and am looking forward to getting my first community pull request. Get involved! I’ve written a lot of documentation on how the tool works and you can read the quickstart guide here.

I’m proud of the work that I’ve done and I’m very happy to bring Swift interoperability into the .NET ecosystem. Come help me out!

I’m Old, Part LXXXIV: The Spice Girls

I was talking to my spouse last night the topic of the Spice Girls came up and she was trying to remember each of their personae. I knew from the gate that this was not going to happen for me.

When I worked for Newfire, one of my co-workers, Andy Hess I think, went to a conference in Great Britain at a time when the Spice Girls were a thing. I think at that time I was listening to either grunge or NPR so I didn’t hear any Spice Girls music, but I knew of them. When Andy came back from his trip, he brought at least one packet of crisps from his trip.

For sure he brought the one on the left. To this day I prefer to believe that one of the Spice Girls was Smoky Bacon Spice.

Learning Assembly: Arithmetic

If you’re in coding at any level, you have some familiarity with arithmetic. Most of the arithmetic you’re likely to do in assembly is will be familiar and that should be no surprise at all. Some operations may be unfamiliar and some familiar operations may have nuance that feel funny at first, but trust me that the nuance is there for a reason.

Fundamentally, there are three models of arithmetic in assembly language and the differences all have to do with a pair of simple questions:

  1. Where do the parameter(s) come from?
  2. Where does the result go?

There are three variations and each is a logical extension of the other.

Accumulator Model

In the accumulator model, there is a dedicated register (or even two) which is used as the result for (nearly) all arithmetic and often as one of the parameters. A simple example is basic addition. You might see some code like this:

LDA Position
ADD #$5
STA Position

In this example, we’re reading the value of Position into register A (LoaD A). If this is unfamiliar to you, see the previous post on moving memory. Then we add 5 to it and store it back into Position. So, in essence, this is equivalent to:

Position += 5;

You’ll notice that we had to store the result explicitly. This is because the result ends up in register A. The accumulator model is very simple, but your code feels particularly wordy. That’s perfectly fine. It’s just the lay of the land.

Second Is Result

In this model, the second parameter is also the result. If I rewrite the previous example in this way it will look like this:

ADD #$5, Position

Second Is Result differs from the accumulator model in that no register gets directly modified, which is a nice convenience. It’s similar in that the CPU is going to do nearly an identical amount of work in both cases. Second Is Result is very common in current CPUs.

Third Is Result

In this model, the first and second elements are the parameters and the third is the result:

ADD #$5, Position, Position

Again, this is equivalent to both models and on the face it doesn’t look particularly useful, since in this example the result is the same as one of the parameters. But what if instead we started from C code like this:

newPosition = oldPosition + 5;

In this case, the assembly would look like this:

ADD #$5, oldPosition, newPosition

From this point of view, it looks like a very handy format, but there are problems – the number of places that you might use aren’t quite so common and the instruction decoding that the CPU needs to do starts to get more complicated. You can see that you could write this using Second Is Result with the following:

MOV oldPosition, newPosition
ADD #$5, newPosition

Or with Accumulator Model like this:

LDA oldPosition
ADD #$5
STA newPosition

Note that the complexity of accumulator model has not changed at all. The important takeaway is that there are usually very direct mechanisms of implementing basic arithmetic as expressed in programming languages and this shouldn’t be a surprise since assembly languages have influenced high level languages, which in turn informed assembly languages.

Besides addition, what’s available? It depends on the CPU, but you can expect to see instructions that do the following on lower end CPUs

  • addition
  • subtration
  • logical and
  • logical or
  • logical exclusive or
  • bit shifting left or right
  • bit rotation
  • complement
  • negation

On higher end CPUs, you would expect to see all of the previous as well as the following:

  • multiplication
  • division
  • floating point versions of arithmetic
  • sign extension
  • conversion to/from floating point

Where Things Get Funny (not funny ha-ha)

When you’re working with a budget CPU, you might not always have multiplication or division. Sucks to be you. You can implement them – the algorithms are straight forward, but multiplication is slow and division is slower. The CPU designers knew that it was likely that the CPUs would have to interact with people and people tend to be much happier with base 10 rather than base 16, so they included a means of doing base 10 called Binary Coded Decimal, or BCD. In BCD, 4 bits out of every byte are used to represent a decimal digit, but you are limited to 0-9 in each nibble. Unfortunately, BCD tends to be pretty clunky. On the 6502, you first had to put the CPU in a special mode with the instruct SED for “SEt Decimal”. This sets a bit in processor and when ever you did addition or subtraction, if the result of operation would leave a value greater than 9, it would adjust the the result. Once done, you had to undo the SED instruction with the CLD instruction (CLear Decimal), otherwise you affect your later code. The 6800 processor had a special bit that was set when the result of BCD arithmetic was incorrect and if so, you would use a special instruction after to fix it. Also gross. Both of these methods, however, were far cheaper to implement than multiplication and division.

Most CPUs have the ability to tell when things may have gone wrong or need attention. For example, after most operations there is a flag that sets set if the result was 0 or if the result was negative or if the result might have caused an overflow or underflow. I’ll talk about that more in a different post.

Most higher end CPUs perform math on several different sizes of input. For example, an x64 processor can perform math operations on 8 bit, 16 bit, 32 bit and 64 bit inputs.

Finally, one thing you see in assembly that you rarely see in high level languages is the ability to cheaply do arbitrary precision arithmetic. The way this is managed is that the CPU has a flag in it that represents binary carry. If you add two values and the result is bigger than what fits in the machine word, then the carry flag gets set. If you subtract two values and the result is less than what fits in the machine word, then the carry gets set.

Most CPUs have a separate instruction for addition with carry and without carry (or subtraction with borrow and without borrow). Why? Because you don’t always want to add with carry, sometimes you just want to add numbers and ignore the carry. The 6502 was not one of those CPUs. It didn’t have separate add and add with carry instructions. Instead, it only had add with carry. This was irritating because if you ever wanted to do plain addition, you have to make sure that you cleared the carry flag first. If you forgot to do this, then your result might be off by one depending on what happened beforehand. The 6502 was the first CPU I coded for and I didn’t understand this at first, which led to some very perplexing bugs.

Why would you leave out multiplication and division? For the most part, it comes down to cost and limitations in the registers. In a typical 8-bit processor, you’re not likely to see either because your registers are typically 8 bit. When you add two 8 bit numbers, the result is at most 9 bits (8 bits plus the carry). When you multiply two 8 bit numbers, the result is at most 16 bits. Where does the result go? In the accumulator model, if you only have 1 accumulator (like the 6502), where do you put the other 8 bits? Furthermore, the 6502 implemented its math through dedicated silicon called an Arithmetic Logic Unit or ALU. All of the math in the 6502 is 8 bit plus carry. Having two arithmetic operations that need 16 bits is suddenly expensive. We’ll cover the ALU

Specialty Math

Some processors put in specialty math operations. For example, it’s extremely common to want to add/subtract 1 from a register or from memory. You’ll sometimes see special instructions for doing this named INCrement and DECrement. Other processors make special “fast” versions of add and subtract that will only add or subtract a small constant value.

We see that performing arithmetic in assembly language is conceptually straight forward, but in practice you need to be aware of the quirks in any given CPU to ensure that you get the result that you intended.