# New Ticket Created by Vasily Chekalkin # Please include the string: [perl #63764] # in the subject line of all future correspondence about this issue. # <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=63764 >
--- src/builtins/any-list.pir | 61 --------------------------------------------- src/setting/Any-list.pm | 21 ++++++++++++++- 2 files changed, 20 insertions(+), 62 deletions(-) diff --git a/src/builtins/any-list.pir b/src/builtins/any-list.pir index a61edd5..6540465 100644 --- a/src/builtins/any-list.pir +++ b/src/builtins/any-list.pir @@ -296,67 +296,6 @@ Return a List with the keys of the invocant. .tailcall self.'pick'($I0) .end -=item reduce(...) - -=cut - -.namespace [] -.sub 'reduce' :multi('Sub') - .param pmc expression - .param pmc values :slurpy - .tailcall values.'reduce'(expression) -.end - -.namespace ['Any'] -.sub 'reduce' :method :multi(_, 'Sub') - .param pmc expression - .local pmc retv - .local pmc iter - .local pmc elem - .local pmc args - .local int i, arity - - arity = expression.'arity'() - if arity < 2 goto error - - iter = self.'iterator'() - unless iter goto empty - retv = shift iter - loop: - unless iter goto done - - # Create arguments for closure - args = new 'ResizablePMCArray' - # Start with 1. First argument is result of previous call - i = 1 - - args_loop: - if i == arity goto invoke - unless iter goto elem_undef - elem = shift iter - goto push_elem - elem_undef: - elem = 'undef'() - - push_elem: - push args, elem - inc i - goto args_loop - - invoke: - retv = expression(retv, args :flat) - goto loop - - empty: - .tailcall '!FAIL'('Cannot reduce an empty list') - - error: - 'die'('Cannot reduce() using a unary or nullary function.') - - done: - .return(retv) -.end - =item sort() diff --git a/src/setting/Any-list.pm b/src/setting/Any-list.pm index 9af5a33..5cb7ed6 100644 --- a/src/setting/Any-list.pm +++ b/src/setting/Any-list.pm @@ -3,7 +3,22 @@ class Any is also { gather { take $_ if $test($_) for $values.list; } - } + }; + + multi method reduce(Code $expression) { + my Int $arity = $expression.count; + die('Cannot reduce() using a unary or nullary function.') if $arity < 2; + + my $list := @.list or fail('Cannot reduce() empty list'); + + my $res = $list.shift; + while $list { + my @args = gather { take $list.shift if $list for 2..$arity }; + $res = &$expression($res, |@args); + } + + $res; + }; our List multi method map(Code *&expr) { return gather { @@ -52,6 +67,10 @@ our List multi grep(Code $test, *...@values) { @values.grep($test) } +multi reduce ( Code $expression ;; *...@values ) { + @values.reduce($expression); +} + our List multi map(Code $expr, *...@values) { @values.map($expr) } -- 1.6.2.rc0