On Aug 23, 2013, at 2:41 AM, Steve Pitchford <steve.pitchf...@gmail.com> wrote:

> How would you implement, in a robust way, the following things:
> 
> 1 kg + 1 kg = 2 kg
> 2 m * 3 m = 6 m^2
> 5 kg * (3 m/s)^2 = 45 J
> 
> The answer is that you wouldn't - the problem domain is so vague as to be 
> meaningless. 1kg or 1m of what?

Understood; but it misses the point I was trying to make.  Bringing a measuring 
system into play needs to be more robust than merely addition and subtraction 
of common units; it also needs to be able to transform those units into related 
ones.  Let's do a little rocket science:

DeltaV = Ve * ln ( m0 / m1 )

Where DeltaV is the total amount your velocity can change, Ve is the velocity 
of your rocket propellant, m0 is your initial mass, and m1 is your final mass.  
Simple enough: as long as m0 and m1 are both measured using the same units, 
they cancel out with each other, letting us take the natural log of a unitless 
number — which is fortunate, because I don't have a clue how you'd take the 
logarithm of a number that has units of measure.  You then multiply that 
unitless number by a velocity (measured in units of distance over units of 
time) to get another velocity (measured in the same units).  

In this problem, the question "of what?" is largely irrelevant; the rocket 
formula will work equally well whether you're shooting a jet of hydrogen out 
the back of your spacecraft or if you're throwing rocks.  Likewise, the number 
of things that you use as propellant is largely irrelevant.  It doesn't hurt to 
keep track of that information, as long as doing so doesn't interfere with your 
calculations; but you don't really need it.  

A related formula is the thrust formula:

F = Isp * m' * g0

Where F is the thrust generated, Isp, is the specific impulse of the fuel (a 
measure of how "efficient" the fuel is), m' is the mass flow: the rate 
(measured in mass per unit of time) that the fuel is being expelled, and g0 is 
the gravitational acceleration at Earth's surface.  The reason why g0 is in 
there is because of a conflation between two very different kinds of units in 
the early days of rocket science, before metric became the standard in 
rocketry; namely, pounds (of force) and pounds (of mass).  

Originally, the formula was simply C< F = Isp * m' >, with F measured in pounds 
and m' measured in pounds per second; as such, Isp was assigned units of 
"seconds" to make these measurements balance out.  When the formula was 
converted over to metric, it became blatantly obvious that things had been 
improperly conflated, since force is measured in Newtons and mass flow is 
measured in kilograms per second.  When that's done, it becomes obvious that 
the Specific Impulse ought to be measured in units of speed (meters per second, 
in this case) rather than in units of time.  But by then, the convention of 
measuring Specific Impulse in "seconds" was firmly rooted in the rocket 
engineering community; so the surface gravity of Earth was brought in as a 
fudge factor, since that is the ratio of one pound of force to one pound of 
mass.  

> Going back to apples - The value of 1kg of apples in terms of representation 
> depends on context. 
> 
> For example, it would be a chore to try to arrange a group of apples to make 
> an exact kilogram. On an individual basis you may have 6 apples. In some 
> cases you may represent that as 6 instances. In another context, you may 
> represent a collection of apples in their tray form - which may have a 
> notional weight with a tolerance. Now, if one were writing a checkout system, 
> it may be sufficient for one to have a "fruit" class, of which "apples" and 
> "oranges" are instances, and both are charged in weight - and their may be 
> additional algorithms to predict stocking levels and re-ordering thresholds, 
> but from personal experience, these algorithms often require the backup of 
> business process such as stock takes to ensure that waste, theft, and 
> approximation errors are taken for granted, and we don't end up with a 
> backlog of rotten apples or empty shelves.

Some relevant tools:

There's a "repetition operator" infix:<xx> that's currently set up to take a 
string and construct a longer one made up of multiple consecutive copies of the 
original string.  e.g., C< 5 xx "ab" eq "ababababab" >.  That might be 
leveraged into a general-purpose "assign a count to an object" operator: e.g., 
C< 5 xx apple > means that you have five apples; C< 5 xx kg of apple > (would 
that parse correctly? I'm not sure off the top of my head; but I hope so) means 
that you have 5 kilograms of apples; and so on.  

Turning that around, the infix:<xx> operator could be used to assign a 
"measure" (defined by whatever is on the right-hand side) to an 
otherwise-unitless "value" (defined by whatever numeric value is on the 
left-hand side) to get a "quantity".   You could then do things like 
multiplying a quantity measured in "kg of apple" by a quantity measured in 
"dollars / kg of apple" to get a quantity measured in "dollars".  

If you mix things up and try to sell some oranges using the price for apples, 
you'll get an easily-tested-for discrepancy in the resulting quantity's 
measure: instead of getting the dollars that you'd expect, you'd get "dollars * 
kg of orange / kg of apple".  Likewise, adding 5 xx apple to 5 xx orange might 
give you 10 xx fruit, since "fruit" is the nearest-common-ancestor to "apple" 
and "orange"; but if you're looking for apples, that generalization of the unit 
will be a tip-off that something undesirable has happened.  

As I understand it, this would be commensurability: a means of testing whether 
the units you end up with after a calculation are the units that you wanted.  

Remember: solutions in Perl should aim to make common tasks easy and difficult 
tasks possible. Something like the above could make the programmer's job easy 
(or at least easier) for common tasks, and would allow him to produce more 
legible code.  It wouldn't necessarily make difficult tasks possible; but it 
might lay the groundwork for doing so, and more importantly it probably 
wouldn't interfere with other solutions for the difficult tasks.  

Trying to make the programmer always think in a strictly OO-based approach also 
runs counter to Perl's multi-paradigm model; the above is an attempt to present 
a more natural measuring system, one that reflects the way real people think 
instead of trying to cram everything into the confines of the OO paradigm.  At 
the same time, I'm trying to incorporate the power of objects into it: you can 
use classes and roles as elements of a quantity's measure.  

And ideally, it could work like a regular OO solution "under the hood", keeping 
it compatible with other solutions: what is a "quantity", anyway?  It might be 
a "quantity" class or role, or it might be a countable container of objects, or 
it might be something else entirely; I haven't gotten into the implementation 
details of it.  I'd be inclined to say that it's a role that's composed into a 
purpose-specific class (for cases where there's no individuation, just "how 
much is there?" and "what is it?"), but also into the standard container types: 
you should be able to query a list, hash, or set for "how many objects do you 
contain?" and "what kind of objects do you contain?"

There also might be some subtler issues such as whether you're doing discrete 
calculations (you can have 2 or 3 kids, but you won't ever have 2.3 kids) or 
continuous ones (there's no reason _not_ to have 2.3 gallons of gasoline).  But 
the above should be enough to get things started, I hope.  

Reply via email to