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
> 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.