diff --git a/basis/combinators/smart/smart-docs.factor b/basis/combinators/smart/smart-docs.factor index 3a09e33f7f..2f1b21f92c 100644 --- a/basis/combinators/smart/smart-docs.factor +++ b/basis/combinators/smart/smart-docs.factor @@ -231,6 +231,14 @@ HELP: smart-with { "param" object } { "obj" object } { "quot" { $quotation "( param ..a -- ..b" } } { "curry" curry } } { $description "A version of " { $link with } " that puts the parameter before any inputs the quotation uses." } ; +HELP: smart-reduce +{ $values { "reduce-quots" sequence } } +{ $description "A version of " { $link reduce } " that takes a sequence of " { $snippet "{ identity reduce-quot }" } " pairs, returning the " { $link reduce } " result for each pair." } ; + +HELP: smart-map-reduce +{ $values { "map-reduce-quots" sequence } } +{ $description "A version of " { $link map-reduce } " that takes a sequence of " { $snippet "{ map-quot reduce-quot }" } " pairs, returning the " { $link map-reduce } " result for each pair." } ; + ARTICLE: "combinators.smart" "Smart combinators" "A " { $emphasis "smart combinator" } " is a macro which reflects on the stack effect of an input quotation. The " { $vocab-link "combinators.smart" } " vocabulary implements a few simple smart combinators which look at the static stack effects of input quotations and generate code which produces or consumes the relevant number of stack values." $nl "Take all input values from a sequence:" diff --git a/basis/combinators/smart/smart-tests.factor b/basis/combinators/smart/smart-tests.factor index 4b47094c2d..9569952433 100644 --- a/basis/combinators/smart/smart-tests.factor +++ b/basis/combinators/smart/smart-tests.factor @@ -95,3 +95,17 @@ IN: combinators.smart.tests \ test-cleave>sequence def>> must-infer { V{ 34 1089 32 } } [ 33 test-cleave>sequence ] unit-test + +{ 60 6000 } [ + { 10 20 30 } { + { 0 [ + ] } + { 1 [ * ] } + } smart-reduce +] unit-test + +{ 1400 60 } [ + { 10 20 30 } { + { [ sq ] [ + ] } + { [ ] [ + ] } + } smart-map-reduce +] unit-test diff --git a/basis/combinators/smart/smart.factor b/basis/combinators/smart/smart.factor index 5b37606dc9..612701e52e 100644 --- a/basis/combinators/smart/smart.factor +++ b/basis/combinators/smart/smart.factor @@ -1,10 +1,10 @@ -! Copyright (C) 2009, 2011 Doug Coleman. +! Copyright (C) 2009, 2011 Doug Coleman, John Benediktsson. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors arrays effects fry generalizations kernel -macros math math.order sequences sequences.generalizations -stack-checker stack-checker.backend stack-checker.errors -stack-checker.values stack-checker.visitor words memoize -combinators ; +USING: accessors arrays assocs combinators effects fry +generalizations kernel macros math math.order memoize sequences +sequences.generalizations sequences.private stack-checker +stack-checker.backend stack-checker.errors stack-checker.values +stack-checker.visitor words ; IN: combinators.smart GENERIC: infer-known* ( known -- effect ) @@ -129,3 +129,15 @@ MACRO: map-reduce-outputs ( quot mapper reducer -- quot ) : smart-with ( param obj quot -- obj curry ) swapd dup inputs '[ [ _ -nrot ] dip call ] 2curry ; inline + +MACRO: smart-reduce ( reduce-quots -- quot ) + unzip [ [ ] like ] bi@ dup length dup '[ + [ @ ] dip [ @ _ cleave-curry _ spread* ] each + ] ; + +MACRO: smart-map-reduce ( map-reduce-quots -- quot ) + [ keys ] [ [ [ ] concat-as ] [ ] map-as ] bi dup length dup '[ + [ first _ cleave ] keep + [ @ _ cleave-curry _ spread* ] + [ 1 ] 2dip (each) (each-integer) + ] ;