Calculators, Binary Hybrids, and UNIX History
I wanted to add a calculator to my leatherman but I never ever want to write a parser. The following is what ensued.
I’ve ended up in situations where I have my
leatherman handy but
bc(1) is not
installed. I very briefly considered implementing my own calculator, but every
time I immediately consider the actual parsing of expressions and discard the
idea. I hate writing parsers!
Recently I considered that maybe there’s some weird linker trick I could do
such that the binary would have a statically liked
bc(1) appended. I asked
some coworkers and basically the answer was that I could compile my
leatherman as a shared library that gets linked into a hacked up
would know how to call out to the
leatherman entrypoint. This is a bridge
too far for just using a calculator.
Side note: I expect at some point to make some rust based tools and having them
leatherman in this fashion would be pretty cool, so I expect that
to happen in the next year or two.
I checked to see if busybox has a
implementation and verified that it indeed does not. But it does have
dc(1), the reverse polish notation calculator that preceeded
$ echo "11 3 / p" | busybox dc 3.66667
(That’s push 11 and 3 onto the stack, divide the first two numbers on the stack, and pop/print the number on the stack.)
My coworker Jeremy Leader pointed out that
bc(1) actually used to be a
dc(1). I happened to notice that when reading the manpage for
DIFFERENCES This version of bc was implemented from the POSIX P1003.2/D11 draft and contains several differences and extensions relative to the draft and traditional implementations. It is not implemented in the traditional way using dc(1). This version is a single process which parses and runs a byte code translation of the program.
My hunch was that “the traditional way” was some yacc based parser. I did some
digging and verified that, as far as I can tell, the original
indeed yacc, was authored by Ken Thompson and the late Dennis Ritchie around
midnight on Wednesday the 14th of May, in 1975. (Note that the commit metadata
shows a different timestamp, but it’s in Pacific Time and Bell Labs is on the
I found this a fun little excursion. At the minimum, I know
dc(1) is at the
ready even in the rare situation that
bc(1) is not (it happens!) On top of that
it’s cool to be able to dig so deep into the history of your industry that you can
find this kind of thing.
I think a natural book to recommend along with this is UNIX: A History and a Memoir. I haven’t read it yet but all the reactions I’ve seen about it are positive.
Another good, sorta related book is Coders at Work. I read it many years ago but really enjoyed it.Posted Mon, Feb 10, 2020
If you're interested in being notified when new posts are published, you can subscribe here; you'll get an email once a week at the most.