Boost logo

Boost :

From: Beth Jacobson (bethj_at_[hidden])
Date: 2006-06-24 14:42:02


Andy Little wrote:
> "Beth Jacobson" wrote
>
> [...]
>
>> Under/overflow will certainly be an issue for some people if they can't
>> specify their own base units, but I don't know if a tight coupling
>> between units and dimensions is the best solution. Could there be
>> some sort of global setting (a facet, maybe?) where we could specify
>> units for base dimensions for the entire application?
>
> The quantity containers and unit typedefs can be easily customised by the user
> to whatever they prefer:
>
> namespace my{
>
> typedef boost::pqs::length::mm distance;
> typedef boost::pqs::time::s time;
> typedef boost::pqs::velocity::mm_div_s velocity;
> }
>
> void f()
> {
> my:::velocity v = my::distance(1) / my_time(1);
>
> }
>

That would remove the unit declarations from the code, but the program
still wouldn't be unit agnostic. Say I wrote a function like this

    my::area GetArea(my::length len, my::length width)
    {
       return len*width;
    }

If I used it in a program using SI units, it would work exactly like
what I'm proposing, but if the calling program used imperial units, it
would first convert len and width from feet to meters, then multiply
them, then convert the result from square meters back to square feet.
The results would be the same either way (assuming no rounding issues),
but it adds three unnecessary conversions.

>> Both your example and mine have a common element though. They both
>> involve moving between numeric values and dimensions. I can't think of
>> an instance where units would be useful when that isn't the case. If
>> that's true, then it seems like overkill to require bound units
>> throughout the program. A simpler solution would be to prohibit
>> dimension variables from being assigned or returning "raw" numbers. The
>> only way to get or set a value would be through unit functions like this.
>
> PQS quantities can't be converted to raw numbers.
>
> double val = pqs::length::m(1) ;// Error
>
> but a function is provided to get the numeric_value:
>
> double val = pqs::length::m(1).numeric_value() ;// Ok
>
> Its name is quite long so it's easy to spot in code.

Thanks. I didn't see it in the docs, but I figured there had to be some
fairly straightforward way to extract the value.

...

>> Since
>> units would be specified at the point of conversion, this method might
>> even be a little safer. In pqs, you might do something like this
>>
>> pqs::length::m depth;
>>
>> // lots of code
>
> Its not possible to initialise a double from a quantity in PQS:
>
>> double depthAsDouble(depth);
>
> so the the above will not compile.

Then the line would look like this
     double depthAsDouble = depth.numeric_value();

>
>> SetFieldValue("DepthInFt", depthAsDouble);
>>
>> cout << "Enter new depth (in feet): "
>> cin >> depth;
>>
>> Because depth is declared far from where it's output and reassigned,
>> these mistakes would be easy to miss.
>
> Not so for the above reason!

But when I use numeric_value(), the problem still remains: there's
nothing in that line to tell you the units of the extracted value. It's
not essential that there should be, but since this is one place where
the library can't protect the user against units errors, it would be
nice if such errors were easier to recognize.

>
> In PQS the units are part of the type. IOW the numeric value and its unit are
> always tightly coupled in code. That is a powerful feature. Once the numeric
> part of a quantity is disassociated from its unit then manual checking and
> external documentation is required, which is often the current situation
> wherever doubles are used to represent quantities. Manual checking doesnt always
> work as well as intended... That of course is why the Mars lander crashed!

I agree that unit checking can be an extremely useful feature, I'm just
not convinced that tight coupling is necessary to achieve that.

If my assumption that unit conversions are only needed when numeric
values are assigned to or extracted from dimensions is correct, then
dimensions don't really need to know about units. The units functions
would need to have a concept of default dimension units so they'd know
what they were converting from or to, but the dimensions themselves
wouldn't know or care.

That would be the real benefit of this system. Reducing the number of
conversions and making units explicit at the point of conversion may
have some small benefit, but making the dimensions library essentially
unitless seems like a major advantage.

Of course it's your library, and I'm not trying to dictate design. But
if you're looking for a way to make the dimensions library essentially
independent of units while retaining the unit safety of the current
system, this might be a direction to consider.

Regards,
Beth


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk