
Noel Belcourt <kbelco <at> sandia.gov> writes:
I have some questions and general observations for Andy.
I'm not Andy, but I'll make a few comments anyway :-) I implemented a similar library a few years ago for my job, so I think I can help respond to some of your points.
1) Can you give examples of the typical use cases for the proposed t2 and t3 quantities?
In my original review (it's in the thread called "[Review][PQS] Review deadline"), I gave a brief explanation of my use of (the equivalent of) t2_quantity and t3_quantity in my work. Actually, I find the t2_quantity most appropriate for the scientific software I write. As I'll mention below, I think the syntax and use of the t2_quantity can be more intuitive than t1_quantity and alleviates most of the problems you listed below. I almost wish the t2_quantity had been implemented first, and the library might seem less cumbersome to people looking at it for the first time. You can see a brief example in my review of how I envision the syntax would look. In my review I also explained briefly why I have a need for t3_quantity.
5) Is there any way to disable automatic unit conversion? Automatic conversion is a major liability for the scientific community in critical sections of computationally intensive codes and bugs related to this could be very difficult to track down.
6) I appreciate arguments favoring readable code but, in this case, I find that all the unit names (cm_div_s2, km_div_s2, ...) are error prone and likely to reduce code reuse. I'd prefer a solution where I define a unit system, such as the SI system, and then have all quantities in my library use that unit system. This solution makes verifying our algorithms work correctly with more than one unit system very easy, no code changes, and makes it easier to write generic algorithms that are unit independent. The explicit type solution in PQS is, in my opinion, significantly more error prone. Consider this scenario:
In a critical section of code, someone could cause repeated conversions between quantities due to a typing error. A quantity declared cm_div_s2 is, 100 lines down the function, assigned it to a quantity declared km_div_s2. This automatic conversion is tough to catch visually, won't cause a compile error but will cause significant performance and numerical problems.
I believe I understand and share your concerns. And I believe the t2_quantity, as I would envision it (and as I've successfully implemented a similar thing) is precisely meant to address every one of these issues. To explain briefly: For t2_quantity, a length is a length, etc. - there is no separate cm type and km type. Internally, the units are all consistent - say, based on meters, seconds, grams, etc. No actual units conversion takes place in computationally intensive code. Units conversion is only done, essentially, for I/O. If you don't mind a few extra multiplies and divides in your constant declarations, you can write code that looks like this: velocity v1 = 10.0 * cm/s; velocity v2 = 25.0 * km/hr; innstead of having to fuss with names like cm_per_s and km_per_hr. Btw, the same can be done for t3_quantity: t3_quantity v = 10.0 * cm/s; t3_quantity p = 2.0 * kg*m/s; where the dimensions get stored and checked at runtime. (Obviously, this incurs overhead that requires a good reason to justify its use in a particular application.) In my code I address this with a compile-time switch allowing me to turn off the "t3_quantity" dimension-checking, allowing me to eliminate all the overhead for production code, while keeping it for a debugging version. (But now I'm really getting off topic, talking about future parts of the library that don't even exist yet.)
8) Is there an easy way to replace the rational dimensions with integers? A number of disciplines could probably make do with integers and paying for rational dimensions seems expensive and unnecessary, although it's certainly more general.
I suspect (though someone may well correct me!) that fractional dimensions are never strictly necessary, in the sense that the formulas can probably be rewritten to avoid them. For a simple example, if I remember correctly, theperiod of a pendulum with a small range of angular motion is something like sqrt(g/L), where g is an acceleration and L is a length. If code is written like this: const sqrt_accel numer = sqrt(g); ... sqrt_length denom = sqrt(L); time result = numer / denom; then rational dimensions are needed. However, in this case you could also just write something like: time result = sqrt(g/L); which requires no fractional dimensions and takes no additional computation time. Having said that, the additional flexibility doesn't bother me at all if it has no runtime penalty and the details are mostly hidden from the user. If it keeps a software engineer from having to rework a physicists equations, it may well be worth it. -- Leland