Boost logo

Boost :

From: David Walthall (walthall_at_[hidden])
Date: 2006-06-19 13:53:51

Oleg Abrosimov wrote:
> Actually, my question is:
> Can you provide good reasons to follow current PQS style (length::m
> etc.) instead of simply Length, as me and others have proposed?

I can think of a couple. Here is a rather contrived one:

pqs::length universe_radius = 1.4e26 * METER;
pqs::volume universe_volume =
     (4.0/3.0) * M_PI * pqs::pow<3>(universe_radius);

You now have 2.744e78 m^3, which could overflow if the maximum exponent
of the double on your system is +37. As I said, that was contrived, but
  embedded systems may not have a large maximum exponent for doubles.

Here is another one from a How about this one that is really from an
application I work on. The layer that I work on has to collect data
from several legacy application outputs that use different underlying
systems of units. One gives data in kJ and another gives data in kcal.
  Rather than having to constantly convert between the two values, which
is error prone, I simply write:

// Prototypes of interface with two different legacy codes
pqs::energy::kJ GetLegacyData1(/*args*/);
pqs::energy::kcal GetLegacyData2(/*args*/);

// used in my program
pqs::energy::kJ = GetLegacyData1() + GetLegacyData2();

Compare that to what I would have to write under a uniform units system.
   Inside of both GetLegacyData2(), instead of just the code:

   return pqs::energy::kcal(ptr->value);

I'd have to write

   return pqs::energy::J(KILOCALORIES * ptr->value);

Not terribly different, but there is an extra conversion in there, and
that brings up a chance for errors. What if I accidentally wrote
KILOCALORIES / ptr->value ? Assuming that I wrote the definition of
KILOCALORIES (which I'd almost certainly have to do for more complicated
things like angstroms^2/picosecond, which is a unit that comes up for
me), I'd have to be careful that (1) I wrote the conversion KILOCALORIES
correctly, and (2) I used it correctly.

Suddenly, all of the nice automatic conversions that save me time (is it
multiply by 4.184 or divide?) are gone and back on my shoulders. I was
ecstatic to get rid of all of the conversion factors in my code, and I
would be sad to see that go away.

> In this letter you only said that it was not a rational decision, but a
> historical one. It doesn't convince me. It is not a good reason for
> library that pretends to be in boost IMO.
> Moreover, I have a strong feeling that the solution with simple Length
> would be better. In particular, it'll simplify your code that uses PQS.

In my opinion, the purpose of a library should be to make the user's
life easier. That is why we are willing to tolerate the awful syntax of
operator[](int i) when we write a class. We only write it once, but use
it many times.

For anyone who wants to use only the basics, you can simply write:
namespace pqs {
   typedef boost::pqs::length::m length;
   static const length METER(1.0);

   typedef boost::pqs::length::s time;
   static const time SECOND(1.0);

   typedef boost::pqs::velocity::m_div_s velocity;
   static const velocity M_PER_S(METER/SECOND);

   // etc for other units

and then just use:
pqs::length inch = 0.0254 * METER;
pqs::time ps = 1.0e-12 * SECOND;
pqs::velocity v = inch/ps;

Everything is nicely stored in meters, seconds, etc. You'll suffer some
compile-time penalty (compared to a much simpler system where everything
can only be in the basic units) for the fact that you don't use all of
the library's power. There should be no run-time penalty (assuming that
you have a good optimizing compiler) since all of the conversions are
known at compile-time and are 1.0.

> You've said that PQS helps you to remember in what units a variable is.
> In a scheme with Length you simply have no need to remember it nor think
> about it anymore.

For me, the beauty is that I don't have to remember (or even care what
units the underlying system gave me the values in). Once the accessor
function was defined, I could store them in whatever units I want and
let PQS do all of the conversion.

Boost list run by bdawes at, gregod at, cpdaniel at, john at