Re: syntax: multi vs. method

2003-11-18 Thread Luke Palmer
Jonathan Lang writes:
 My apologies for the break in the chain of responses; I lost your reply
 before I could reply to it, and had to retrieve it from the list archives.
  
 
 Luke Palmer wrote:
  Well, multi is no longer a declarator in its own right, but rather a
  modifier.  Synopsis  Exegesis 6 show this.  
 
 I don't know about Exegesis 6, 

Then you should probably read it.  It is the most recent of the
documents, so what it says is closest to the current thinking. Plus,
it's a fun read.

 but Synopsis 6 (http://dev.perl.org/perl6/synopsis/S06.html) is still
 showing multi to be a declarator on par with sub, method, rule, and
 macro.  

Now that I look, yes, that's true.  It's wrong.

  I think this makes things even clearer, and has a fine-grained but
  elegant control over the scope of the routine.
 
 Agreed; I'd like something like this to be implemented.  
 
  This easily allows for multisubmethods and even multimacros
  (provided you have yourself a polymorphic object at compile time).
 
 For the record, subs never have invocants as currently described - so you
 could easily say that any sub that has an invocant is actually a
 submethod:
 
sub touch ($a: $b) {...}
 
 would be synonymous with:
 
submethod touch ($a: $b) {...}

Hmm.  Well, that depends on whether calling works like it does in Perl
5.  That is, given:

multi sub touch (Foo $a: $b) {...}

Is this legal:

my $x = new Foo;
$x.touch;

I haven't been able to deduce this.

  I also think it's important to say multi explicitly every time you
  mean it.  It allows the compiler to warn you when you're just being
  stupid about scoping as opposed to actually wanting to overload the
  routine.  From a design perspective, it makes it clear that this method
  introduces logical control-flow in addition to performing a task.
 
 That's probably good programming advice; but it should remain advice
 rather than being a requirement.  

Spoken like a true Perl programmer :-)

I don't see the win in losing the Cmulti keyword though.  Sure, there
are 5 fewer characters, but declarations aren't a place where concise
and terse are synonymous.  IMO, a colon is too small a character for
such a large distinction.  Misunderstanding the rule slightly can lead
to overriding instead of overloading...  reminds me of C++ [1].

 If you allow the distinction between a method and a multimethod to be
 determined implicitly, you can, if you choose, ignore the submethod and
 multi keywords altogether with minimal loss of capabilities: 
 
submethod touch ($a) {...}
multi watch ($a, $b) {...}
 
 would be equivelent to
 
sub touch ($_: $a) {...}
method watch ($a, $b:) {...}

Luke

[1]  While I haven't the hatred for C++ that quite a few people on this
list do, I definitely consider it an advanced language, by which I
mean there are subtle variants in the rules that cause wildy different
behaviors.  Beginners (and intermediates) still struggle with this one:

class Base { 
public:  
virtual int num() const { return 10; } 
}

class Derived : public Base {
public: 
int num() { return 20; }
}

int main() {
Base* b = new Base;  Base* d = new Derived;
cout  b-num()  endl;  // 10
cout  d-num()  endl;  // 10 !!
}

Now why the heck did the call to d-num() return 10??!!!  Because they
missed a Cconst in the overriding of num(), hiding it instead.  This
is precisely what would happen if you missed a colon in adding a
multimethod.  Sorry, I don't want to inflict this kind of pain on Perl
programmers.



Control flow variables

2003-11-18 Thread Luke Palmer
I was reading the most recent article on perl.com, and a code segment
reminded me of something I see rather often in code that I don't like.
Here's the code, Perl6ized:

... ;
my $is_ok = 1;
for 0..6 - $t {
if abs(@new[$t] - @new[$t+1])  3 {
$is_ok = 0;
last;
}
}
if $is_ok {
push @moves: [$i, $j];
}
...

I see this idiom a lot in code.  You loop through some values on a
condition, and do something only if the condition was never true.
$is_ok is a control flow variable, something I like to minimize.  Now,
there are other ways to do this:

if (0..6 == grep - $t { abs(@new[$t] - @new[$t+1]) })
{ ... }

But one would say that's not the cleanest thing in the world.

Python pulled this idiom out in to the syntax (yay them), with Celse
on loops.  The else block on a python loop executes only if you never
broke out of the loop.  That's a great idea.

So, in Perl's postmodern tradition, I think we should steal that idea.
I'm a little uneasy about calling it Celse, though.  Maybe CFINISH
would do, making the example:

for 0..6 - $t {
if abs(@new[$t] - @new[$t+1])  3 {
last;
}
FINISH { 
push @moves: [$i, $j];
}
}

I'd also like to say that while converting the rest of this sub to Perl
6, I realized how much I love the ..^ and ^.. operators.  I was
wondering whether people had forgotten about them :-). 

Luke


Re: Control flow variables

2003-11-18 Thread Simon Cozens
[EMAIL PROTECTED] (Luke Palmer) writes:
 I was reading the most recent article on perl.com, and a code segment
 reminded me of something I see rather often in code that I don't like.

The code in question got me thinking too; I wanted to find a cleaner
way to write it, but didn't see one.

 So, in Perl's postmodern tradition, I think we should steal that idea.

I agree, but (as usual) would like to consider whether there's a way
to solve a general problem rather than solving a specific problem by
throwing additional syntax at it. (which sadly seems to be fast becoming
the Perl 6 way)

Given that we've introduced the concept of if having a return status:

  my $result = if ($a) { $a } else { $b };

Then why not extend this concept and have a return status from other
control structures?

  for 0..6 - $t { 
last if abs(@new[$t] - @new[$t+1])  3;
  } or push @moves: [$i, $j];

Of course, these things have consequences; I'm not sure whether we really
want people saying

  push @moves:[$i, $j] unless last if abs(@[EMAIL PROTECTED])3 for 0..6;

