TallyCat: a unit calculator parser for JS
What is TallyCat?
TallyCat was an online unit based calculator, originally at the tally.cat web address, registered simply because I really needed to own a .cat domain. It let you do arithmetic with units. You could add not just 4 + 5, but 4 feet plus 5 inches, then convert it to millimeters. I wrote it because my child kept asking (and still does) how much some value is in some other unit. Sometimes he’d ask crazier questions like if we filled his bedroom up with water how many gallons could it hold. Turns out
8ft * 12ft * 10ft as gallons equals
Calculating with units seems useful, and I originally planned to integrate it with a larger project called Brainshell that was like a word processor for computational thinking about the real world. As such it would not only need to do math with units, but have access to interesting data sets that used those units. I imagined you could write expressions to turn temperature sensor data into beautiful bar charts with something as simple as:
GetData(‘TempSensor1’) => SumBy('day') => Chart()
I hoped Brainshell could eventually be an entire general purpose data processing language that would use operator pipelining, cloud based datasets, built in charting and graphing, and anything else I thought would be cool. Another forever project.
Ultimately the Brainshell project failed for the simple reason that I don’t actually do that much data work. My day job usually doesn’t involve working with large datasets, and when it does (web analytics), I have existing special purpose tools that work better than my general tools. So TallyCat was the useful part that came out of that work.
You can now use TallyCat in your own applications by just importing the
tallycat-parser library and calling
Parser.parseString("4ft*6ft*8ft as gallons").
The core of the parser is a grammar written in OhmJS. This parses a string into a tree structure of numbers with units which is then reduced. The unit system is smart enough to understand not just that meters can be converted to feet and feet to inches, but that units of higher dimensions can become different types. For example length to the power of three becomes a volume. It also means you can’t accidentally multiply two things that are incompatible.
TallyCat also has some constants built in like Pi and earth.radius, so you can answer questions like “How long would it take Superman to fly around the world if he’s faster than a speeding bullet”, or more useful things like how much rum is needed to make a two liter bottle of holiday punch.
Today TallyCat works pretty well and has a lot of unit tests (more tests than code, probably) but it could still use some more work. If you are interested, here’s a short list
- generate API docs from the source.
- add more examples
- make work in both the browser and node (fs module vs URLs to load the grammar)
- Let the user add new constants
- expose where a parse failed in a useful way, such as if the expression is invalid vs just incomplete
Posted December 14th, 2020