Re: Ruby iterators and blocks (was: Perl 6 Summary)

2002-07-04 Thread Erik Bågfors

On Thu, 2002-07-04 at 11:19, Andy Wardley wrote:
 On Tue, Jul 02, 2002 at 03:20:35PM -0500, Dan Sugalski wrote:
  I'm pretty sure the iterators they build are just closures with named 
  arguments, and behave as any other closure would behave. 
 
 Not quite.  Ruby iterators expect a block.  This is very much like a closure
 except that block parameters are local to the scope in which the block is 
 defined, not lexically scoped within the block.
 
 Or in other words, any existing variable of the same name as a block parameter
 will be updated when the block is called.
 
 An example:
 
   n = 10
 
   def twice
 yield 1
 yield 2
   end
 
   twice { |n| puts Hello World #{n} }
 
   puts n is now #{n}
 
 The result of this is:
 
   Hello World 1
   Hello World 2
   n is now 2
 
 I personally believe this approach is flawed, especially considering the fact 
 that there is no way (that I know of) to force block parameters to be truly
 lexically scoped or temporary (i.e. 'my' or 'local' in Perlspeak).  Much too 
 easy to mangle existing variables like this.
 

Most people agree. In the future there will be a way of doing that. 
Matz himself has said so.

/Erik

-- 
Erik Bågfors   | [EMAIL PROTECTED]
Supporter of free software | GSM +46 733 279 273
fingerprint:  A85B 95D3 D26B 296B 6C60 4F32 2C0B 693D 6E32



Re: Ruby iterators and blocks (was: Perl 6 Summary)

2002-07-04 Thread Larry Wall

On 4 Jul 2002, Erik [ISO-8859-1] Bågfors wrote:
: On Thu, 2002-07-04 at 11:19, Andy Wardley wrote:
:  I personally believe this approach is flawed, especially considering the fact 
:  that there is no way (that I know of) to force block parameters to be truly
:  lexically scoped or temporary (i.e. 'my' or 'local' in Perlspeak).  Much too 
:  easy to mangle existing variables like this.
: 
: Most people agree. In the future there will be a way of doing that. 
: Matz himself has said so.

Indeed, Ruby is the main reason I decided to keep my explicit in Perl 6.  :-)

Larry




Re: Ruby iterators

2002-07-03 Thread Allison Randal

On Tue, Jul 02, 2002 at 07:32:00PM -0600, Luke Palmer wrote:
 On Tue, 2 Jul 2002, Michael G Schwern wrote:
 
  * Yes, Perl 6 will have named arguments to subroutines.
  
  What I can remember from the Perl 6 BoF is it will look something like this:
  
  sub foo ($this, $that) {
  print $this if $that;
  }
  which is like:
  
  sub foo {
  my($this, $that) = _;
  print $this if $that;
  }
  
  somebody else on this list can handle explaining how that all works better
  than I can.  There's stuff about pointy subroutines, -, method topics,
  etc... *hand wave*
  
 
 Yep (far as I know. The only way I can secure my knowledge is to be 
 arrogant and then be confirmed or negated). After this, you can call foo 
 like so:
 
   foo(Bar, 1);
 
 Or like this:
 
   foo(that = 1, this = Bar);
 
 Or like this:
 
   foo(Bar, that = 1);
 
 They all do the same thing.

Yes.

 As far as pointy subs, - is just a synonym for sub, with some extra sugar 
 sprinkled on.  You don't need to put parenthesis around the arglist, and I 
 think $_ is always aliased to the first argument.  

Yes, yes and yes.

 If there are no arguments, the sub takes one argument and it is
 aliased to $_. Am I right?

If you think you want a pointy sub with no parameters, like:

for stuff - { print; }

stuff = grep - { /blarf/ } list;

%commands = (
add  = - { $^a + $^b },
incr = - { $_ + 1 },
)

what you really want is a bare closure:

for stuff { print; }

stuff = grep { /blarf/ } list;

%commands = (
add  = { $^a + $^b },
incr = { $_ + 1 },
);

which will alias $_ to the first argument. The pointy sub with no
parameters may even be a syntax error.

(Methods do act like you suggested, because even when they have no
parameter list or explicit arguments, they still have 1 argument -- the
invocant, a.k.a. $self -- and it is aliased to $_.)

 Of course you can't make named subs with -, just anonymous ones.

Yes.

  I *think* you will also be able to do this, at least I can't see why you
  wouldn't be able to:
  
  stuff = grep { length $^foo = 42 } list;
  
  which is nice for nested greps and maps.  You don't have to fight over who
  has $_.
 
 Yep, grep takes a closure argument now.  

And if Larry goes with what he suggested last Thursday, that may be the
only type of argument it takes in that position, no more bare
expressions. Two curly-braces seem a small price to pay for the gains in
consistency.

 If you wanted to make things interesting, you could do it this way
 too.
 
   stuff = grep - $foo { length $foo = 42 } list;
 
I'd even say that's the preferred way of doing it, though it's more a
matter of style.

tips hat to Luke Nicely explained.

Allison



Re: Ruby iterators

2002-07-02 Thread Michael G Schwern

On Fri, Jun 28, 2002 at 01:21:50PM -0700, Erik Steven Harrison wrote:
 Over on Perlmonks someone was asking about Perl 6's ability to have named
 argument passing. He also asked about the Jensen Machine and Ruby iterators.
 Now, just being on this list has taught me so much, but, I'm not quite sure
 how it works, practically speaking, and whether or not we'll get in in P6.
 (I understand the abstract o fpass by name, but not how we use it). Could
 someone explain it to me, and tell me what the Perl 6 stance on the matter
 is?

