Re: Loop controls
On Fri, Apr 26, 2002 at 08:49:23AM +1000, Damian Conway wrote: > for $results.get_next() { > FIRST { print "Results:"; } > NEXT { print ""; } > LAST { print "Done."; } > print $_; > } How about something like this: for $results.each() { print "Results:" if $results.first; print $_; print $results.last ? "Done." : ""; } or perhaps foreach $item ($results.each) { print "Results:" if $item.first; print $_; print $item.last ? "Done." : ""; } Calling each() on a list (or a hash?) should somehow transmogrigfy it, or provide an attribute interface around it, which makes it look more like a classic iterator. The psuedo-iterator can implement methods like first(), last(), index(), count(), size(), max() and so on for providing information about, and control over loops. This is an approach I've used to great effect in the Template Toolkit. In this case, the iterator controlling a 'FOREACH' loop is aliased to the 'loop' variable [% FOREACH x = y %] [% "\n" IF loop.first %] [% loop.count %] [% x.key %] [% x.val %] [% "\n" IF loop.last %] [% END %] Builtin support for iterators can make difficult things easy. Ruby's implementation is worth a look for inspiration (as indeed is most of the Ruby language :-) A
Re: Loop controls
At Fri, 26 Apr 2002 09:40:14 +0100, Andy Wardley wrote: > This is an approach I've used to great effect in the Template Toolkit. > In this case, the iterator controlling a 'FOREACH' loop is aliased to > the 'loop' variable > >[% FOREACH x = y %] > [% "\n" IF loop.first %] > > [% loop.count %] > [% x.key %] > [% x.val %] > > [% "\n" IF loop.last %] >[% END %] > > Builtin support for iterators can make difficult things easy. Ruby's > implementation is worth a look for inspiration (as indeed is most of the > Ruby language :-) Have you looked through Inline::TT, a mad hack by me? I suppose you'll find it interesting! ;) http://perlmonks.org/index.pl?node_id=162123 -- Tatsuhiko Miyagawa <[EMAIL PROTECTED]>
Re: Loop controls
On Thu, 2002-04-25 at 18:20, Damian Conway wrote: > Miko O'Sullivan wrote: > > before { ... } # run before first iteration, > > # only if there is at least one iteration > > Larry is still considering allowing a C block that would do this. [...] > This will be called a C block. It goes inside the loop block. [...] > This will be called a C block. It goes inside the loop block. [...] > C blocks to accomplish this. This bothers me. Traditionally, all-caps keywords in Perl have indicated compile-time constructs that may relate only loosely to the code around them (e.g. BEGIN, END). Why would these keywords need to be set off in this fashion? Is there something dangerous about: for @x->$y { first { ... } ... next { ... } last { ... } } else { ... } I can see next and last being confusing, and you might want to choose other keywords, but making them upper-case doesn't really eliminate the confusion. Also, first is perhaps a poor keyword itself. What about this case: for @x->$y { if (defined $y) { first { ... } } } Does that work?
Re: Loop controls
On Fri, Apr 26, 2002 at 10:29:58AM -0400, Aaron Sherman wrote: > On Thu, 2002-04-25 at 18:20, Damian Conway wrote: > > Miko O'Sullivan wrote: > > > > before { ... } # run before first iteration, > > > # only if there is at least one iteration > > > > Larry is still considering allowing a C block that would do this. > [...] > > This will be called a C block. It goes inside the loop block. > [...] > > This will be called a C block. It goes inside the loop block. > [...] > > C blocks to accomplish this. > > This bothers me. Traditionally, all-caps keywords in Perl have indicated > compile-time constructs that may relate only loosely to the code around > them (e.g. BEGIN, END). Actually all-caps keywords in Perl have indicated code blocks that perl will call implicitly: TIEHASH TIEARRAY STORE FETCH etc Which seems to fit well enough with the perl6 usage. Tim.
Re: Please rename 'but' to 'has'.
At 2:26 PM +0100 4/26/02, Nicholas Clark wrote: >On Tue, Apr 23, 2002 at 01:25:15PM -0400, Dan Sugalski wrote: >> At 12:36 PM -0400 4/23/02, Buddha Buck wrote: >> >OK, but that limits you to the, um, 24 standard levels of >> >precedence. What do you do if you don't think that that's enough >> >> Internally precedence is going to be stored as a floating-point >> number. Dunno how it'll be exposed at the language level, but at >> least there'll be more than just 20 or so levels. > >Why store precedence as floating point rather than integer? >[Or did I miss a design document} Because, while you may run into problems fitting something in between 1.001 and 1.002, it's not a problem to fit something between 3 and 4. Floating point precedence is a problem at the edge, but integer precedence makes things potentially difficult for user-added operators if you want to fit things between the standard operators. -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Please rename 'but' to 'has'.
On Fri, Apr 26, 2002 at 11:33:06AM -0400, Dan Sugalski wrote: > At 2:26 PM +0100 4/26/02, Nicholas Clark wrote: > >On Tue, Apr 23, 2002 at 01:25:15PM -0400, Dan Sugalski wrote: > >> At 12:36 PM -0400 4/23/02, Buddha Buck wrote: > >> >OK, but that limits you to the, um, 24 standard levels of > >> >precedence. What do you do if you don't think that that's enough > >> > >> Internally precedence is going to be stored as a floating-point > >> number. Dunno how it'll be exposed at the language level, but at > >> least there'll be more than just 20 or so levels. > > > >Why store precedence as floating point rather than integer? > >[Or did I miss a design document} > > Because, while you may run into problems fitting something in between > 1.001 and 1.002, it's not a problem to fit something between > 3 and 4. Floating point precedence is a problem at the edge, but > integer precedence makes things potentially difficult for user-added > operators if you want to fit things between the standard operators. Is it worth it? For perl at least I thought Larry has said that you'll be able to create new ops but only give them the same precedence as any one of the existing ops. Why not use a 16 bit int and specify that languages should use default precedence levels spread through the range but keeping the bottom 8 bits all zero. That gives 255 levels between '3' and '4'. Seems like enough to me! Floating point seems like over-egging the omelette. Tim. p.s. I missed the start of this thread so I'm not sure why this is a parrot issue rather than a language one. I also probably don't know what I'm talking about :)
Re: Loop controls
On Fri, Apr 26, 2002 at 08:49:23AM +1000, Damian Conway wrote: > Trey Harris wrote: > > > So: > > > > for $results.get_next() { > > FIRST { print "Results:"; } > > NEXT { print ""; } > > } else { > > print "No results."; > > } > > > > Do I have that right? > > Yes. Presuming Larry decides in favour of C and C. Hmmm... how about: for $results.get_next() { print $_; LAST { print "Done."; } ELSE { print "No results."; } } The "else" of a loop construct isn't really the same as the "else" of an C. You can't use an C for one thing. And the condition for reaching the "else" is different too, it isn't always a "false value", sometimes it's "no values to iterate over" or "condition met before first execution of loop". This syntax makes the difference pretty obvious, and fits in nicely with the other NAMED blocks ("Alphabet Blocks" :). I can also think of some advantages to having the "else" within the scope of the loop. You might want your object to return a "false" value from .get_next() (one that C will see as non-iterate-able) but that still contains some interesting properties that can be used by the "else". If the "else" followed the loop this value wouldn't be in scope. This presumes that the value would still be topicalized/aliased even when it wasn't iteratable. Perhaps this makes the most sense with a C, where it is simply testing for truth. method get_next { ... return "xyz572" but false if $something; ... } ... while $result.get_next() -> $next { # do something with $next... ELSE { if $next eq "xyz572" { print "We defined this value, $next, as false for obscure purposes."; print "No loop was executed. Just wanted to let you know."; } } } Hmmm... this leads me to wonder if we wouldn't perhaps have a use for an "elsif" on loops afterall, for actions we want to execute only when the the loop doesn't execute and another condition is true: for $result.get_next() -> $next { print $next; ELSEIF $result.weird() { print "I meant to do that."; } } Allison
Re: Please rename 'but' to 'has'.
> This is now extensible to any number of precedence levels, and you can > now use simple string comparison to compare any two precedences. It even > short circuits the comparison as soon as it finds a character that > differs. > > Gee, maybe I should patent this. Too late. Amazon has already patented the concept of string comparisons. Microsoft is in litigation over the number "2". -Miko
Re: Please rename 'but' to 'has'.
At 5:05 PM +0100 4/26/02, Tim Bunce wrote: >On Fri, Apr 26, 2002 at 11:33:06AM -0400, Dan Sugalski wrote: >> At 2:26 PM +0100 4/26/02, Nicholas Clark wrote: >> >On Tue, Apr 23, 2002 at 01:25:15PM -0400, Dan Sugalski wrote: >> >> At 12:36 PM -0400 4/23/02, Buddha Buck wrote: >> >> >OK, but that limits you to the, um, 24 standard levels of >> >> >precedence. What do you do if you don't think that that's enough >> >> >> >> Internally precedence is going to be stored as a floating-point >> >> number. Dunno how it'll be exposed at the language level, but at >> >> least there'll be more than just 20 or so levels. >> > >> >Why store precedence as floating point rather than integer? >> >[Or did I miss a design document} >> >> Because, while you may run into problems fitting something in between >> 1.001 and 1.002, it's not a problem to fit something between >> 3 and 4. Floating point precedence is a problem at the edge, but >> integer precedence makes things potentially difficult for user-added >> operators if you want to fit things between the standard operators. > >Is it worth it? I think so, yes. >For perl at least I thought Larry has said that you'll be able to >create new ops but only give them the same precedence as any one >of the existing ops. Don't recall that, though all decisions are subject to later revision. Still, it doesn't have to be exposed either. :) >Why not use a 16 bit int and specify that languages should use >default precedence levels spread through the range but keeping the >bottom 8 bits all zero. That gives 255 levels between '3' and '4'. >Seems like enough to me! If we're going that route, we've essentially edged over into reals of some sort, at which point we might as well just make it a float. >p.s. I missed the start of this thread so I'm not sure why this is >a parrot issue rather than a language one. It's a parrot issue in that it'll be welded into the parser part when the parser builds up its operator precedence table. >I also probably don't know what I'm talking about :) I'll believe that the first time I see it actually happen... ;-P -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Please rename 'but' to 'has'.
Tim Bunce writes: : For perl at least I thought Larry has said that you'll be able to : create new ops but only give them the same precedence as any one : of the existing ops. Close, but not quite. What I think I said was that you can't specify a raw precedence--you can only specify a precedence relative to an existing operator. That way it doesn't matter what the initial precedence assignments are. We can always change them internally. : Why not use a 16 bit int and specify that languages should use : default precedence levels spread through the range but keeping the : bottom 8 bits all zero. That gives 255 levels between '3' and '4'. : Seems like enough to me! : : Floating point seems like over-egging the omelette. It's also under-egging the omelette, and not just because you eventually run out of bits. I don't think either integer or floating point is the best solution, because in either case you have to remember separately how many levels of derivation from the standard precedence levels you are, so you know which bit to flip, or which increment to add or subtract from the floater. In an approach vaguely reminscent of surreal numbers, I'd just use a string that does trinary ordering. Suppose you have 26 initial precedence levels. Call these A-Z. Subsequent characters can just be 0-2. Skip A for the moment, call the lowest precedence level B, the next lowest C, and so on. * To make a new operator at the same precedence, simply copy the base precedence string. * To make a new operator at a higher precedence level, copy the base precedence and append a "1" to it. * To make a new operator at a lower precedence level, copy the base precedence, decrement the last character (that's why we skipped A) and append a "2". This is now extensible to any number of precedence levels, and you can now use simple string comparison to compare any two precedences. It even short circuits the comparison as soon as it finds a character that differs. Gee, maybe I should patent this. : p.s. I missed the start of this thread so I'm not sure why this is : a parrot issue rather than a language one. I also probably don't : know what I'm talking about :) It's a language issue insofar as the language specifies that the implementation should avoid arbitrary limits. Larry
Re: Please rename 'but' to 'has'.
At 09:45 AM 04-26-2002 -0700, Larry Wall wrote: >Tim Bunce writes: >: For perl at least I thought Larry has said that you'll be able to >: create new ops but only give them the same precedence as any one >: of the existing ops. > >Close, but not quite. What I think I said was that you can't specify >a raw precedence--you can only specify a precedence relative to an >existing operator. That way it doesn't matter what the initial >precedence assignments are. We can always change them internally. > >: Why not use a 16 bit int and specify that languages should use >: default precedence levels spread through the range but keeping the >: bottom 8 bits all zero. That gives 255 levels between '3' and '4'. >: Seems like enough to me! >: >: Floating point seems like over-egging the omelette. > >It's also under-egging the omelette, and not just because you >eventually run out of bits. I don't think either integer or floating >point is the best solution, because in either case you have to remember >separately how many levels of derivation from the standard precedence >levels you are, so you know which bit to flip, or which increment to >add or subtract from the floater. So you'd have something like: sub operator:mult($a, $b) is looser('*') is inline {...} sub operator:add($a, $b) is tighter("+") is inline {...} sub operator:div($a,$b) is looser("/") is inline {...} assuming default Perl5 precedences for *, *, and / you would have the precedence strings for *, +, /, mult, add, and div to be "S", "R", "S", "S2", "S1", "S2" respectively? So mult and div would have the same precedences? Hmmm What problems would be caused by: sub operator:radd($a,$b) is tighter("+") is inline is rightassociative {...} sub operator:ladd($a,$b) is tighter("+") is inline is leftassociative {...} Right now, all the operator precedence levels in Perl5 have either right, left, or no associativity, but they do not mix right and left associative operators. Will that be allowed in Perl6? >Larry
Re: Please rename 'but' to 'has'.
Buddha Buck writes: : So you'd have something like: : : sub operator:mult($a, $b) is looser('*') is inline {...} : sub operator:add($a, $b) is tighter("+") is inline {...} : sub operator:div($a,$b) is looser("/") is inline {...} : : assuming default Perl5 precedences for *, *, and / you would have the : precedence strings for *, +, /, mult, add, and div to be "S", "R", "S", : "S2", "S1", "S2" respectively? So mult and div would have the same : precedences? Yes. This seems the most sensical approach to me. If you base two operators on the same precedence level with the same pedigree, they should have the the same precedence. One can always differentiate them explicitly. I could even see people setting up a system of "virtual" operators that are just there for deriving precedence from, so you could have 20 standard levels of precedence between * and + if you wanted. sub operator:PREC1($a, $b) is tighter('+') {...} sub operator:PREC2($a, $b) is tighter('PREC1') {...} sub operator:PREC3($a, $b) is tighter('PREC2') {...} ... sub operator:funky($a, $b) is like("PREC13") { ... } : Hmmm What problems would be caused by: : : sub operator:radd($a,$b) is tighter("+") is inline is rightassociative {...} : sub operator:ladd($a,$b) is tighter("+") is inline is leftassociative {...} : : Right now, all the operator precedence levels in Perl5 have either right, : left, or no associativity, but they do not mix right and left associative : operators. Will that be allowed in Perl6? Well, associativity is mostly just a tie-breaking rule, so we'd just want to refine the tie-breaking rule to say what happens in that case. It's possible the right thing to do is to treat conflicting associativity as non-associative, and force parentheses. Larry
Re: Please rename 'but' to 'has'.
Larry Wall <[EMAIL PROTECTED]> writes: > : Why not use a 16 bit int and specify that languages should use > : default precedence levels spread through the range but keeping the > : bottom 8 bits all zero. That gives 255 levels between '3' and '4'. > : Seems like enough to me! > : > : Floating point seems like over-egging the omelette. > > It's also under-egging the omelette, and not just because you > eventually run out of bits. I don't think either integer or floating > point is the best solution, because in either case you have to remember > separately how many levels of derivation from the standard precedence > levels you are, so you know which bit to flip, or which increment to > add or subtract from the floater. On this subject, has it been considered doing it the Cecil way? http://www.cs.washington.edu/research/projects/cecil/www/Release/doc-cecil-lang/cecil-spec-37.html (no numbered priorities, but a partial-order relation on operators) -- Pixel programming languages addict http://merd.net/pixel/language-study/
Re: Loop controls
On Fri, 2002-04-26 at 14:11, Allison Randal wrote: > On Fri, Apr 26, 2002 at 08:49:23AM +1000, Damian Conway wrote: > Hmmm... how about: > > for $results.get_next() { > print $_; > LAST { print "Done."; } > ELSE { print "No results."; } > } > > The "else" of a loop construct isn't really the same as the "else" of an > C. You can't use an C for one thing. And the condition for Why not? What would be wrong with: for @x { ... } elsif (stuff) { ... } else { ... } Of course it brings other less wholesome things to mind like "elsfor" and "elsloop" and "if ... elsfor" and "for ... elsif ... elsloop ... else", but why not? > reaching the "else" is different too, it isn't always a "false value", Yes it is. > sometimes it's "no values to iterate over" or "condition met before > first execution of loop". while(@x) { ... } / if (@x) { ... } while($x) { ... } / if ($x) { ... } These are different how? To my eye, the only difference is what happens at the end of the block. In fact, while ($x) { ... ; last; } is an if. > I can also think of some advantages to having the "else" within the > scope of the loop. You might want your object to return a "false" value > from .get_next() (one that C will see as non-iterate-able) but that > still contains some interesting properties that can be used by the > "else". If the "else" followed the loop this value wouldn't be in scope. This is something I had not considered, but sounds very cool. sub alllines ($file) { my $fh; if ($fh = IO::File->new("<$file")) { return $fh->getlines; } else { return $! but false; } } while alllines("/etc/passwd") -> $_ { ... } else { die "/etc/passwd: $_"; } Yeah... I like it.
Re: Loop controls
On Fri, Apr 26, 2002 at 05:24:13PM -0400, Aaron Sherman wrote: > On Fri, 2002-04-26 at 14:11, Allison Randal wrote: > > The "else" of a loop construct isn't really the same as the "else" of an > > C. You can't use an C for one thing. > > Why not? What would be wrong with: > > for @x { > ... > } elsif (stuff) { > ... > } else { > ... > } Nothing's wrong with it exactly... It could be valid syntax. It seems semantically odd though. > Of course it brings other less wholesome things to mind like "elsfor" > and "elsloop" and "if ... elsfor" and "for ... elsif ... elsloop ... > else", but why not? Urk. And why? Besides, I would expect an C to actually be a loop of it's own, on the principle of "elsif = else + if" so "elsfor = else + for". > > And the condition for reaching the "else" is different too, it isn't > > always a "false value", > > Yes it is. > > > sometimes it's "no values to iterate over" or "condition met before > > first execution of loop". > > while(@x) { ... } / if (@x) { ... } > while($x) { ... } / if ($x) { ... } > > These are different how? To my eye, the only difference is what happens > at the end of the block. In fact, > > while ($x) { ... ; last; } > > is an if. Yes, but there's a difference with C in that you wouldn't want an "else" to execute anytime the C came across a false value, but only if the *first* value it came across was false (i.e. only if the loop isn't going to execute at all). Otherwise, you'd just use a LAST block (a parallel that I think argues for ELSE blocks). And C and C are even more different. You could kind of stretch the point and say that the evaluation of the second expression is the false value, I'll give you that. But it still has the same problem as C. $i = $somevalue; # possibly set by user input to 5 or higher ... loop ; $i < 5; $i++ { ... } And where's the "false value" here? The "else" would be more of "no values to iterate over". for @names -> $name { ... } > > I can also think of some advantages to having the "else" within the > > scope of the loop. > > while alllines("/etc/passwd") -> $_ { > ... > } else { > die "/etc/passwd: $_"; > } But the aliased value, $_, is restricted to the scope of the C's block, it isn't going to be accessible in the block associated with the C (you would be getting some $_ from an outer scope). We could create exceptions to the scoping rules that would make it possible. But part of the point in getting rid of C was to avoid funky exceptions for code blocks dangling off the end of loops. Allison
Re: Loop controls
> Of course it brings other less wholesome things to mind like "elsfor" > and "elsloop" and "if ... elsfor" and "for ... elsif ... elsloop ... > else", but why not? Well, I agree with the concept, but boyoboy those names ain't gonna fly. We'll have to head down the road of unlessfor elseuntil unlessuntil Two issues spring to mind: 1) Do we have a reality check on why this syntax is needed? I agree it's cool idea, but can anyone name a real-world scenario where it would be useful? Can we do things just bcause they're cool? That approach didn't work too well for me as a teenager, but then nothing else did either. 2) Could we come up with a generic syntax? Some simple that allows for any combination? -Miko
Re: Loop controls
On Fri, 26 Apr 2002, Allison Randal wrote: > Besides, I would expect an C to actually be a loop of it's own, > on the principle of "elsif = else + if" so "elsfor = else + for". So, you're suggesting we add C then? Just because it's possible doesn't mean it's necessary. Luke
Re: Loop controls
On Fri, Apr 26, 2002 at 11:14:36PM -0600, Luke Palmer wrote: > On Fri, 26 Apr 2002, Allison Randal wrote: > > > Besides, I would expect an C to actually be a loop of it's own, > > on the principle of "elsif = else + if" so "elsfor = else + for". > > So, you're suggesting we add C then? Just because it's > possible doesn't mean it's necessary. I'd say it's not only unnecessary, but undesireable. Hence the "Urk". The standard: else { for @whatever { } } Seems plenty adequate to the task. And more readable. Allison