-- 
The course of true anything never does run smooth.
-- Samuel Butler


Re: Control flow variables

2003-11-18 Thread Luke Palmer
Simon Cozens writes:
 [EMAIL PROTECTED] (Luke Palmer) writes:
  I was reading the most recent article on perl.com, and a code segment
  reminded me of something I see rather often in code that I don't like.
 
 The code in question got me thinking too; I wanted to find a cleaner
 way to write it, but didn't see one.
 
  So, in Perl's postmodern tradition, I think we should steal that idea.
 
 I agree, but (as usual) would like to consider whether there's a way
 to solve a general problem rather than solving a specific problem by
 throwing additional syntax at it. (which sadly seems to be fast becoming
 the Perl 6 way)

Well... it is and isn't.  At first sight, it makes the language look
huge, the parser complex, a lot of syntax to master, etc.  It also seems
to me that there is little discrimination when adding new syntax. 

But I've come to look at it another way.  Perl 6 is doing something
(many things, really) that no other language has done before: making it
very easy to add new syntax to the language.

So modules that introduce new concepts into the language can add new
syntax for them without working with (ugh) a source filter.  And some of
these new syntaxes in the core language will actually be in standard
modules, if they're not commonly used.  Just like traits.

But even when they're not, Perl is a generic, multiparadigm language.
It covers and supports many concepts, and new concepts grafted onto an
existing but unfit syntax make things harder.  Humans are pretty good at
syntax.  Many times mathematicians make up new syntax when they
introduce a new concept: making it easier to think about, and easier to
recognize.

I'll also point out that FINISH isn't really extra syntax, just extra
vocabulary.

 Given that we've introduced the concept of if having a return status:
 
   my $result = if ($a) { $a } else { $b };

Ack!  We have?  It does make sense if we want to be able to implement
Cif as a regular sub... I guess.  Yuck.

 Then why not extend this concept and have a return status from other
 control structures?
 
   for 0..6 - $t { 
 last if abs(@new[$t] - @new[$t+1])  3;
   } or push @moves: [$i, $j];
 
 Of course, these things have consequences; I'm not sure whether we really
 want people saying
 
   push @moves:[$i, $j] unless last if abs(@[EMAIL PROTECTED])3 for 0..6;

That's illegal anyway.  Can't chain statement modifiers :-)

But a close relative would be possible:

push @moves: [$i, $j] unless for 0..6 { last if abs(@[EMAIL PROTECTED])  3 }

Yeah, how about no.  :-)

Luke



Re: Control flow variables

2003-11-18 Thread Simon Cozens
Luke Palmer:
 Well... it is and isn't.  At first sight, it makes the language look
 huge, the parser complex, a lot of syntax to master, etc.  It also seems
 to me that there is little discrimination when adding new syntax. 

Correct.

 But I've come to look at it another way.  Perl 6 is doing something
 (many things, really) that no other language has done before: making it
 very easy to add new syntax to the language.

Well, that's hardly a new concept for a programming language.

 So modules that introduce new concepts into the language can add new
 syntax for them without working with (ugh) a source filter.  And some of
 these new syntaxes in the core language will actually be in standard
 modules, if they're not commonly used.  Just like traits.

This is good. This is what I like to hear. This is why the answer to
all these stupid syntax questions should be Look, if you need it, just put it
in a module when we're done. But can we please get on with getting Perl 6 
designed and out the door, now?

But it isn't, and I don't know why it isn't, and so we end up spending loads
of time discussing things that can be punted out to modules. Designing Perl 6
is hard enough; let's not try to fill CP6AN at the same time.

 I'll also point out that FINISH isn't really extra syntax, just extra
 vocabulary.

It's extra special cases, which come to the same thing.

my $result = if ($a) { $a } else { $b };
 
 Ack!  We have?  It does make sense if we want to be able to implement
 Cif as a regular sub... I guess.  Yuck.

Yep, we did. Of course, the nice thing about it is that it allows

do_thing() if if ($a) { $b } else { $c };

 That's illegal anyway.  Can't chain statement modifiers :-)

Bah, should be able to!

 But a close relative would be possible:
 push @moves: [$i, $j] unless for 0..6 { last if abs(@[EMAIL PROTECTED])  3 }
 
 Yeah, how about no.  :-)

That's the thing, see. By saying no, we're saying control structures like
'if' will be able to return a value, but control structures not like 'if'
won't, and that means we need to remove at least three words from 'When syntax
or semantics change, it will always be a change for the better: for greater
consistency, for more intuitability, for extra Do-What-I-Meanness.'... ;)

-- 
Resist the urge to start typing; thinking is a worthwhile alternative.
-- Kernighan and Pike


Re: Control flow variables

2003-11-18 Thread Dan Sugalski
On Tue, 18 Nov 2003, Simon Cozens wrote:

 Luke Palmer:

  That's illegal anyway.  Can't chain statement modifiers :-)

 Bah, should be able to!

Will be able to.

Dan

--it's like this---
Dan Sugalski  even samurai
[EMAIL PROTECTED] have teddy bears and even
  teddy bears get drunk



Re: Control flow variables

2003-11-18 Thread Simon Cozens
[EMAIL PROTECTED] (Dan Sugalski) writes:
  Luke Palmer:
   That's illegal anyway.  Can't chain statement modifiers :-)
 Will be able to.

I thought as much; Perl 6 will only be finally finished when the biotech
is sufficiently advanced to massively clone Larry...

-- 
quidity Sometimes it's better not to pedant.


RE: Control flow variables

