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`OctMiles + 0c`HexKilometers;:) 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 Jam. 1:5-6
xx and closures
We were discussing on #perl6, and thought that the feature: sub foo () { say Blech; } { foo() } xx 5; Would be useful. Since it is dwimmery, and you wouldn't want the closure to execute if you didn't know it was there, we decided that it would probably be best if this were distinct from: my $closure = { foo() }; $closure xx 5; Does the convenience (and obviousness when reading) enough to warrant adding a special case in this situation? Luke
strings, numbers and... lists?
The discussion about x/xx made me wonder. We have this table: string list x xx ~ , And we also have this table: string number ~ + - x * eq == But there is overlap between the two tables: string number list x * xx ~ + , Let's add the other operators: string number list x * xx ~ + , - eq == The list form of eq/== is known in eq and ==, but these don't work well when the types are not balanced. And the string form of minus is currently spelled s/foo//. There is, as far as I know, no listy minus. I suggest we add operators to fill this the void and add to TIMTOWTDI. Because the ASCIIbet is exhausted, I'll use existing numeric operators enclosed in square brackets. string number list x * xx ~ + , [+] - [-] eq == [~~] I chose chosen smart match instead of equality here, because of the balancedness thing. [~~] is like the rather verbose all(... ~~ ...): if (all(@foo ~~ @bar) { ... } if (@foo [~~] @bar) { ... } The difference between , and [+] is precedence: my @foo = (@bar, @baz); my @foo = @bar [+] @baz; This buys us a nice alternative for push too. It's like the much discussed ,= but communicating the same thing better: push @foo, @bar; @foo [+]= @bar; This is still rather boring. It gets more interesting when we add minus: splice @foo, $_, 1 given first { @foo[$_] ~~ 15 }, [EMAIL PROTECTED]; @foo [-] 15; # whoa! Note that grep solves a different problem: it would remove all occurrences of 15, instead of only the first encountered. And, this can remove multiple elements at once: splice @foo, $_, 1 given first { @foo[$_] ~~ 15 }, [EMAIL PROTECTED]; splice @foo, $_, 1 given first { @foo[$_] ~~ 15 }, [EMAIL PROTECTED]; splice @foo, $_, 1 given first { @foo[$_] ~~ 42 }, [EMAIL PROTECTED]; @foo [-] (15, 15, 42); If we allow all() to be a special case on the RHS, we get a synonym for grep too, now communicating what we want gone instead of what we want to be left with: @foo .= grep :{ not /\W/ }; @foo [-]= all /\W/; Consistency would want any() to remove a random matching element, and the default to really justs imply one(). There's one hole left in the table. Stringy minus can just be ~-: string number list x * xx ~ + , [+] - [-] eq == [~~] This wants ~ to be an abbreviation for ~+, and eq for ~==, which if we grab the table for bitwise operations and put everything to gether, gets us ?== for boolean equality. do { ($temp = $foo) ~~ s/gone//; $temp } $foo ~- foo; Of course, you'd want to allow regexes too: do { ($temp = $foo) ~~ s/g+one//; $temp } $foo ~- /g+one/; We're now communicating that we want to remove something, instead of replace it with an empty string. This is very powerful self-documentation. Again, if we want to remove all of them, a conjunction comes to our resque. do { ($temp = $foo) ~~ s/g+one//; $temp } $foo ~- all /g+one/; But, of course, :each should work too. More dwimmery can probably be invented by looking at the operator table in S03 and applying the same logic. [+] should probably be spelled (+) but that's uglier. Other alternatives are @+ (but this REALLY says array, while it's for lists) and *+ (hard to read, but ~^ and ~- have the same problem). Juerd -- http://convolution.nl/maak_juerd_blij.html http://convolution.nl/make_juerd_happy.html http://convolution.nl/gajigu_juerd_n.html
Re: strings, numbers and... lists?
Juerd skribis 2005-03-28 16:44 (+0200): splice @foo, $_, 1 given first { @foo[$_] ~~ 15 }, [EMAIL PROTECTED]; @foo [-] 15; # whoa! Note: unfair comparison. The equal thing would be [-]=. In fact, this illustrates the problem even better, because to get @foo [-] 15 without [-], you need either a temporary array: do { my @temp = @foo; splice @temp, $_, 1 given first { @temp[$_] ~~ 15 }, [EMAIL PROTECTED]; @temp } or a grep with an extra variable: do { my $seen_first; grep { $seen_first or $_ ~~ 15 $seen_first++ } == @foo } Juerd -- http://convolution.nl/maak_juerd_blij.html http://convolution.nl/make_juerd_happy.html http://convolution.nl/gajigu_juerd_n.html
string/list division
It was a matter of time, of course, after my last thread. How often do we want chunks of a string or list? And how often do we abuse a temporary copy and substr/splice for that? What if instead of my @copy = @array; while (my @chunk = splice @copy, 0, $chunksize) { ... } # ^1 we could just write for @array [/] $chunksize - @chunk { ... } and instead of my $copy = $string; while (defined(my $chunk = substr $copy, 0, $chunksize)) { ... } # ^2 we could use for $string ~/ $chunksize - $chunk { ... } I think it'd make life much easier. Of course, [/] is subject to the same discussion as the other thread, and should perhaps be (/) or */. Juerd PS. http://tnx.nl/3689VBOF # consistency gone mad (expires in 1 day) ^1 Yes, I know it can be made more efficient by using the list reference trick, sub { [EMAIL PROTECTED] }-(LIST). ^2 Same thing, but with \substr. Too bad there is only one LVALUE, because you can't keep a reference around. Will this be fixed in P6? -- http://convolution.nl/maak_juerd_blij.html http://convolution.nl/make_juerd_happy.html http://convolution.nl/gajigu_juerd_n.html
Re: string/list division
Juerd writes: What if instead of my @copy = @array; while (my @chunk = splice @copy, 0, $chunksize) { ... } # ^1 Well, I for one never write that. I very seldom use splice. we could just write for @array [/] $chunksize - @chunk { ... } Well, we could also write: for @array - $a, $b, $c {...} But if we're dealing with the chunks, rather than named pieces of the chunks, then I wonder if this would DTRT: for @array - [EMAIL PROTECTED] is shape($chunksize) {...} I have difficulty believing that that would work. Essentially we need a way of saying that the arity of a parameter list is a specific size, but that we want to put all the arguments into an array. And of course if it were possible, then the above would be the way to do it. Your list mod idea is interesting, though. I fear that adding too many list operators will start to make us look like Haskell, where we have *extremely* expressive single lines that take an hour to write and an hour to read (I call this concise hell). I think the fact that we have other WTDIs might save us from that, though[1]. I remember talking to an APL programmer at the last OSCON, who believed that APL captured a program's essence. The fact that you could do very complex things using combinatorial meta operators in very few characters seemed to him to define the true nature of programming (Identifying programming much more with mathematics than with engineering on this front). It is questionable whether we should give him his essence in Perl 6. On one hand, it's another paradigm, and Perl 6 is multiparadigmatic so that everybody feels comfortable writing it. On the other hand, the more paradigms we include, the more code readers won't understand (and learning new paradigms is very much harder than learning new syntax). Still, Perl's module theory of encapsulation works somewhat well for a multiparadigmatic language, where generally only one person has to understand the code... but he has to understand it very well. But I digress (one wonders how *that* came out of this proposal). [1] Keep in mind that I don't necessarily consider concise hell to be a bad thing. I just consider it very different from the direction Our Successful Perl has gone so far, and certainly different from the way I like to write/read code. But I'll use concise hell as a negative connotation for the rest of this email, because I'm subjective like that. and instead of my $copy = $string; while (defined(my $chunk = substr $copy, 0, $chunksize)) { ... } # ^2 Which is very rare in the regexy world of Perl. I almost never use Csubstr, since regexes do everything I ever wanted to do with strings but was afraid to ask. we could use for $string ~/ $chunksize - $chunk { ... } I think it'd make life much easier. Supposing that we see a need for an operator like this. I wonder if we're diving so far into the realm of consistency with this proposal that it would be better to talk about the ~ and [ ] metaoperators. And of course the + variants of these operators could not exist since numbers behave quite differently from sequences. So, let's consider for a moment what a string looks like if it were just like a list of characters (barring Unicode discussions which I generally try to avoid). Let's use ~[] for string-meta and *[] for list-meta. ~[~] is just like ~, but *[~] concats two lists, an operation perl has seemed lacking (not that that's been an issue). *[] is shift, *[] is pop, ~[] is chop, ~[] is that other one that people have requested. I don't know what the meta-comparison operators would do. If we define them so that: [$a, $b, $c] *[] [$d, $e, $f] === $a $d $b $e $c $f, then we find that *[] and *[] are mostly adding syntax for something relatively uncommon that deserves a name (and is starting to look like concise hell). *[==] on the other hand is extremely useful, and is something that perl has lacked in its core for ages. Uh, that's about all I can really think of for useful operators. Perhaps I'm missing some (like your modulus, but that's defining a new sequence mod operator anyway). All in all, I don't think meta operators buy us very much in this case, except for more tickets to concise hell. Perhaps a good thing to do here is to separate out a class of sequence operators, like ~ and your [/], define them parallel-like for strings and lists, and see how that looks. If I were the one doing this, I would try to keep the list of sequence operators small (not every operator need have a sequential analog). Luke
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 Cexp(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
Re: string/list division
On Mon, 2005-03-28 at 13:38, Luke Palmer wrote: Your list mod idea is interesting, though. I fear that adding too many list operators will start to make us look like Haskell, where we have *extremely* expressive single lines that take an hour to write and an hour to read (I call this concise hell). Ah, to have access to the Concise Hell compiler... ;-) Seriously, if you have a line of code which takes an hour to write and an hour to read, is that any better or worse than the equivalent 10 pages of code that take an hour to write and an hour to read? That said, one of Perl's largest PR problems has always been the power of the syntax and grammar of the language. When people look at a program and see: my %uid_map = map {/^(\w+):[^:]*:(\d+)/} ; They tend to get a hair upset. It's not that they have to stare at this any longer than they have to stare at the equivalent in C or C++ or Java, but that they have this understanding of how long it should take to read a line of code, without respect to the semantic content of the line. In this one line we have (yeah, I know you can all read it, but I'm going to list the components so that we stop and think about them) the equivalent of a block of code with three loops (a read loop, a match/store loop, and a hash builder loop), along with the implicit behavior of over the pseudo-filehandle ARGV, along with the implicit behavior of m/.../ in a list-context. Write that in C and it would be a LOT of code (depending on the toolkits you used). Which one is easier to read? I'd argue that the Perl is much easier to read, but that's only IF you know Perl well enough that you can absorb such semantic complexity at a glance. The question is: should you be apologetic and/or fail to follow this semantic compression down to its logical conclusion because some people will find it off-putting. I think that in the specific case of Perl 6, the answer is a resounding NO for two reasons: 1. Perl 6 can (dangerous lack of the future subjunctive here) introspect to a degree that almost no other language can (some functional languages are exceptions here), so writing a strict module that forces programmers to avoid these semantically rich constructs (or limit their use to reasonable situations) is at your fingertips. You could even make it invalid at a parser level to chain more than some given number of operations. 2. Parrot provides access to Perl 6 code from other languages, so if Damian writes some wiz-bang module that everyone in the world wants access to, even the people who don't like Perl 6 can do so without having to get used to Perl 6. If APL had had Parrot, we might all be running APL code to this day. Because of this, Perl 6 need not apologize for it's APL/Haskell-like penchant for semantic compression. It can evolve along the lines that Perl 4 and 5 made available to it, and not leave anyone behind. -- Aaron Sherman [EMAIL PROTECTED] Senior Systems Engineer and Toolsmith It's the sound of a satellite saying, 'get me down!' -Shriekback
Re: String Theory
On Mon, Mar 28, 2005 at 11:53:07AM -0500, Chip Salzenberg wrote: : According to Larry Wall: : On Fri, Mar 25, 2005 at 07:38:10PM -, Chip Salzenberg wrote: : : And might I also ask why in Perl 6 (if not Parrot) there seems to be : : no type support for strings with known encodings which are not subsets : : of Unicode? : : Well, because the main point of Unicode is that there *are* no encodings : that cannot be considered subsets of Unicode. : : Certainly the Unicode standard makes such a claim about itself. There : are people who remain unpersuaded by Unicode's advertising. I conclude : that they will find Perl 6 somewhat disappointing. If it turns out to be a Real Problem, we'll fix it. Right now I think it's a Fake Problem, and we have more important things to worry about. Most of the carping about Unicode is with regard to CJK unifications that can't be represented in any one existing character set anyway. Unicode has at least done pretty well with the round-trip guarantee for any single existing character set. There are certainly localization issues with regard to default input and output transformations, and things like changing the default collation order from Unicodian to SJISian or Big5ian or whatever. But those are good things to make explicit in any event, and that's what the language-dependent level is for. And people who are trying to write programs across language boundaries are already basically screwed over by their national character sets. You can't even go back and forth between Japanese and English without getting all fouled up between ¥ and \. Unicode distinguishes them, so it's a distinction that Perl 6 *always makes*. That being said, there's no reason in the current design that a string that is viewed as on the language level as, say, French couldn't actually be encoded in Morse code or some such. It's *only* the abstract semantics at the current Unicode level that are required to be Unicode semantics by default. And it's as lazy as we care to make it--when you do s/foo/bar/ on a string, it's not required to convert the string from any particular encoding to any other. It only has to have the same abstract result *as if* you'd translated it to Unicode and then back to whatever the internal form is. Even if you don't want to emulate Unicode in the API, there are options. For some problems it'd be more efficient to do translate lazily, and for others it's more efficient to just translate everything once one input and once on output. (It also tends to be a little cleaner to isolate lossy translations to one spot in the program. By the round-trip nature of Unicode, most of the lossy translations would be on output.) But anyway, a bit about my own psychology. I grew up as a preacher's kid in a fundamentalist setting, and I heard a lot of arguments of the form, I'm not offended by this, but I'm afraid someone else might be offended, so you shouldn't do it. I eventually learned to discount such arguments to preserve my own sanity, so saying someone might be disappointed is not quite sufficient to motivate me to action. Plus there are a lot of people out there who are never happy unless they have something to be unhappy about. If I thought that I could design a language that will never disappoint anyone, I'd be a lot stupider than I already think I am, I think. All that being said, you can do whatever you like with Parrot, and if you give a decent enough API, someone will link it into Perl 6. :-) Larry
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 Cexp(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
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]
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, 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, 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]
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 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]
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
getting Perl 6 special support in text editors
This message is largely FYI, and some of its details are only relevant to Mac OS X users, though the general theme is not. Following today's release of BBEdit 8.1 text editor, which among its new features is integrated Subversion support (it had CVS for awhile already), I have been compelled to write the creators with my first feature request. The message I sent is quoted verbatim below. In short, I requested Perl 6 specific support and gave them some pointers on what I thought were short term priorities as well as info or suggestions to make their job the easiest (resulting in soonest delivery). This was prompted largely by that the existing (and otherwise very useful) Perl 5 syntax coloring makes a mess (runaway string quote) when encountering such things as 's:g///' and '$foo //= $bar'. AFAIK, a lot of Perl 6 developers use Mac OS X, and should benefit from this. As for users of other environments, I don't know if any other editors already do the right thing with Perl 6 syntax; if not, I suggest that now is a good time to petition their creators for this feature and/or add it yourselves. Right about now is just when we should be getting a large influx of Perl 6 developers, and they might as well have the best possible experience. Assuming this request is accepted, I will post again when the supporting version is available and/or a roadmap is known. -- Darren Duncan -- Date: Mon, 28 Mar 2005 14:49:47 -0800 To: [EMAIL PROTECTED] From: Darren Duncan [EMAIL PROTECTED] Subject: BBEdit 8.1 feature request: Perl 6 syntax coloring Cc: [EMAIL PROTECTED] To the BareBones support team, Thanks for the improvements you brought in BBEdit 8.1, such as the Subversion integration. BBEdit is probably the most valuable application that I own, and that I spend the most of my computer time using. I have a feature request that I hope you can include ASAP, such as by the time BBEdit 8.2 ships, if not sooner (such as for 8.1.1). I am also willing to help you test it. I request is that you add syntax coloring support for the language Perl 6 (and rename the old support to 'Perl 5'). You can do this incrementally, using Perl 5 as a starting template. For simplicity, don't worry yet about being able to integrate with a Perl 6 runtime in your !# menu, such as for 'Run' or 'Check Syntax'. The actual editing environment updates are much more important. You can get the official word here: http://dev.perl.org/perl6/synopsis/ While Perl 6 file names use the same extensions as Perl 5, such as *.pl and *.pm, it should still be possible to auto-detect Perl 6 if a file starts with a 'class' or 'module' keyword, or the likes of 'use v6;' (see Synopsis 01). Otherwise, users can still choose from the Language sub-menu as before. The most important short term improvements you can make, as I see it, is correct syntax coloring when you do know you are being fed Perl 6, even if it has to be an explicit telling with the Language sub-menu. Within syntax coloring, a lot of details are easy, such as the 'class' or 'method' being keywords like 'package' or 'sub'. These details are of the greatest importance due to the runaway-quote effect of not handling them: 1. The bare '//' and '//=' are now operators like '||' and '||=' but that they test for definedness instead of truth (see Synopsis 03, near the top). BBedit 8.1 under Perl 5 currently treats those as the beginnings of a regexp-quote, which messes up large amounts of code just afterwards to look like string contents that aren't. (Support for this should also be added to the Perl 5 language colorer since Perl 5.9 and 5.10 will add those operators too.) 2. You need to stop treating a leading ':' in a regexp/rule declaration as a delimiter, which likewise leads to runaway quoting; eg, the old 's///g' is now 's:g///' (see Synopsis 05). Such improvements as these will greatly improve my experience in writing Perl 6 with BBEdit. And I am on the team that is developing Perl 6 itself, which is partly functional now and proceeding at a rapid pace thanks to Pugs ( see http://pugscode.org/ ), with large improvements every week. A lot of other Perl 6 developers are also Mac OS X users, and will be able to use your new features immediately. Once again, for simplicity, you can make the Perl 6 colorer as a fork of your Perl 5 one, where everything is the same but when explicitly known different. Thank you in advance for all your hard work. Please reply asap so I know you received this email. -- Darren Duncan
Re: Unknown level of hash
ZL == Zhuang Li [EMAIL PROTECTED] writes: ZL Hi, given an array: @a = ('E1', 'E2', ..., 'En'); ZL Is there an easy way, hopefully one liner, to do the following without a ZL loop? If not, will Perl support this in Perl 6? ZL $hash-{E1}-{E2}-...-{En} = 1; i think perl6 plans to have a way to do this. there is a dim operator to set dimensions. so it would be something like this: %hash{ dim @a } or is $hash has a hash ref: $hash{ dim @a } i cc'ed p6l so i can/will be corrected. uri -- Uri Guttman -- [EMAIL PROTECTED] http://www.stemsystems.com --Perl Consulting, Stem Development, Systems Architecture, Design and Coding- Search or Offer Perl Jobs http://jobs.perl.org
Re: xx and closures
Juerd [EMAIL PROTECTED] writes: I wonder now if that can just be my $password = any('a'..'z') x 5; Wouldn't that generate a junction, and so need a .pick? my $password = (any('a'..'z') x 5).pick; Or perhaps just leave it a junction, to use as a generator: my $any_password = any('a'..'z') x 5; my %password = map { $_ = $any_password.pick } @users; ... or am I missing something? Eirik -- Skill without imagination is craftsmanship and gives us many useful objects such as wickerwork picnic baskets. Imagination without skill gives us modern art. -- Tom Stoppard
Re: .method == $self.method or $_.method?
Larry Wall [EMAIL PROTECTED] writes: I've been thinking about this in my sleep, and at the moment I think I'd rather keep .foo meaning $_.foo, but break the automatic binding of the invocant to $_. Instead of that, I'd like to see a really, really short alias for $self. Suppose we pick o for that, short for object. Then we get self calls of the form: o.frobme(...) I really, really don't want to see .foo meaning anything but $_.foo, so how about arranging things so that the invocant becomes $_ iff you don't give it a name. So: method whatever { # $_ is whatever's invocant } method whosit ($self:) { # $_ is unbound, so: .this # fails ... } Note that this would also work for mappy things with pointy subs used to name arguments. method whatever { map { .this } .list_of_contents; # Works, but is weird... map - $x { .do_something_with($x.result) } # .do_something uses the # method's invocant. } Same applies to given: method foo { given .parent - $p { ... # $_ is foo's invocant } given .parent { ... # $_ is the result of calling .parent } }
Re: return of copies vs references
Darren Duncan [EMAIL PROTECTED] writes: At 11:26 PM -0700 3/16/05, Luke Palmer wrote: For each of the above cases, is a copy of or a reference to the attribute returned? For each, will the calling code be able to modify $obj's attributes by modifying the return values, or not? Well if you're making accessors, why the heck are you making them private? But I can't really answer your question, because it depends on how you write the accessors. I am writing accessors to mediate with the attributes, which are all private, and whose implementation may change over time. What I want, in the normal case, is that calling code which invokes my methods will get a copy of attributes which it can modify, that won't affect the original attribute values. When I last asked a related question here, I was told that simply returning an attribute will allow the caller to modify the original attribute by default. I wanted to make sure this didn't happen. It is possible that there was a misunderstanding regarding the previous question, and the default action is in fact a copy. Doesn't that rather depend on the type of the attribute? Personally, if I get an object back from accessor method then I expect that any modifications of that object's state will be seen the next time I look at the results of that accessor method. This is a direct result of the way reference types work, and the world is a better place because of it. If you want a (deep) copy of the returned object you should say so: my $res = $object.attribute.clone;
Re: S28ish [was: [Pugs] A couple of string interpolation edge cases]
Larry Wall wrote: On Sat, Mar 26, 2005 at 02:37:24PM -0600, Rod Adams wrote: : Please convince me your view works in practice. I'm not seeing it work : well when I attempt to define the relevent parts of S29. But I might : just be dense on this. Well, let's work through an example. multi method substr(Str $s: Ptr $start, PtrDiff ?$len, Str ?$repl) Depending on the typology of Ptr and PtrDiff, we can either coerce various dimensionalities into an appropriate Ptr and PtrDiff type within those classes, or we could rely on MMD to dispatch to a suite of substr implementations with more explicit classes. Interestingly, since Ptrs aren't integers, we might also allow multi method substr(Str $s: Ptr $start, Ptr ?$end, Str ?$repl) which might be a more natural way to deal with variable length encodings, and we just leave the lengthy version in there for old times sake. ...snip... for the non-destructive slicing of a string, and leave substr() with Perl 5 semantics, in which case it's just a SMOP to coerce the user's substr($a, 5, 10); to something the effectively means substr($a, Ptr.new($a, 5, $?UNI_LEVEL), PtrDiff.new(10, $?UNI_LEVEL)); Actually, in this case, I expect we're actually calling into multi method substr(Str $s: PtrDiff $start, PtrDiff ?$len, Str ?$repl) where $start will be counted from the begining of the string, so the call is effectively substr($a, PtrDiff.new(5, $?UNI_LEVEL), PtrDiff.new(10, $?UNI_LEVEL)); 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. I see some danger here. In particular, there is a huge difference between a Ptr (position), and a PtrDiff (length). I'm going to rename these classes StrPos and StrLen for the time being. A StrPos can have multiple char units associated with it, and has the ability morph between them. However, it is also strictly bound to a given string. A StrLen can only have one char unit associated with it, since there is no binding string and anchors with which to reliably map how many cpts there are to so many lchars. I see the following operations being possible at a logical level: StrPos = StrPos + StrLen StrLen = StrPos - StrPos # must specify units (else implied), and must be same base Str StrLen = StrLen + StrLen # if same units. StrLen = StrLen + Int So I see the following cases of Substr happening: multi sub substr(Str $s, StrPos $start : StrPos ?$end, ?$replace) Where $start and $end must be anchored to $s multi sub substr(Str $s, StrPos $start, StrLen $length : ?$replace) Same restriction on $start, multi sub substr(Str $s, StrLen $offset : StrLen ?$length, ?$replace) Where $offset gets used as C$s.start + $offset and kicked over to case #2. Hmm. Okay, that's not dangerous, just a lot to look at. What gets dangerous is letting users think of a StrPos as a number, since it's not. Only StrLen's get to pretend to be numbers. StrPos should have some nifty methods to return StrLen's relative to it's base Str's .start, and those StrLens can look like a number, but the StrPos never gets to ever look like a number. Make it where StrLen does Int, and there's a C«coerce:as(Int,StrLen)» with default units of your Chars as highest supported by string applied to, and I think we're getting somewhere. We need to define what happens to a StrPos when it's base Str goes away. Having it assume some nifty flavor of undef would do the trick. This implies that a Str knows all the StrPos's hanging off it, so the destructor can undef them. But that shouldn't pose a problem for p6c. 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). I don't see the need for all this. Make a C«coerce:as(Int,StrLen)» as mentioned above, and the MMD should be able to figure out that it can take the Int peg and hammer it into the StrLen hole. Then leave it up to the coerce sub to complain if the Int happens
Re: return of copies vs references
At 7:10 AM +0100 3/29/05, Piers Cawley wrote: Doesn't that rather depend on the type of the attribute? Personally, if I get an object back from accessor method then I expect that any modifications of that object's state will be seen the next time I look at the results of that accessor method. This is a direct result of the way reference types work, and the world is a better place because of it. If you want a (deep) copy of the returned object you should say so: my $res = $object.attribute.clone; I recanted what you're replying to last week. Essentially, I agree with you that references of non-scalar values should be returned by default, and that the method must do an explicit copy if that's what they want returned. Things are much simpler that way, and its how Perl 5 worked. -- Darren Duncan
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: Unknown level of hash
Yes. I think it's both useful and fun. I was thinking something similar to @[EMAIL PROTECTED] = map{1} @a; But getting $hash-{E1}-{E2}-...-{En} = 1; instead of $hash{E1} = 1; ... $hash{En} =1;. What I'd really like to do is: Given @a = ('E1', 'E2', ..., 'En'); @b = ('K1', 'K2', ..., 'Km'); @c = ('V1', 'V2', ..., 'Vm'); To get the following in one line: $hash-{E1}-...-{En}-{K1} = 'V1'; $hash-{E1}-...-{En}-{K2} = 'V2'; $hash-{E1}-...-{En}-{Km} = 'Vm'; john -Original Message- From: Jeff Yoak [mailto:[EMAIL PROTECTED] Sent: Monday, March 28, 2005 3:40 PM To: Zhuang Li Cc: fwp@perl.org Subject: Re: Unknown level of hash On Mon, 2005-03-28 at 15:06, Zhuang Li wrote: Hi, given an array: @a = ('E1', 'E2', ..., 'En'); Is there an easy way, hopefully one liner, to do the following without a loop? If not, will Perl support this in Perl 6? $hash-{E1}-{E2}-...-{En} = 1; use Data::Dumper; my @x = qw/a b c d e/; my $h = {}; my $s = join '}-{',@x; eval '$h-{'.$s.'}=1'; print Dumper $h; You asked this on a fun with Perl mailing list, but something about your tone implies that you think this may be a useful, good thing to do rather than simply fun. Please know that I intend this only for fun. :-) Cheers, Jeff