Markus Laire wrote:

Larry Wall wrote:


Now, I admit that I've handwaved the tricksy bit, which is, "How do you know, Larry, that substr() wants 5`Codes rather than 5`Meters? It's all very well if you have a single predeclared subroutine and can look at the signature at compile time, but you wrote those as multi methods up above, so we don't know the signature at compile time."

Well, that's correct, we don't know it at compile time.  But what
*do* we know?  We know we have a number, and that it was generated
in a context where, if you use it like a string position, it should
turn into a number of code points, and if you use it like a weight,
it should turn into a number of kilograms (or pounds, if you're NASA).

In other words, the effective type of that literal 5 is not "Int",
but "Int|Codes|Meters|Kilograms|Seconds|Bogomips" or some such.
And if MMD can handle that in an argument type and match up Codes as
a subtype of Ptr, and if we write our method signature only in the
abstract types like Ptr, we're pretty much home free.  That certainly
simplifies how you write S29, though I don't know if the MMD folks
will be terribly happy with the notion of dispatching arguments with
junctional types.  But it does fall out of the design rather naturally.

> ...

So do you actually envision perl6 to allow a junction of units on numbers? This would have huge implications, depending on what exactly is possible with these units...


Would/could some of these DWIM in perl6?

    # import proper MMD-subs for + - * etc...
    use MyUnitConversions;

    my $length = 1.3`Meters + 4.6`Yards;
    my $weight = 4`Pounds - 1'Kilograms;
    my $money = 12`€ + 5.78`£ + 12`US$;

Then, how would I specify the unit of the result?

The real "fun" in determining what should happen with units comes to when you do operations that _change_ the units.

 my $Current    = 5`Amps;
 my $Resistance = 10`Ohms;
 my $Power      = $Current * $Resistance; # Do I get 50`Watts here?


my $theta = 45`Degrees; my $x = cos($theta); # no units on $x my $theta2 = acos($x); # in radians? or does $x carry a # "used to be Degrees" property?


my $distance1 = 100`Meters; my $distance2 = 0.25`Kilometers; my $timeinterval = 5'Seconds; my $velocity1 = $distance1 / $timeinterval; my $velocity2 = $distance2 / $timeinterval; my $acceleration = ($velocity2-$velocity1)/$timeinterval; # is $acceleration something like 30`Meters/Second/Second ?

Don't forget fun operations like C<$x**2> and others, which should be nicely reversible, or used as is. (Think cubic meters for volume). And there will likely always be corner cases like C<exp(2*log(5`Feet)) != 5`Feet**2> which I would be very surprised about it Perl caught them.

Another fun thing is dealing with ambiguous unit names. "Pound" can refer to Force, Mass, or Money. "1`Gallon" can be either "4`Quarts" or "5`Quarts" depending on which side of the Atlantic you're on. "Ounce" can be either Mass or Liquid Volume, _and_ has US/UK issues. Having to specify "5`FluidUSOunces" can get tedious, though hopefully short aliases can be made. Then there's the fun of currency, where the exchange rates are time dependent. (Do we start say "5'US$.at($time)"?)


All that being said, I think it would be great if we could come up with a way of integrating units into Perl 6. But I'd want the following features:
- It's more than just a "toy" for solving a few minor problems like specifying characters.
- It's fairly comprehensive in that it should be easy to write functions which mutate the units intelligently, and know when to flag a type mismatch.
- It all goes away by default for the user who doesn't want to bother with it.



-- Rod Adams

Reply via email to