2003-11-18 Thread Austin Hastings


 -Original Message-
 From: Luke Palmer [mailto:[EMAIL PROTECTED]
 Sent: Tuesday, November 18, 2003 9:21 AM
 To: Language List
 Subject: Control flow variables
 
 
 I was reading the most recent article on perl.com, and a code segment
 reminded me of something I see rather often in code that I don't like.
 Here's the code, Perl6ized:
 
 ... ;
 my $is_ok = 1;
 for 0..6 - $t {
 if abs(@new[$t] - @new[$t+1])  3 {
 $is_ok = 0;
 last;
 }
 }
 if $is_ok {
 push @moves: [$i, $j];
 }
 ...

This is what I was talking about when I mentioned being able to do:

  cleanup .= { push @moves: [$i, $j]; }

a few weeks ago. Treat code vars like code, not like sub-refs.

=Austin



Re: Control flow variables

2003-11-18 Thread Luke Palmer
Austin Hastings writes:
 Luke Palmer wrote: 
  I was reading the most recent article on perl.com, and a code segment
  reminded me of something I see rather often in code that I don't like.
  Here's the code, Perl6ized:
  
  ... ;
  my $is_ok = 1;
  for 0..6 - $t {
  if abs(@new[$t] - @new[$t+1])  3 {
  $is_ok = 0;
  last;
  }
  }
  if $is_ok {
  push @moves: [$i, $j];
  }
  ...
 
 This is what I was talking about when I mentioned being able to do:
 
   cleanup .= { push @moves: [$i, $j]; }
 
 a few weeks ago. Treat code vars like code, not like sub-refs.

I'm not sure I know what you mean with regard to this example.
Exemplify further, please?

Luke

 =Austin
 


Re: Control flow variables

2003-11-18 Thread Dan Sugalski
On Tue, 18 Nov 2003, Simon Cozens wrote:

 [EMAIL PROTECTED] (Dan Sugalski) writes:
   Luke Palmer:
That's illegal anyway.  Can't chain statement modifiers :-)
  Will be able to.

 I thought as much; Perl 6 will only be finally finished when the biotech
 is sufficiently advanced to massively clone Larry...

Not because of this. It's easier to allow it than not allow it.

Dan

--it's like this---
Dan Sugalski  even samurai
[EMAIL PROTECTED] have teddy bears and even
  teddy bears get drunk



Re: Control flow variables

2003-11-18 Thread Simon Cozens
[EMAIL PROTECTED] (Austin Hastings) writes:
 This is what I was talking about when I mentioned being able to do:
   cleanup .= { push @moves: [$i, $j]; }

This reminds me of something I thought the other day might be useful:

$cleanup = bless {}, class { 
method DESTROY { ... }
};

Of course, it probably wouldn't work in this context because you couldn't
guarantee that the destructor will be called at the point of loop exit, but I
like the anonymous class syntax anyway.

-- 
I've looked at the listing, and it's right!
-- Joel Halpern


Re: Control flow variables

2003-11-18 Thread Dan Sugalski
On Tue, 18 Nov 2003, Simon Cozens wrote:

 [EMAIL PROTECTED] (Austin Hastings) writes:
  This is what I was talking about when I mentioned being able to do:
cleanup .= { push @moves: [$i, $j]; }

 This reminds me of something I thought the other day might be useful:

 $cleanup = bless {}, class {
 method DESTROY { ... }
 };

 Of course, it probably wouldn't work in this context because you couldn't
 guarantee that the destructor will be called at the point of loop exit, but I
 like the anonymous class syntax anyway.

 $cleanup = bless {}, class : impatient {
 method DESTROY { ... }
 };

That'll probably do it, at the expense of extra runtime block exit
overhead until the object dies. If you just want a block exit action,
then:

 add_block_exit_action(\foo);

or something similar will do it. (Though we could add new syntax for it if
you really want... :-)

Dan

--it's like this---
Dan Sugalski  even samurai
[EMAIL PROTECTED] have teddy bears and even
  teddy bears get drunk



RE: Control flow variables

