Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

Re^3: Perl6 Contest #2: P6 That Doesn't Look Like P5

by tall_man (Parson)
on Jun 07, 2005 at 16:37 UTC ( #464377=note: print w/replies, xml ) Need Help??

in reply to Re^2: Perl6 Contest #2: P6 That Doesn't Look Like P5
in thread Perl6 Contest #2: P6 That Doesn't Look Like P5

On the principle that ugly working code is better than elegant nonworking code, I did a brute-force conversion of part of Algorithms:Loop. It supports a last-in-the list-parameter the hard way, by copying it as the first parameter instead of in $_,
use v6; sub _NL_Iter(@loops, $when) returns Ref { my @list; my $i = -1; my @idx; return sub { return } if ! @loops; my @vals = @loops; return sub { while 1 { # Prepare to append one more value: if $i < @loops.end { @idx[++$i]= -1; if @loops[$i].does(Code) { @vals[$i]= @loops[$i](@list[-1], @list); } } ## return if $i < 0; # Increment furthest value, chopping if done there. while @vals[$i].elems <= ++@idx[$i] { pop @list; return if --$i < 0; } @list[$i]= @vals[$i][@idx[$i]]; if $when.does(Code) { return @list if $when(@list[-1], @list); } else { return @list; } } }; } sub NestedLoop(++@loops, +$code, +$when) { my $onlywhen = $when; my $count_elems = @loops.elems + 1; $onlywhen //= sub { @_ == $count_elems }; # Default case - when we +have a full count. my $iter= _NL_Iter(@loops, $onlywhen ); if ! $code { # There seeems to be no way to check for void context, since # want.count is not working. I wanted to test want.count == 0 +. return $iter; } my @ret; my @list; while @list = $iter() { @list = $code( @list ); if want.List { push @ret, @list; } else { @ret[0] += @list; } } return want.List ?? @ret :: ( $ret[0] // 0 ); } my $next = NestedLoop(loops => ([0..2], [0..2], [0..2])); my @group; while @group = $next() { say ~@group; }; say "\nsecond case:"; my $N = 4; my $depth = 3; my $i2 = NestedLoop(loops => ( [ 0..$N ], ( sub { [@_[0]+1..$N] } ) xx ($depth- +1), ) ); while @group = $i2() { say ~@group; };

Replies are listed 'Best First'.
Re^4: Perl6 Contest #2: P6 That Doesn't Look Like P5
by tall_man (Parson) on Jun 08, 2005 at 00:16 UTC
    I was looking for ways to pass out-of-band parameters to the loop subroutines (preferably without requiring the users to make messy changes), and this idea of using named parameters in combination with a splatted list occurred to me.
    #!/usr/bin/pugs use v6; #use Test; #plan 2; sub oob(+$x = $CALLER::_, *@lst) { return ($x,@lst); } sub runner() { $_ = "qqq"; oob("a","b","c"); } my ($x, @lst) = runner(); say "x = *$x* lst = *",~@lst,"*"; #is($x, 'qqq', '... default named parameter with $CALLER_ and a list', + :todo<bug>); #is(~@lst, 'a b c', '... list after default named parameter with $CALL +ER_', :todo<bug>);

    What I actually got was:

    x = *a* lst = *b c*
    and not:
    x = *qqq* lst = *a b c*

    This was unexpected after seeing examples in E06, so it could be a bug test (with the Test stuff uncommented). Or I may be completely misunderstanding positional parameters.

      Couldn't you place named paramteres after the uhhh....splatted?... parameter?

      Actualy a quick test shows that doesn't work. I think however it would be usefull to have a set of positional paramters (like your slurpy array) and then follow them with parameters that are meant to be set by named pairs. Then sub oob(*@lst,?$x = $CALLER::_) { would DWIM

      Eric Hodges
        I don't believe it will ever be possible to put named parameters after slurpy parameters. From E06:

        An important restriction on named arguments is that they cannot come before positional arguments, or after any arguments that are bound to a slurpy array. Otherwise, there would be no efficient, single-pass way of working out which unnamed arguments belong to which parameters. But apart from that one overarching restriction (which Larry likes to think of as a zoning law), we’re free to pass named arguments in any order we like. That’s a huge advantage in any subroutine that takes a large number of parameters, because it means we no longer have to remember their order, just their names.

        So this looks like the reason for my bug also. Named parameters cannot come before *@lst (because it's positional) and they cannot come after (because it's slurpy) so the declaration is invalid.

        By the way, the "+" for "named only" doesn't really mean it. I found this astonishing code in the test cases:

        sub foo (+$x = 3) { $x } is(foo(4), 4, "using a named as a positional works");

        If that is legal, what's the difference between a "+" prefix and a "?" prefix on a parameter?

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://464377]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (7)
As of 2020-08-03 15:41 GMT
Find Nodes?
    Voting Booth?
    Which rocket would you take to Mars?

    Results (27 votes). Check out past polls.