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 %]
   [% table\n IF loop.first %]
   tr
 td[% loop.count %]/td
 td[% x.key %]/td
 td[% x.val %]/td
   /tr
   [% /table\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 CFIRST block that would do this.
[...]
 This will be called a CNEXT block. It goes inside the loop block.
[...]
 This will be called a CLAST block. It goes inside the loop block.
[...]
 Celse 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 CFIRST block that would do this.
 [...]
  This will be called a CNEXT block. It goes inside the loop block.
 [...]
  This will be called a CLAST block. It goes inside the loop block.
 [...]
  Celse 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:BR; }
NEXT { print HR; }
  } else {
print No results.;
  }
  
  Do I have that right?
 
 Yes. Presuming Larry decides in favour of CFIRST and Celse.

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
Cif. You can't use an Celsif 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 Cfor 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
Cwhile, 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.

snip

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
 Cif. You can't use an Celsif 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 Cfor 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
  Cif. You can't use an Celsif 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 Celsfor 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 Cwhile in that you wouldn't want an
else to execute anytime the Cwhile 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 Cfor and Cloop 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 Cwhile.

  $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 Cwhile's
block, it isn't going to be accessible in the block associated with the
Celse (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 Ccontinue 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 Celsfor 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 Celsunless 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 Celsfor 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 Celsunless 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