Re: Loop controls

2002-04-26 Thread Andy Wardley

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

2002-04-26 Thread Tatsuhiko Miyagawa

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

2002-04-26 Thread Aaron Sherman

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

2002-04-26 Thread Tim Bunce

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'.

2002-04-26 Thread Dan Sugalski

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'.

2002-04-26 Thread Tim Bunce

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

2002-04-26 Thread Allison Randal

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'.

2002-04-26 Thread Miko O'Sullivan

> 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'.

2002-04-26 Thread Dan Sugalski

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'.

2002-04-26 Thread Larry Wall

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'.

2002-04-26 Thread Buddha Buck

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'.

2002-04-26 Thread Larry Wall

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'.

2002-04-26 Thread Pixel

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

2002-04-26 Thread Aaron Sherman

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

2002-04-26 Thread Allison Randal

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

2002-04-26 Thread Miko O'Sullivan

> 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

2002-04-26 Thread Luke Palmer

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

2002-04-26 Thread Allison Randal

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