* Yes, Perl 6 will have named arguments to subroutines.

What I can remember from the Perl 6 BoF is it will look something like this:

sub foo ($this, $that) {
print $this if $that;
}

which is like:

sub foo {
my($this, $that) = @_;
print $this if $that;
}

somebody else on this list can handle explaining how that all works better
than I can.  There's stuff about pointy subroutines, -, method topics,
etc... *hand wave*

Even better, you can have small anonymous subroutines with implied
arguments.

@sorted_list = sort { $^a cmp $^b } @list;

which Perl will translate into the moral equivalent of:

my $sub = sub ($^a, $^b) { $^a cmp $^b };
@sorted_list = sort $sub, @list;

basically, it's a quick way to declare a subroutine while still having named
arguments for things like sort, map  grep.  Perl orders the arguments in
UTF8 order.

I *think* you will also be able to do this, at least I can't see why you
wouldn't be able to:

@stuff = grep { length $^foo = 42 } @list;

which is nice for nested greps and maps.  You don't have to fight over who
has $_.

So now grep/map/etc... will all take real code refs, so...


* Yes, Perl 6 will have the moral equivalent to Ruby iterators.

I'm particularly happy about the iterators, something that leapt out at me
when I learned Ruby as being very, very powerful.

For those who don't know what Ruby iterators are, you can go back through
the archives for the thread Does this mean we get Ruby/CLU-style iterators?
or an earlier thread:
http:[EMAIL PROTECTED]/msg08343.html

From what I understand, the prototyping mechanism will be extended to allow
a method to take a block/code ref at the end of it's arguments.  Correct me
if I'm wrong, but while, for and such will all just be built-in subroutines.
So one can write something like this:

 class File;
 method foreach ($file, block) {
my $fh = open $file;
while( $fh ) {
   block($_);
}
 }

 # open /usr/dict/words and print out each line.
 File.foreach '/usr/dict/words' {
 print;
 }

The block is just an anonymous subroutine passed in as the second argument
to File.foreach().  In Perl 5, it would look something like this:

 package File;
 sub foreach {
 my($file, $block) = @_;
 open(FILE, $file);
 while(FILE) {
 $block-($_);
 }
 }
 
 File-foreach '/usr/dict/words', sub {
 print;
 };

so what Perl 6 is really adding is the ability to write methods which look
like loops.


Ruby also has it's |$a| mechanism to name the arguments.  Presumably, you'll
get the same effect with the implied arguments I mentioned earlier.

File.foreach '/usr/dict/words' {
print $^line;
}

Something like that.



* What's a Jensen Machine?


-- 
This sig file temporarily out of order.



Re: Ruby iterators

2002-07-02 Thread Luke Palmer

On Tue, 2 Jul 2002, Michael G Schwern wrote:

 On Fri, Jun 28, 2002 at 01:21:50PM -0700, Erik Steven Harrison wrote:
  Over on Perlmonks someone was asking about Perl 6's ability to have named
  argument passing. He also asked about the Jensen Machine and Ruby iterators.
  Now, just being on this list has taught me so much, but, I'm not quite sure
  how it works, practically speaking, and whether or not we'll get in in P6.
  (I understand the abstract o fpass by name, but not how we use it). Could
  someone explain it to me, and tell me what the Perl 6 stance on the matter
  is?
 
 * Yes, Perl 6 will have named arguments to subroutines.
 
 What I can remember from the Perl 6 BoF is it will look something like this:
 
 sub foo ($this, $that) {
   print $this if $that;
 }
 which is like:
 
 sub foo {
 my($this, $that) = _;
   print $this if $that;
 }
 
 somebody else on this list can handle explaining how that all works better
 than I can.  There's stuff about pointy subroutines, -, method topics,
 etc... *hand wave*
 

Yep (far as I know. The only way I can secure my knowledge is to be 
arrogant and then be confirmed or negated). After this, you can call foo 
like so:

foo(Bar, 1);

Or like this:

foo(that = 1, this = Bar);

Or like this:

foo(Bar, that = 1);

They all do the same thing.

As far as pointy subs, - is just a synonym for sub, with some extra sugar 
sprinkled on.  You don't need to put parenthesis around the arglist, and I 
think $_ is always aliased to the first argument.  If there are no 
arguments, the sub takes one argument and it is aliased to $_. Am I 
right?

Of course you can't make named subs with -, just anonymous ones.

 I *think* you will also be able to do this, at least I can't see why you
 wouldn't be able to:
 
 stuff = grep { length $^foo = 42 } list;
 
 which is nice for nested greps and maps.  You don't have to fight over who
 has $_.

Yep, grep takes a closure argument now.  If you wanted to make things 
interesting, you could do it this way too.

stuff = grep - $foo { length $foo = 42 } list;

 * Yes, Perl 6 will have the moral equivalent to Ruby iterators.
 
 
 Ruby also has it's |$a| mechanism to name the arguments.  Presumably, you'll
 get the same effect with the implied arguments I mentioned earlier.
 
 File.foreach '/usr/dict/words' {
 print $^line;
 }
 
 Something like that.

Or

File.foreach '/usr/dict/words' - $arg {
print $arg;
}


Luke