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.