3 ms·
For a while in the codebase I was working on, we had a set of distinct types for different units. You know, a type for meters, another for centimetres, etc etc.
by plasticeagle 4y ago
For a while in the codebase I was working on, we had a set of distinct types for different units. You know, a type for meters, another for centimetres, etc etc. We had types for radians, types for degrees.
We had conversion functions between them, and type inference when you performed certain operations.
The result was a disaster. Not an enormous disaster, but enough of a problem to rip the entire thing out and replace it with plain double-prevision floating points, and sensible variable names, everywhere.
Why was this? It was a combination of there being nothing sensible to infer when you, say, multiply an angle and a distance (which happens when you're doing algebra), and everything in the whole codebase needing to be aware of these types.
The downside of all these brilliant ideas is dependency. If you define an "EmailAddress" type, as the article suggests, you've got to write the code for it somewhere. Now all your projects are dependent on this library, with all the pain and anguish that versioning and linking/including/whatever the library brings.
Before, you depended on nothing but the String type, which is very likely built into your language. When all your code needed to do was pull that email address out of some persistent store (say), and send to some other piece of code, your dependency list was just the Persistence library. But with your fancy EmailAddress type, your dependencies are now much worse.
Keep things as simple as they can be. An EmailAddress type is not useful.
- _dain_ 4y ago>The result was a disaster. wtf? metres and centimetres are not different types! they are just different ways of writing same type: Length. radians and degrees are just ways of writing a dimensionless Angle quantity. you made the absolutely elementary mistake of conflating a physical quantity with the unit used to measure it, of course it was a disaster. >nothing sensible to infer when you, say, multiply an angle and a distance angles are dimensionless so they should just be a distinct type of float. there is literally no problem here.
- sixstringtheory 4y agoI can see how it could cause problems if they weren’t using the type system correctly. typedef float cm; typedef float meter: cm a = 1; meter b = 1; if (a == b) { // launch rockets } I’ve done something similar (not including rockets, don’t worry!) in Swift with its typealias feature. Thankfully there is a way to actually force compiler errors in such situations with something like https://github.com/pointfreeco/swift-tagged https://github.com/pointfreeco/swift-tagged
- LEDThereBeLight 4y agoYou might not have seen this pattern before, but annotating values with units as types is a legitimate approach. There’s a whole chapter about it in the book Software Design for Flexibility by Gerald Sussmann, the author of Structure and Interpretation of Computer Programs, which is linked on here pretty often. It has to be done in the right way, though, in a language that’s expressive enough to support it.
- sixstringtheory 4y agoI would rather have dependency problems-which are able to be automated with sufficient tooling-than working in a codebase written by someone that thought you could just use floats and strings for everything in an extremely overloaded fashion. Doubly so if they don’t believe in documenting all the separate use cases and just keep all that knowledge in their head.
- za3faran 4y agoDidn't NASA lose a space orbiter due to mixing up units in the code? A properly written library should not have the issues you're mentioning.
- broadwaylamb 4y agoI think there's a misconception that types are meant to tag things according to the programmer's mental taxonomy. They're not. Types should be based on significant distinctions in how your particular program treats and processes the data. For instance, you don't need an EmailAddress type because your program doesn't do anything special with the knowledge that this string is actually an email address. It just treats it like another string. It takes some judgment to determine this, but I consider that part of the learning curve in using types rather than an inherent tradeoff from the tool itself.