Soft question: are Quantity - and newly added MixedUnit and MixedMagnitude - needed in a symbolic manipulation language?

Quantity is the product of magnitude and unit, so couldn't even mixed ones be represented as polynomials, eg:

t1 = 1*Unit["Hours"] + 30*Unit["Minutes"];

t2 = 30*Unit["Minutes"] + 1*Unit["Seconds"];

Note there is no Unit head in WL - using upper case U to make it look legit. What technical hurdles stand in the way of evaluating, say:

t1-t2 --> 59*Unit["Minutes"] + 59*Unit["Seconds"]

versus the current, awkward representation:

Quantity[MixedMagnitude[{1, 30}], MixedUnit[{"Hours", "Minutes"}]] - 
 Quantity[MixedMagnitude[{30, 1}], MixedUnit[{"Minutes", "Seconds"}]]
  • 4
    $\begingroup$ I started from the version of Mma, in which Quantity still did not exist. At that time we very efficiently used the constructs as 5*kg*10*m /. kg -> Nw/m with the effect 50 Nw. The advantage is that the units notations are shorter and closer to the ones we use in real "scientific" life. $\endgroup$ Commented May 11, 2016 at 14:18
  • 4
    $\begingroup$ What about multiplying by 0? 0 isn't 0 for a lot of units. 0 is different in Kelvin and Farenheit. $\endgroup$
    – Searke
    Commented May 11, 2016 at 16:32
  • 2
    $\begingroup$ @Searke, apart from temperature units (which also had special handling in the old Miscellaneous`Units`​ package), I'm hard-pressed to think of a unit example where $0$ was "special". $\endgroup$ Commented May 11, 2016 at 17:07
  • 2
    $\begingroup$ @Kuba Honestly, there probably aren't enough people using Mathematica through an IDE to worry. Lots of nice things won't work outside a notebook like :esc: dist :esc: and other such characters. For me at least, having to write out "Distributed" and "Quantity" are the least of my programming woes. $\endgroup$
    – Searke
    Commented May 11, 2016 at 23:45
  • 2
    $\begingroup$ @alancalvitti You want to add special rules to prevent 0 * x from not equaling 0 unless there's evidence that x isn't a "Unit"? Or would you prefer to have some other (worse) inconsistancy? And what about cannonicalization? You want to build the rules cannonicalizing units into the operations of Multiplication and Addition? That's a nightmare. No thank you. $\endgroup$
    – Searke
    Commented May 12, 2016 at 19:55

1 Answer 1


(The code in this answer is tested using Mathematica 10.0, in which MixedUnit and MixedMagnitude are not available. However, the online help is pretty clear, and I explain why these functions are needed.)

When two quantities are summed, it seems like a reasonable default to convert them to the same unit, as otherwise one would quickly end up with expressions involving (say) meters, nanometers, Angstroms, etc., which would have to explicitly be converted to some target unit in order to have any idea what the magnitude actually is.

So, given this default, t1 = 1 Quantity["Hours"] + 30 Quantity["Minutes"] gives Quantity[90, "Minutes"] (by the way, the choice of unit in sums seems to be such as to make (the log of) the magnitude as close to (the log of) 30 as possible), and t2 = 30 Quantity["Minutes"] + 1 Quantity["Seconds"] gives Quantity[1801/60, "Minutes"]. Their difference t1-t2 is naturally Quantity[3599/60, "Minutes"].

This result can be converted to seconds using UnitConvert[t1-t2, "Seconds"], but one may want it to be split in terms of minutes and seconds. It would have been possible to implement UnitConvert such that UnitConvert[t1-t2, {"Minutes","Seconds"}] would split t1-t2. However, UnitConvert was made Listable, which enables nice constructions such as UnitConvert[{t1,t2,t1-t2}, "Seconds"] to convert several times into seconds, or UnitConvert[t1,{"Years","Hours","Nanoseconds"}] to see a time expressed in different units, or UnitConvert[{quantities},{units}] to convert several quantities to several units (same number of quantities and units). This behaviour is consistent with very many Mathematica builtins.

Since UnitConvert[t1-t2, {"Minutes","Seconds"}] already is defined as giving t1-t2 twice, once in minutes and once in seconds, we need another way of splitting. Furthermore, it would be better if the split result Quantity[59, "Minutes"] + Quantity[59, "Seconds"] did not automatically recombine as soon as it is evaluated again (e.g., copied and pasted into a new calculation/table/etc.) So the output as a sum of Quantity is not great (one could have had a bunch of Hold, but that's horrible). The choice of expressing the split result as Quantity[MixedMagnitude[{59,59}], MixedUnit[{"Minutes", "Seconds"}]] is quite long-winded, I agree, but it has the advantages of preserving the fact that Quantity have 2 arguments in all cases (plus options), the first being the magnitude and the second the unit. This also gives a natural way to express that some quantity should be split in terms of several units: simply use MixedUnit[{"Minutes", "Seconds"}] as the unit argument of UnitConvert.

One way to implement a short-hand to express things like 1 hour and 30 minutes is the following (I used && as a notation for a sum that preserves units using MixedUnit and MixedMagnitude; however, I cannot test because my version of Mathematica is too old):

HoldPattern[And[x__Quantity]] ^:= 
1 Quantity["Hours"] && 30 Quantity["Minutes"]

(*=> Quantity[MixedMagnitude[{1, 30}], MixedUnit[{"Hours", "Minutes"}]]*)

By the way, it is very easy to define shorthands for Quantity["Hours"] etc by doing

Clear[Mili, Kilo];
Mili = 1/1000;
Kilo = 1000;
Protect[Mili, Kilo];
Scan[(Clear[#]; # = Quantity[ToString[#]]; Protect[#]) &,
  {Meters, Feet, Grams, Pounds, Kelvins, Fahrenheit}];

{UnitConvert[0 Fahrenheit, Kelvins], 2 Kilo Grams / (Mili Meters), 2 Feet + 3 Meters + 1 Kilo Feet}

(*=> {Quantity[45967/180, "Kelvins"], Quantity[2000000, ("Grams")/("Meters")], Quantity[192756/625, "Meters"]}*)
  • $\begingroup$ Bruno, thanks for this approach. I'm giving this provisional thumbs up until I get to test it. Though ideally there would be no more need for MixedMagnitude or MixedUnit, than for SecondOrderPolynomial. $\endgroup$ Commented Jun 1, 2016 at 18:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.