2003-11-18 Thread Austin Hastings


 -Original Message-
 From: Luke Palmer [mailto:[EMAIL PROTECTED]
 Sent: Tuesday, November 18, 2003 10:49 AM
 To: Austin Hastings
 Cc: Language List
 Subject: Re: Control flow variables
 
 
 Austin Hastings writes:
  Luke Palmer wrote: 
   I was reading the most recent article on perl.com, and a code segment
   reminded me of something I see rather often in code that I don't like.
   Here's the code, Perl6ized:
   
   ... ;
   my $is_ok = 1;
   for 0..6 - $t {
   if abs(@new[$t] - @new[$t+1])  3 {
   $is_ok = 0;
   last;
   }
   }
   if $is_ok {
   push @moves: [$i, $j];
   }
   ...
  
  This is what I was talking about when I mentioned being able to do:
  
cleanup .= { push @moves: [$i, $j]; }
  
  a few weeks ago. Treat code vars like code, not like sub-refs.
 
 I'm not sure I know what you mean with regard to this example.
 Exemplify further, please?
 

Quoting Luke Palmer from weeks back:

 From: Luke Palmer [mailto:[EMAIL PROTECTED]
 Jeff Clites writes:
  Austin Hastings writes:
   Speaking to the practical side, I have written code that has to 
   disentangle itself from the failure of a complex startup sequence. 
   I'd love to be able to build a dynamic exit sequence. (In fact, 
   being able to do Cblock .= { more_stuff(); };/C is way up 
   on my list...)
  
  I've wanted to do that sort of thing before, but it seems simpler 
  (conceptually and practically) to build up an array of cleanup 
  subs/blocks to execute in sequence, rather than to have a .= for 
  blocks. (Another reason it's handy to keep them separate is in cases in 
  which each needs to return some information--maybe a status which 
  determines whether to proceed, etc.)
 
 But this is already supported, in its most powerful form:
 
 wrap block: { call; other_stuff() }
 
 Luke

Which begs the question of whether there's a way to get a handle to the current 
Cfor/C loop from within?

  LOOP: for 0..6 - $t {
 if abs(@new[$t] - @new[$t+1])  3 {
 wrap Block(): { call; handle_error(); };
 last;
 }
 }

 # handle_error() called here?

(Yes, this would presume that the Ccall/C came first, since how could it 
interpolate the call otherwise. It's a limitation of the wrap-as-append philosophy.)

=Austin



s/// in string context should return the string

2003-11-18 Thread Stéphane Payrard
 s/// in string context should return the string after substituion.
 It seems obvious to me but I mention it because I can't find it
 in the apocalypses.

--
  stef


Re: Control flow variables

2003-11-18 Thread Mark A. Biggar
OOPS, totally miss-read your code, ignore my first part of my last
message.
--
[EMAIL PROTECTED]
[EMAIL PROTECTED]




Re: Control flow variables

2003-11-18 Thread Mark A. Biggar
Luke Palmer wrote:

I was reading the most recent article on perl.com, and a code segment
reminded me of something I see rather often in code that I don't like.
Here's the code, Perl6ized:
... ;
my $is_ok = 1;
for 0..6 - $t {
if abs(@new[$t] - @new[$t+1])  3 {
$is_ok = 0;
last;
}
}
if $is_ok {
push @moves: [$i, $j];
}
...
What's wrong with:

 for 0..6 - $t {
 if abs(@new[$t] - @new[$t+1])  3 {
 push @moves: [$i, $j];
 last;
 }
 }


I see this idiom a lot in code.  You loop through some values on a
condition, and do something only if the condition was never true.
$is_ok is a control flow variable, something I like to minimize.  Now,
there are other ways to do this:
if (0..6 == grep - $t { abs(@new[$t] - @new[$t+1]) })
{ ... }
But one would say that's not the cleanest thing in the world.
and very unreadable, (even if that's heresy :-) )

Python pulled this idiom out in to the syntax (yay them), with Celse
on loops.  The else block on a python loop executes only if you never
broke out of the loop.  That's a great idea.
So, in Perl's postmodern tradition, I think we should steal that idea.
I'm a little uneasy about calling it Celse, though.  Maybe CFINISH
would do, making the example:
for 0..6 - $t {
if abs(@new[$t] - @new[$t+1])  3 {
last;
}
FINISH { 
push @moves: [$i, $j];
}
}
Violates least surprise, if the 'if' is true for '$t == 6' due
to the ambiguity between 'last' on '$t==6' and falling out the bottom
of the loop.  Maybe you want FINISH_EARLY instead?
--
[EMAIL PROTECTED]
[EMAIL PROTECTED]


Re: Control flow variables

2003-11-18 Thread Michael Lazzaro
On Tuesday, November 18, 2003, at 06:38 AM, Simon Cozens wrote:
Given that we've introduced the concept of if having a return status:

  my $result = if ($a) { $a } else { $b };

Would that then imply that

sub blah {
  ...  # 1
  return if $a;# 2
  ...  # 3
}
...would return $a if $a was true, and fall through to (3) if it was 
false?


[EMAIL PROTECTED] (Dan Sugalski) writes:
Luke Palmer:
That's illegal anyway.  Can't chain statement modifiers :-)
Will be able to.
I was under the strong impression that Larry had decided that syntactic 
ambiguities prevented this from happening.  (Now, of course, you will 
ask me for a cite to the thread, which I can't even begin to find at 
this point...)

MikeL



RE: s/// in string context should return the string

2003-11-18 Thread Austin Hastings
As a Bvalue where possible, so they can cascade and nest.

=Austin

 -Original Message-
 From: Stephane Payrard [mailto:[EMAIL PROTECTED]
 Sent: Tuesday, November 18, 2003 12:19 PM
 To: [EMAIL PROTECTED]
 Subject: s/// in string context should return the string
 
 
  s/// in string context should return the string after substituion.
  It seems obvious to me but I mention it because I can't find it
  in the apocalypses.
 
 --
   stef


RE: Control flow variables

2003-11-18 Thread Austin Hastings


 -Original Message-
 From: Michael Lazzaro [mailto:[EMAIL PROTECTED]
 Sent: Tuesday, November 18, 2003 2:06 PM
 To: [EMAIL PROTECTED]
 Subject: Re: Control flow variables



 On Tuesday, November 18, 2003, at 06:38 AM, Simon Cozens wrote:
  Given that we've introduced the concept of if having a return status:
 
my $result = if ($a) { $a } else { $b };
 

 Would that then imply that

  sub blah {
...  # 1
return if $a;# 2
...  # 3
  }

 ...would return $a if $a was true, and fall through to (3) if it was
 false?


It sure should, provided there were a correct context waiting, which would
quite nicely address another WIBNI thread a couple of months back about a
quick return under those conditions.

Very nice.

=Austin



Re: Control flow variables

2003-11-18 Thread Luke Palmer
Austin Hastings writes:
 
 
  -Original Message-
  From: Michael Lazzaro [mailto:[EMAIL PROTECTED]
  Sent: Tuesday, November 18, 2003 2:06 PM
  To: [EMAIL PROTECTED]
  Subject: Re: Control flow variables
 
 
 
  On Tuesday, November 18, 2003, at 06:38 AM, Simon Cozens wrote:
   Given that we've introduced the concept of if having a return status:
  
 my $result = if ($a) { $a } else { $b };
  
 
  Would that then imply that
 
   sub blah {
 ...  # 1
 return if $a;# 2
 ...  # 3
   }
 
  ...would return $a if $a was true, and fall through to (3) if it was
  false?
 
 
 It sure should, provided there were a correct context waiting, which would
 quite nicely address another WIBNI thread a couple of months back about a
 quick return under those conditions.

I don't think so.  I say that all the time to mean precisely:

if $a { return }

And I don't think people are ready to give that up. 

In particular, if we kept our bottom-up parser around, this particular
construct would cause an infinite-lookahead problem.  So for ambiguity's
sake, Cif $a should not be a valid term without a block following.

Luke


Re: Control flow variables

2003-11-18 Thread Luke Palmer
Austin Hastings writes:
 
 
  -Original Message-
  From: Michael Lazzaro [mailto:[EMAIL PROTECTED]
  Sent: Tuesday, November 18, 2003 2:06 PM
  To: [EMAIL PROTECTED]
  Subject: Re: Control flow variables
 
 
 
  On Tuesday, November 18, 2003, at 06:38 AM, Simon Cozens wrote:
   Given that we've introduced the concept of if having a return status:
  
 my $result = if ($a) { $a } else { $b };
  
 
  Would that then imply that
 
   sub blah {
 ...  # 1
 return if $a;# 2
 ...  # 3
   }
 
  ...would return $a if $a was true, and fall through to (3) if it was
  false?
 
 
 It sure should, provided there were a correct context waiting, which would
 quite nicely address another WIBNI thread a couple of months back about a
 quick return under those conditions.

Oh, and if you really want to do that return thing without using a
Cgiven, you can just:

sub blah {
return $a || goto CONT;
CONT:
...
}

I don't see what's wrong with that. :-p

Luke


Re: Control flow variables

2003-11-18 Thread Michael Lazzaro

Would that then imply that

 sub blah {
   ...  # 1
   return if $a;# 2
   ...  # 3
 }
...would return $a if $a was true, and fall through to (3) if it was
false?
It sure should, provided there were a correct context waiting, which 
would
quite nicely address another WIBNI thread a couple of months back 
about a
quick return under those conditions.
I don't think so.  I say that all the time to mean precisely:

if $a { return }

And I don't think people are ready to give that up.

In particular, if we kept our bottom-up parser around, this particular
construct would cause an infinite-lookahead problem.  So for 
ambiguity's
sake, Cif $a should not be a valid term without a block following.
So, just to make sure, these two lines are both valid, but do 
completely different things:

return if $a;
return if $a { $a }
MikeL



Re: Control flow variables

2003-11-18 Thread Damian Conway
Luke Palmer started a discussion:


I see this idiom a lot in code.  You loop through some values on a
condition, and do something only if the condition was never true.
$is_ok is a control flow variable, something I like to minimize.  Now,
there are other ways to do this:
if (0..6 == grep - $t { abs(@new[$t] - @new[$t+1]) })
{ ... }
But one would say that's not the cleanest thing in the world.
Only because you overdid the sugar. :

if grep {abs(@new[$^t] - @new[$^t+1])  3} 0..6
{ ... }
is pretty clean.

But, in any case, handling exceptional cases are what exceptions are for:

try {
for 0..6 - $t {
die if abs(@new[$t] - @new[$t+1])  3;
}
CATCH {
push @moves: [$i, $j];
}
}
As regards return values of control structures, I had always assumed that:

* scalar control structures like Cif, Cunless, and Cgiven return
  the value of the last statement in their block that they evaluated;
* vector control structures like Cloop, Cwhile, and Cfor in a list
  context return a list of the values of the last statement each
  iteration evaluated;
* vector control structures like Cloop, Cwhile, and Cfor in a scalar
  context return an integer indicating the number of times their block
  was iterated.
So we might also write:

for 0..6 - $t {
   last if abs(@new[$t] - @new[$t+1])  3;
}
 7 and push @moves: [$i, $j];
Damian




Re: Control flow variables

2003-11-18 Thread Damian Conway
Michael Lazzaro wrote:

So, just to make sure, these two lines are both valid, but do completely 
different things:

return if $a;
Means:

if ($a) { return }


return if $a { $a }
Means:

   if ($a) { return $a } else { return undef }

Damian



RE: Control flow variables

2003-11-18 Thread Austin Hastings


 -Original Message-
 From: Damian Conway [mailto:[EMAIL PROTECTED]
 Sent: Tuesday, November 18, 2003 4:02 PM
 To: Language List
 Subject: Re: Control flow variables


 Luke Palmer started a discussion:


  I see this idiom a lot in code.  You loop through some values on a
  condition, and do something only if the condition was never true.
  $is_ok is a control flow variable, something I like to minimize.  Now,
  there are other ways to do this:
 
  if (0..6 == grep - $t { abs(@new[$t] - @new[$t+1]) })
  { ... }
 
  But one would say that's not the cleanest thing in the world.

 Only because you overdid the sugar. :

  if grep {abs(@new[$^t] - @new[$^t+1])  3} 0..6
  { ... }

 is pretty clean.

 But, in any case, handling exceptional cases are what exceptions are for:

  try {
  for 0..6 - $t {
  die if abs(@new[$t] - @new[$t+1])  3;
  }
   CATCH {
  push @moves: [$i, $j];
  }
  }

 As regards return values of control structures, I had always assumed that:

  * scalar control structures like Cif, Cunless, and Cgiven
return the value of the last statement in their block that they
evaluated;

  * vector control structures like Cloop, Cwhile, and Cfor in a
list
context return a list of the values of the last statement each
iteration evaluated;

  * vector control structures like Cloop, Cwhile, and Cfor in
a scalar context return an integer indicating the number of times
their block was iterated.

This seems excessive, but easily discarded during optimization. On the other
hand, I don't trust the last statement evaluated behavior for loops, since
the optimizer could very well do surprising things to loop statements.
(Likewise, however, for scalar control structures.)

What does this say about order of evaluation?

  if @arry.length != while @arry { transmit(@arry.pop) or last; }
  {
print Couldn't send them all.;
  }

I'm pretty sure that has to have unspecified behavior, but ... comment?


 So we might also write:

  for 0..6 - $t {
 last if abs(@new[$t] - @new[$t+1])  3;
  }
   7 and push @moves: [$i, $j];


 Damian

Oh goody. Another (ab)use for named blocks:

  my named_block = for 0..6 - $t { last if abs (@new[$t] - @new[$t+1]) 
3; }

  push @moves: [$i, $j] if named_block()  7;

This seems hideously powerful, but at the same time dangerous. Kind of like
select.

=Austin



RE: Control flow variables

2003-11-18 Thread Austin Hastings


 -Original Message-
 From: Luke Palmer [mailto:[EMAIL PROTECTED]
 Sent: Tuesday, November 18, 2003 3:11 PM
 To: Austin Hastings
 Cc: Michael Lazzaro; [EMAIL PROTECTED]
 Subject: Re: Control flow variables
 
 
 Austin Hastings writes:
  
  
   -Original Message-
   From: Michael Lazzaro [mailto:[EMAIL PROTECTED]
   Sent: Tuesday, November 18, 2003 2:06 PM
   To: [EMAIL PROTECTED]
   Subject: Re: Control flow variables
  
  
  
   On Tuesday, November 18, 2003, at 06:38 AM, Simon Cozens wrote:
Given that we've introduced the concept of if having a 
 return status:
   
  my $result = if ($a) { $a } else { $b };
   
  
   Would that then imply that
  
sub blah {
  ...  # 1
  return if $a;# 2
  ...  # 3
}
  
   ...would return $a if $a was true, and fall through to (3) if it was
   false?
  
  
  It sure should, provided there were a correct context waiting, 
 which would
  quite nicely address another WIBNI thread a couple of months 
 back about a
  quick return under those conditions.
 
 I don't think so.  I say that all the time to mean precisely:
 
 if $a { return }
 
 And I don't think people are ready to give that up. 
 
 In particular, if we kept our bottom-up parser around, this particular
 construct would cause an infinite-lookahead problem.  So for ambiguity's
 sake, Cif $a should not be a valid term without a block following.
 

How on earth are you going to have an infinite lookahead problem when a semicolon is 
the next character?

=Austin



RE: Control flow variables

2003-11-18 Thread Dan Sugalski
On Tue, 18 Nov 2003, Austin Hastings wrote:

 This seems excessive, but easily discarded during optimization. On the other
 hand, I don't trust the last statement evaluated behavior for loops, since
 the optimizer could very well do surprising things to loop statements.
 (Likewise, however, for scalar control structures.)

This shouldn't be a problem. If there's potential ambiguity then the
optimization can't be applied. Modulo optimizer bugs you'll be fine.

Dan

--it's like this---
Dan Sugalski  even samurai
[EMAIL PROTECTED] have teddy bears and even
  teddy bears get drunk



Re: Control flow variables

2003-11-18 Thread Luke Palmer
Austin Hastings writes:
  From: Luke Palmer [mailto:[EMAIL PROTECTED]
 
  Austin Hastings writes:
From: Michael Lazzaro [mailto:[EMAIL PROTECTED]
   
Would that then imply that
   
 sub blah {
   ...  # 1
   return if $a;# 2
   ...  # 3
 }
   
...would return $a if $a was true, and fall through to (3) if it was
false?
   
   
  In particular, if we kept our bottom-up parser around, this particular
  construct would cause an infinite-lookahead problem.  So for ambiguity's
  sake, Cif $a should not be a valid term without a block following.
  
 
 How on earth are you going to have an infinite lookahead problem when a semicolon is 
 the next character?

Sorry, s/\$a/some-hideously-long-condition/

Luke

 =Austin
 


Re: Control flow variables

2003-11-18 Thread Damian Conway
Luke Palmer wrote:

My Cif/Cunless typo may
have misled you, but the original example pushed only if *none* of them
passed the condition.
Ah, sorry, I misunderstood.

So you want:

push @moves, [$i, $j];
for 0..6 - $t {
if abs(@new[$t] - @new[$t+1])  3 {
pop @moves;
last;
}
}
;-)

Damian





RE: Control flow variables

2003-11-18 Thread Austin Hastings


 -Original Message-
 From: Dan Sugalski [mailto:[EMAIL PROTECTED]
 Sent: Tuesday, November 18, 2003 4:34 PM
 To: Language List
 Subject: RE: Control flow variables


 On Tue, 18 Nov 2003, Austin Hastings wrote:

  This seems excessive, but easily discarded during optimization.
 On the other
  hand, I don't trust the last statement evaluated behavior for
 loops, since
  the optimizer could very well do surprising things to loop statements.
  (Likewise, however, for scalar control structures.)

 This shouldn't be a problem. If there's potential ambiguity then the
 optimization can't be applied. Modulo optimizer bugs you'll be fine.


That's the problem I have with it. I'm inclined to believe that the
optimization is more important than the postcondition, most of the time.

On the gripping hand, I *really* like Damian's Simple Rules for Control
Flow Return Values. So much so that I can easily see a bunch of idioms
coming up around them.

First:

  return if (some hideously long and possibly expensive guard);

That one just rocks. It's like:

  $_ = expensive();
  return if;

Singing Frank Zappa
  Valley Perl .. It's .. Valley Perl
  like .. return if
  when...ever
  duh!
/

Second:

I'm way not sure about how the vector context result of iteration structures
will work. Specifically, what happens when a loop forks a thread, or passes
to a parallelized coroutine? There may not actually BE a result. (Of course,
in a right-thinking system this will be noted, and replaced by a placeholder
object that will wait for the result if evaluated.)

Third:

The scalar count of iterations will make it seem that Cfor is a
macrification of Cmap, which isn't necessarily bad. In fact, I can see
this:

  $count = for [EMAIL PROTECTED] - $a {
check($a) or last;
  }

  if ($count != @a) { fail; }

Leading to:

  if (scalar(@a) != for [EMAIL PROTECTED] - $a { check($a) or last; }) { fail; }

Which leads to Cmap/Cgrep pretty directly:

  if grep {!check($^a) } @a { fail; }

So it should actually help with the newbie learning curve, providing an easy
transition from loops to map/grep.

Which really is a good thing.

=Austin



Re: Control flow variables

2003-11-18 Thread Seiler Thomas
Damian Conway wrote:

  push @moves, [$i, $j];
  for 0..6 - $t {
  if abs(@new[$t] - @new[$t+1])  3 {
  pop @moves;
  last;
  }
  }



Indeed, an elegant way around the problem.
So... lets call a function instead:

my $is_ok = 1;
for 0..6 - $t {
if abs(@new[$t] - @new[$t+1])  3 {
$is_ok = 0;
last;
}
}
if $is_ok {
yada()  # has sideeffects...
}

(wrote many such constructs for cgi sanity
checks and always found it mildly annoying)

regards
thomas

--
Imagination is more important than knowledge [Einstein]


begin 666 wink.gif
M1TE.#EA#P`/`+,``+^_O___
M`'Y! $```$`+ `/``\```0T,$@):ITX5,'Y
MQ4 GE,[EMAIL PROTECTED]PI;C9:YZYGOQK?C12R8C%7P;[EMAIL PROTECTED]
`
end



Re: Control flow variables

2003-11-18 Thread Damian Conway
Seiler Thomas wrote:

So... lets call a function instead:

my $is_ok = 1;
for 0..6 - $t {
if abs(@new[$t] - @new[$t+1])  3 {
$is_ok = 0;
last;
}
}
if $is_ok {
yada()  # has sideeffects...
}


That's just:

for 0..6, 'ok' - $t {
when 'ok' { yada() }
last if abs(@new[$t] - @new[$t+1])  3;
}
;-)

Damian





Re: syntax: multi vs. method

2003-11-18 Thread Jonathan Lang
Luke Palmer wrote:
 Jonathan Lang writes:
  Luke Palmer wrote:
   Well, multi is no longer a declarator in its own right, but rather
   a modifier.  Synopsis  Exegesis 6 show this.  
  
  I don't know about Exegesis 6, 
 
 Then you should probably read it.  It is the most recent of the
 documents, so what it says is closest to the current thinking. Plus,
 it's a fun read.

OK; I just finished it.  Apparently, there's a distinction between
multimethod and multi sub, and it's a distinction which renders one of
my points invalid.  A multimethod has multiple invocants and handles
dispatching based on the types of said invocants.  A multi sub has no
invocants; instead, it has a subset of its parameters (seperated from the
others by a colon) which it uses for dispatching purposes.  As such,
multi sub ($a: $b) {...} already has meaning, in that dispatching will
be decided strictly off of $a's type.  

So the following three declarations cover very similar (but not quite
identical) things: 

  multi sub call ($a: $b) {...}
  submethod invoke ($a: $b) {...}
  method check ($a: $b) {...}

All three of these use multiple dispatching.  The only distinctions are
that invoke and check can be called using method-like syntax, whereas
call cannot; and check pays attention to inheritence, whereas call
and invoke do not.  

In the case of multiple dispatch variables, the situation gets a bit
messier as I understand you:

  multi sub call ($a, $b: $c) {...}
  multi submethod invoke ($a, $b: $c) {...}
  multi method check ($a, $b: $c) {...}

Why do we suddenly need to append the multi keyword to submethod and
method?  Because it has a different meaning for method or submethod:
with sub, the multi keyword means use multiple dispatching, and so
we use it any time that we have one or more dispatch parameters; with
submethod and method, multiple dispatching is assumed and the keyword
means use more than one invocant.  

IMHO, we should choose one of these definitions for multi and stick with
it.  If you go with use multiple dispatching, multi becomes redundant
for method and submethod; if you go with allow more than one dispatch
parameter, then you ought to be able to declare a multiply dispatching
sub with a single dispatch parameter without using the multi keyword. 
Personally, I think that the first definition is the less confusing one.  

If you choose it, you'll never have need to use the multi keyword in
conjunction with method or submethod, restricting its use in practice
to cases where multiple dispatching doesn't normally occur (subs and
macros, mostly).  In those cases, one _could_ implicitly determine whether
the sub or function is multiply dispatched by looking for the colon in the
signature; but I tend to agree in these cases that requiring the multi
keyword might be a good idea.  

=
Jonathan Dataweaver Lang

__
Do you Yahoo!?
Protect your identity with Yahoo! Mail AddressGuard
http://antispam.yahoo.com/whatsnewfree


Re: Control flow variables

2003-11-18 Thread Damian Conway
Joseph Ryan wrote:

Not to be a jerk, but how about:

   my $is_ok = 1;
   for @array_of_random_values_and_types - $t {
   if not some_sort_of_test($t) {
   $is_ok = 0;
   last;
   }
   }
   if $is_ok {
   yada() # has sideeffects...
   }
That's just:

given @array_of_random_values_and_types - @data {
for @data.kv, [EMAIL PROTECTED] - $i, $t {
when [EMAIL PROTECTED] { yada() }
last if not some_sort_of_test($t);
}
}
;-)

Damian



Re: Control flow variables

2003-11-18 Thread David Wheeler
On Tuesday, November 18, 2003, at 06:11  PM, Joseph Ryan wrote:

Not to be a jerk, but how about:

   my $is_ok = 1;
   for @array_of_random_values_and_types - $t {
   if not some_sort_of_test($t) {
   $is_ok = 0;
   last;
   }
   }
   if $is_ok {
   yada() # has sideeffects...
   }
Isn't that just:

for @array_of_random_values_and_types, 'ok' - $t {
when 'ok' { yada(); last }
last unless some_sort_of_test($t);
}
IOW, the topic is only 'ok' when all of the items in the array have 
been processed, which in your code is what happens when  
some_sort_of_test($t) returns a true value.

Regards,

David

--
David Wheeler AIM: dwTheory
[EMAIL PROTECTED]  ICQ: 15726394
http://www.kineticode.com/ Yahoo!: dew7e
   Jabber: [EMAIL PROTECTED]
Kineticode. Setting knowledge in motion.[sm]


Re: Control flow variables

2003-11-18 Thread Joseph Ryan
David Wheeler wrote:

On Tuesday, November 18, 2003, at 06:11  PM, Joseph Ryan wrote:

Not to be a jerk, but how about:

   my $is_ok = 1;
   for @array_of_random_values_and_types - $t {
   if not some_sort_of_test($t) {
   $is_ok = 0;
   last;
   }
   }
   if $is_ok {
   yada() # has sideeffects...
   }


Isn't that just:

for @array_of_random_values_and_types, 'ok' - $t {
when 'ok' { yada(); last }
last unless some_sort_of_test($t);
}
IOW, the topic is only 'ok' when all of the items in the array have 
been processed, which in your code is what happens when  
some_sort_of_test($t) returns a true value.


And also if @array_of_random_values contains 'ok'.

- Joe



Re: Control flow variables

2003-11-18 Thread Damian Conway
David Wheeler wrote:

Isn't that just:

for @array_of_random_values_and_types, 'ok' - $t {
when 'ok' { yada(); last }
last unless some_sort_of_test($t);
}
IOW, the topic is only 'ok' when all of the items in the array have been 
processed
Unless, of course, the string 'ok' is also one of the random_values_and_types.
Hence my alternative solution.
Damian



Re: Control flow variables

2003-11-18 Thread David Wheeler
On Tuesday, November 18, 2003, at 06:44  PM, Joseph Ryan wrote:

And also if @array_of_random_values contains 'ok'.
D'oh! See Damian's solution, then. ;-)

David

--
David Wheeler AIM: dwTheory
[EMAIL PROTECTED]  ICQ: 15726394
http://www.kineticode.com/ Yahoo!: dew7e
   Jabber: [EMAIL PROTECTED]
Kineticode. Setting knowledge in motion.[sm]


Re: syntax: multi vs. method

2003-11-18 Thread Larry Wall
I think most everyone is missing the new simplicity of the current
conception of multi.  It's now completely orthogonal to scoping
issues.  It merely says, I'm putting multiple names into a spot
that would ordinarily demand a unique name.

In other words, what a name means in a given scope is a kind of
invariant--there's no magic hocus pocus in which multimethod dispatch
suddenly steals calls from ordinary method dispatch.

This is actually more powerful than the usual multimethods.  To get
the usual behavior of multimethods in other languages, you have to
explicitly declare the multimethods in global space:

multi sub *add( Foo $foo, Bar $bar );

If you write:

multi sub add( Foo $foo, Bar $bar );

then the current package has multiple add routines, but they aren't global.

If you write:

multi my sub add( Foo $foo, Bar $bar );

then the current *lexical* scope has multiple add routines!

If you write:

multi method add( $self: Foo $foo, Bar $bar );

then there are multiple add methods in the current class.  Note the
invocant is not optional in this case.  Also, there's an implied
second colon after $bar, indicating the end of the arguments to be
considered for multi dispatch.  (You can put as many colons as you
want in any multi declaration--each subsequent colon indicates that
the preceding additional argument or arguments are to be used as
tie breakers, just as Foo and Bar are being used for tie-breaking
in the method above.)  Likewise for submethods:

multi submethod add( $self: Foo $foo, Bar $bar );

In essence, the compiler could implement multi by taking any such
set of identically named routines and implementing them as a single
routine with switching logic to tell the types apart.

One ramification of all this is that true multimethods must always
be called as subroutines, not as methods.

I hope this clarifies things a bit.  Well, more than a bit...

Larry


Re: [perl] RE: s/// in string context should return the string

2003-11-18 Thread Joe Gottman
- Original Message - 
From: Austin Hastings [EMAIL PROTECTED]
To: [EMAIL PROTECTED]; [EMAIL PROTECTED]
Sent: Tuesday, November 18, 2003 3:04 PM
Subject: [perl] RE: s/// in string context should return the string


 As a Bvalue where possible, so they can cascade and nest.

   Excuse me.  I know enough C++ to know the difference between an lvalue
and an rvalue, but what the heck is a BValue?

Joe Gottman




Re: [perl] Re: syntax: multi vs. method

2003-11-18 Thread Joe Gottman

- Original Message - 
From: Jonathan Lang [EMAIL PROTECTED]
 So the following three declarations cover very similar (but not quite
 identical) things:

   multi sub call ($a: $b) {...}
   submethod invoke ($a: $b) {...}
   method check ($a: $b) {...}

 All three of these use multiple dispatching.  The only distinctions are
 that invoke and check can be called using method-like syntax, whereas
 call cannot; and check pays attention to inheritence, whereas call
 and invoke do not.


   Also, I assume that invoke and check will have access to $a's private
data members and methods, while call will not.

Joe Gottman




Re: syntax: multi vs. method

2003-11-18 Thread Luke Palmer
Larry Wall writes:
 If you write:
 
 multi method add( $self: Foo $foo, Bar $bar );
 
 then there are multiple add methods in the current class.  Note the
 invocant is not optional in this case.  Also, there's an implied
 second colon after $bar, indicating the end of the arguments to be
 considered for multi dispatch.  (You can put as many colons as you
 want in any multi declaration--each subsequent colon indicates that
 the preceding additional argument or arguments are to be used as
 tie breakers, just as Foo and Bar are being used for tie-breaking
 in the method above.)  

So what is the, ahem, submethod for determining the dispatch within the
tie-breaking cascades?  A simple sum of differences?  Cartesian
distance? 

Luke

 Larry