Abacist – Calculations with non-decimal units and mixed bases in Scala

34 pointsposted a month ago
by cbeach

6 Comments

btbuildem

a month ago

OP you may have meant to have linked directly to https://soundness.dev/abacist

Not a scala person, but I like the idea of being able to shift between unit/measurement systems. Lots of strange little edge cases. Eg, how does rounding work in imperial, can I get 3.1415926535 meters to the closest 1/64th of an inch?

cbeach

a month ago

ah that's strange - I thought I had linked correctly. And now it's too late to edit :-(

TOGoS

a month ago

This seems similar to the 'ComplexAmount' system I used to use in PHP and JavaScript programs for representing measurements using mixed units. Basically just a map of unit code => quantity. And for extra exactness, quantity would be represented as a rational number.

Was useful for a client that let you place orders using a mixture of USD and CAD (the alternative being a lot of 'canada'/'canadian'/'cad' fields added willy-nilly everywhere a cost needed to be represented; I don't know how people can stand to program that way). But also for generating G-code for a CNC router [1], when sometimes you want to model in mm, and sometimes in inches, and keep all the numbers exact until the last possible moment.

[1] https://github.com/TOGoS/TTSGCG

nadavwr

a month ago

PHP and JavaScript are dynamic. Here you'll be able to pass distances as feet or meters, but if you try to pass in pounds you'll get a compile time error -- can't do that in dynamic languages :)

TOGoS

a month ago

So, when I said JavaScript, I really meant TypeScript, and I found its gradual/structural typing system to be the most ergonomic type system I've ever used (if you want nominal types, it's pretty trivial to get there just by adding a compile-time-only tag, like `{ typeName?: "FooType" }`).

In this case, the TypeScript approach might be something like

  const distanceInMm : {"mm": Rational} = toMm(distanceInArbitraryUnits);
You can get as specific as you want, without having to wrap/unwrap anything, or even define a new named type. [1]

I think I like Scala conceptually--when people talk about it I think "yeah, good idea!"--but every time I've looked at Scala code it struck me as having an excessive amount of boilerplate to wrap/unwrap stuff just to make the type checker happy.

The other bad-tasting thing about Scala is that I wrote a program[2] in it many years ago and then later came back to try to fix some bugs and the language had changed so much that I had to find some old version of it + an old JVM and Dockerize it. Docker's a godsend for this sort of thing, but kind of inconvenient for development.

[1] My notes about this approach in TypeScript: https://www.nuke24.net/plog/32.html

[2] https://github.com/TOGoS/PicGrid