
On 10/11/05, Andy Little <andy@servocomm.freeserve.co.uk> 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@servocomm.freeserve.co.uk> 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@servocomm.freeserve.co.uk> 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@servocomm.freeserve.co.uk> 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