|
Boost : |
From: Matt Calabrese (rivorus_at_[hidden])
Date: 2005-10-11 14:35:30
On 10/11/05, Andy Little <andy_at_[hidden]> wrote:
>
> FWIW in pqs I worked very hard to make sure that operations worked
> smoothly
> without "rare cases". This approach made for ease of use with simple
> syntax.
>
>
I'm not going to make bad code easy to write by allowing points to be added
with operator +. Again, this is why in geometry you don't normally define
addition of points, since on its own it makes no sense. In reality it only
makes sense as an implementation detail of a higher-level operation. For
instance, the rare case you mention and that I mention are still very easily
expressible without the need for operator + to be defined. I suggested
providing a function such as average( t1, t2, t3, t4, t5, t6 ), which
internally uses component-wise addition through my componentwise_add
function (NOT using operator +). As I said, I will provide this and
barycentric combination function templates to cover those situations, but
I'm not going to overload operator + for points, since it isn't a logical
operation on its own and would just allow for illogical expressions, such as
just the addition of the temperature at the beginning of the day with the
temperature at the end of the day. If I really want to go far, using
expression templates I could allow addition to compile only if it is a
direct subexpression of a multiplicative expression containing division, or
if the expression follows the form of a barycentric combination, but that
would be going overboard. Using high-level functions which abstract the
functionality is generally a much better approach.
On 10/11/05, Andy Little <andy_at_[hidden]> wrote:
> What would you output in a case such as :
>
> std::cout << millimeters(1) / seconds(1);
I have not yet set up output, though have it planned extensively. The way I
plan on output working for unit types is, initially, when complex derived
unit types are formed through operations, their output name is going to be
described using all base classifications connected by operations I.E. if you
did 2meters * 5kilograms / 5seconds^2 the name of the unit when output would
be "5 ( meters * kilograms seconds^-2 )". Note that it would not say 5
Newtons. This is because such a name lookup could be extremely costly for
derived units and requires some form of registration. More precisely, with
registration, in order to figure out that the name "Newton" could be used,
the algorithm would still have to take R*N*log(N) time in the worst case,
where R is the number of units registered under that derived classification
and N is the number of unique base unit types which make up the derived unit
type. This complexity is necessary due to the nature of compile-time
associative sequences as having an order dependent upon how they are
created. If the person wishes to output the more simple name such as
"Newtons", they would use an expression modifier such as simply_named(
your_expression_here ) prior to output. I could provide that functionality
by default, but avoiding it can provide much better compilation time, so I
don't plan on it. In addition to this, I will also allow for shortened names
such as kg for kilograms, etc. which would also be an option prior to output
through an expression modifier.
On 10/11/05, Andy Little <andy_at_[hidden]> wrote:
>
What do you do when two quantities have the same dimensional signature eg
> torque
> and energy?
Then the division of one by the other results in a type having
"empty_classification" (which is the derived classification used by angles,
etc. as with SI Units).
On 10/11/05, Andy Little <andy_at_[hidden]> wrote:
>
The other area I worked hard at was dimensionless results for which I
> returned
> the promoted value_type of the operands. It would have been easy to
> provide a
> dimensionless quantity but this too would fail in "rare cases".
I provide a dimension-less quantity called empty_classification, since it
provides more information and is safer than a raw value. I understand why
one might think it a good idea to result in just the raw value as opposed to
an encapsulated one, but I don't believe it is the correct decision. This is
because while the resultant quantity is of an empty classification, it does
still have a unique unit type. I.E. Both radians and degrees have an
empty_classification, yet have different unit types and their values mean
different things. If you just result in the raw value as opposed to a
quantity specifying units, you lose all of the unit information. Now that
you have lost the unit information, using the value in an operation with
other units of empty_classification would be seemingly ambiguous. For
instance, I do not believe it is a good idea to allow for
quantity< degrees >( 180. ) + 3.14159
By your logic, such an expression would have to be allowable. However, it
really should not, since 3.14159, while is of empty_classification, does not
state which unit type it has. Obviously here it is in radians, which happens
to be the natural unit type of empty_classification, but you can never be
sure of this and so shouldn't even always just assume raw values are in
radians. One of the main purposes of a library like this is to make
operations more typesafe, whereas what you suggest actually has the opposite
effect.
Another example is forming an angle in radians via a ratio:
circumference_in_meters / radius_in_meters
The resultant expression is a quantity in radians and should have that unit
information accessible, despite that it is of empty classification. Your
approach would have it be a raw value without units associated with it which
just results in a loss in type information. You could just always assume raw
values are radian values, but that's just asking for trouble as it opens the
library up to misuse. If anything, I may provide a raw conversion operator
to the raw value for units with empty_classification to allow for implicit
conversion to ratios (which would be equivalent the yielding the raw value
of the quantity after being converted to radians), however I have not yet
decided if such an operation would be appropriate as implicit, and to be
honest, I am leaning towards no.
-- -Matt Calabrese
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk