Re: Units on numbers [was Re: S28ish]
Craig DeForest wrote: Yow -- units would be extra cool for perl6: I know of no other language that has units support built in. It would go a long way toward making perl6 the language of choice for students in the physical sciences... Frink is built around this idea: http://c2.com/cgi/wiki?FrinkLanguage - osfameron
Re: Units on numbers [was Re: S28ish]
Craig DeForest wrote: Yow -- units would be extra cool for perl6: I know of no other language that has units support built in. It would go a long way toward making perl6 the language of choice for students in the physical sciences... Well, my HP48 pocket calculator used to have it :) -- TSa (Thomas Sandlaß)
Re: Units on numbers [was Re: S28ish]
Craig DeForest wrote: Yet another point: there are plenty of non-obvious reductions that people worry about, such as "N m" -> "J" (energy) but "m N" -> "m N" (torque); but it's probably not worth worrying about such things: if the coder knows that s/he wants a torque, s/he should be able to ask for reduction to a particular form [e.g. 'units( $val, $template )' should exist and return $val in whatever units $template has, if possible.] Oh, and don't underestimate the usefulness of doing things in non-base-ten mixed units, and useful fractions: my height is 5`ft+(6+1/4)`in, not 66.25`in, thank you. In any case, I'd love something like this, and I suspect many other people would as well... but remember, again, extensibility is key. C< $d=22`AWG; $a=pi*($d/2)**2; print $a`mm**2." qm"; # buying wire in Germany> doesn't work very well if there is no way to specify insane units like AWG. 25`USD*1.06+5`EUR can't be computed at all without extensibility, because the conversion rate from USD to EUR doesn't stay static over time. For that matter, monetary conversions are going to take some effort to get right, though they will be very useful if they are gotten right, because going through a common intermediary isn't correct. You won't get the same results converting USD to EUR to JPY as you will from converting USD to JPY. (OTOH, if you want to convert from DEM to FRF, you /must/ convert to EUR in the middle, or you will get the wrong result. Of course, neither the DEM nor the FRF have existed in several years, so it probably isn't that important...) -=- James Mastros, Who certainly looks forward to this.
Re: Units on numbers [was Re: S28ish]
>From: [EMAIL PROTECTED] >The problem with using the >units(1) database is that it only >deals with >multiplicative relations -- so, e.g., >It won't handle temperature. So the temperature functions available in units(1) aren't defined in the database? They're hard-coded? I find that unlikely. In case you haven't seen them, I'm talking about TempF(x) and TempC(x), which represent absolute points on the scale and convert happily to each other including the offset, not degF and degC which represent temperature differences.
Re: Units on numbers [was Re: S28ish]
On Monday 28 March 2005 05:48 pm, Craig DeForest wrote: > The problem with using the units(1) database is that it only deals with > multiplicative relations -- so, e.g., it won't handle temperature. [EMAIL PROTECTED]:~$ units 2084 units, 71 prefixes, 32 nonlinear units Among those "nonlinear units" are such units as tempF and tempC, defined as functions of a base unit tempK; units(1) seems to be at least decently capable with such things. --Andrew
Re: Units on numbers [was Re: S28ish]
On Mon, 2005-03-28 at 17:48, Craig DeForest wrote: > The problem with using the units(1) database is that it only deals with > multiplicative relations -- so, e.g., it won't handle temperature. Well, that's fine. You don't have to get everything from one source. Larry is right though, units is a fine starting point. I'm still of the basic opinion that all of the logic can be handled through roles (classes?) and MMD, rather than trying to code up a units converter in parallel to the type system. -- Aaron Sherman <[EMAIL PROTECTED]> Senior Systems Engineer and Toolsmith "It's the sound of a satellite saying, 'get me down!'" -Shriekback
Re: Units on numbers [was Re: S28ish]
The problem with using the units(1) database is that it only deals with multiplicative relations -- so, e.g., it won't handle temperature. Units resolvers are not so hard to come by -- the strategy is to try to break each compound unit out into a collection of fundamental quantities that are interconvertible (e.g. all lengths get converted to "meters"), while keeping track of the conversion constant. I haven't looked at units(1) in a while, but it used to do this to both the original units and the destination units, then take the ratio of the accumulated constants. That's why the "conformability" error messages are sometimes a little weird: they always refer to the fully expanded SI representation of each unit. Quoth Aaron Sherman on Monday 28 March 2005 03:40 pm, > On Mon, 2005-03-28 at 16:00, Larry Wall wrote: > > I've always thought that we should make use of the database of the > > "units" program for standardized names of units. The units database > > has a pretty good list of which units are just differently scaled > > units of the actual underlying fundamental dimensions, and a lot > > of encoded experience in distinguishing ambiguous units names. It'd > > be a shame to reinvent all that. > > That makes fine sense, and I think it would be fairly trivial to > generate a set of roles from the Units database at run-time, > pre-compiled with the source or both (selectable in some way). > > Of course, there are going to be people who have to re-define chunks of > that namespace because they have special needs (e.g. money -- this is > such a huge bear of a problem that it can only be solved for the > domain-specific cases), but that's fine, and does not preclude your > suggestion. > > here's a start: > > perl -nle 'while(<>) {print("# $_"),next if /^\s*($|\#)/;$c="";s/\s+\#.*// > && ($c=$&);($unit,$def)=split /\s+/, $_, 2;if ($def eq "!") > {$base{$unit}=1;print "class units::$unit does unit { ... }$c"} elsif > ($unit =~ /-$/){print "# No handling for prefixes yet > ($unit=$def)$c"}elsif($base{$def}){print "class units::$unit is > units::$def;$c"}else{print "# No handling for derived units yet > ($unit=$def)$c"}}' < /usr/share/units.dat
Re: Units on numbers [was Re: S28ish]
On Mon, 2005-03-28 at 16:00, Larry Wall wrote: > I've always thought that we should make use of the database of the > "units" program for standardized names of units. The units database > has a pretty good list of which units are just differently scaled > units of the actual underlying fundamental dimensions, and a lot > of encoded experience in distinguishing ambiguous units names. It'd > be a shame to reinvent all that. That makes fine sense, and I think it would be fairly trivial to generate a set of roles from the Units database at run-time, pre-compiled with the source or both (selectable in some way). Of course, there are going to be people who have to re-define chunks of that namespace because they have special needs (e.g. money -- this is such a huge bear of a problem that it can only be solved for the domain-specific cases), but that's fine, and does not preclude your suggestion. here's a start: perl -nle 'while(<>) {print("# $_"),next if /^\s*($|\#)/;$c="";s/\s+\#.*// && ($c=$&);($unit,$def)=split /\s+/, $_, 2;if ($def eq "!") {$base{$unit}=1;print "class units::$unit does unit { ... }$c"} elsif ($unit =~ /-$/){print "# No handling for prefixes yet ($unit=$def)$c"}elsif($base{$def}){print "class units::$unit is units::$def;$c"}else{print "# No handling for derived units yet ($unit=$def)$c"}}' < /usr/share/units.dat -- Aaron Sherman <[EMAIL PROTECTED]> Senior Systems Engineer and Toolsmith "It's the sound of a satellite saying, 'get me down!'" -Shriekback
Re: Units on numbers [was Re: S28ish]
On Mon, Mar 28, 2005 at 01:30:14PM -0700, Craig DeForest wrote: : Yow -- units would be extra cool for perl6: I know of no other language that : has units support built in. It would go a long way toward making perl6 the : language of choice for students in the physical sciences... Well, yes. I certainly would have liked it back when I was taking physics, but I had to make do with BASIC/PLUS. One of the reasons I eventually got hired on at the college's computer center was that the director was impressed by the fact that my physics program to calculate the gravitational constant from my experimental data was named "G". He said, "Everyone else always names their programs with the full six available characters." So he knew I was a Lazy Critter from the start. Larry
Re: Units on numbers [was Re: S28ish]
On Mon, Mar 28, 2005 at 03:40:14PM -0500, Aaron Sherman wrote: : Now you can ask for whatever you like: : : say "We have {â.new $money}â" : : Though you might have some snazzy way of saying that. Just by the by, that's illegal syntax. Methods with arguments require parens. You could, however, say say "We have {new â: $money}â" : > The real "fun" in determining what should happen with units comes to : > when you do operations that _change_ the units. Doing the proper dimensionalysis, that's really just a specialized form of type inferencing, I expect. : > my $Current= 5`Amps; : > my $Resistance = 10`Ohms; : > my $Power = $Current * $Resistance; # Do I get 50`Watts here? : : Again, if Amps and Ohms know that they can do that, then you're all set. : Otherwise, you just construct a new value like so: : : my Watts $Power = $Current * $Resistance; : : Which again are probably all aliases for Units::Physics::* I've always thought that we should make use of the database of the "units" program for standardized names of units. The units database has a pretty good list of which units are just differently scaled units of the actual underlying fundamental dimensions, and a lot of encoded experience in distinguishing ambiguous units names. It'd be a shame to reinvent all that. But the basic underlying principle here is just the same as with characters. Define your formal parameters in terms of the fundamental dimensions like Length and Time, and let the computer worry about the scaling issues. I consider types like Velocity and Acceleration to also be fundamental in that sense, even though composed of other fundamental dimensions, so it's not necessary to write Length/Time or Length/Time**2 (however you care to spell those types). It is this sense in which Position or Ptr is fundamental, even though it is a location in a particular string at a particular time. Larry
Re: Units on numbers [was Re: S28ish]
On Mon, 2005-03-28 at 15:07, Rod Adams wrote: > Markus Laire wrote: > > 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... > > # 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? You ask for the unit you want. I'm not sure I like or dislike this syntax, but it's easy enough to see that: 12`¤ is just 12 but ¤ where ¤ is probably an alias for the class (role?) Units::Money::Euro. Addition would be defined in a base class in such a way that conversion to an appropriate intermediate unit would be done and then addition performed. The derived classes would provide addition only for the special case where both operands were in the derived unit (for performance). Now you can ask for whatever you like: say "We have {¤.new $money}¤" Though you might have some snazzy way of saying that. > 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? Again, if Amps and Ohms know that they can do that, then you're all set. Otherwise, you just construct a new value like so: my Watts $Power = $Current * $Resistance; Which again are probably all aliases for Units::Physics::* -- Aaron Sherman <[EMAIL PROTECTED]> Senior Systems Engineer and Toolsmith "It's the sound of a satellite saying, 'get me down!'" -Shriekback
Re: Units on numbers [was Re: S28ish]
Yow -- units would be extra cool for perl6: I know of no other language that has units support built in. It would go a long way toward making perl6 the language of choice for students in the physical sciences... The perl5 CPAN modules already have a pretty good unit system that could be ported to the junctive strategy. The problem of resolving ambiguous units is subject to DWIMming based on context; my own units engines always include a context field that lets you choose what context should be used for further unit string parsing (e.g. "SI", "currency", etc.). If not specified, any unambiguous units in a compound statement can be used to guess an appropriate context for the ambiguous ones. It's not clear how that would fit into the junction scheme, but that might bear some thinking about... Another point: one should probably worry more about making the unit parser extensible, than about making it complete. The main symptom of an incomplete or confused parser is a bunch of units-junk that is usually parsable by a human but not in "simplest form" (e.g. "barn megaparsec tsp^-1" or some such [0.63]); that's generally not a fatal problem, especially if the user has access to the units database and can add another simplifying resolution. Yet another point: there are plenty of non-obvious reductions that people worry about, such as "N m" -> "J" (energy) but "m N" -> "m N" (torque); but it's probably not worth worrying about such things: if the coder knows that s/he wants a torque, s/he should be able to ask for reduction to a particular form [e.g. 'units( $val, $template )' should exist and return $val in whatever units $template has, if possible.] Quoth Rod Adams on Monday 28 March 2005 01:07 pm, > 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 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/
Re: Units on numbers [was Re: S28ish]
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 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
Re: Units on numbers [was Re: S28ish]
Larry Wall wrote: > ... SKIP ... Okay, that looks scary, but if as in my previous message we define "chars" as the highest Unicode level allowed by the context and the string, then we can just write that in some notation resembling: substr($a, 5`Chars, 10`Chars); or whatever notation we end up with for labeling units on numbers. Even if we don't define "chars" that way, they just end up labeled with the current level (here assuming "Codes"): substr($a, 5`Codes, 10`Codes); or whatever. But this is all implicit, which is why you can just write substr($a, 5, 10); and have it DWYM. 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? my $unit = 1`Minutes|Kilograms|Meters; my $time_mins`Minutes = $unit * 5.45; # 5.45 Minutes my $time_secs`Seconds = $unit * 5.45; # 327 Seconds my $weight`Weight = $unit * 2.34; my $length`Length = $unit * 12.56; But these would need MMD based on return-type which is out IIRC? So perhaps just simple: my $time_mins = unit_conversion($unit * 5.45, Minutes); my $time_secs = unit_conversion($unit * 5.45, Seconds); Or using some infix-op: my $time_mins = ($unit * 5.45) ` Minutes; my $time_secs = ($unit * 5.45) ` Seconds; And what about hex/dec/oct/bin? Could these be included in this system? my $number`Dec = 12`Oct + 010101`Bin + 0cab`Hex; And then we of course definitely need my $length = 12`Oct&Miles + 0c`Hex&Kilometers;:) Not sure if I'm on right track at all - but Units on numbers with MMD gives some really nice ideas to a mathematically minded person... my $speed_a = 78`Kilometers / 2`Hour; my $speed_b = 50`(Miles/Hour); # or 50`Miles_per_Hour my $delta = $speed_a - $speed_b; -- Markus Laire