1 ! Copyright (C) 2007, 2009 Chris Double, Doug Coleman, Eduardo
2 ! Cavazos, Slava Pestov.
3 ! See http://factorcode.org/license.txt for BSD license.
4 USING: arrays combinators kernel kernel.private math ranges
5 memoize.private sequences ;
8 ! These words can be inline combinators when the word does no math
9 ! on the input parameters, e.g. n.
10 ! If math is done, the word needs to be a macro so the math can
11 ! be done at compile-time.
14 ALIAS: n*quot (n*quot)
16 MACRO: call-n ( n -- quot )
17 [ call ] <repetition> '[ _ cleave ] ;
19 : repeat ( n obj quot -- ) swapd times ; inline
23 MACRO: nsum ( n -- quot )
26 ERROR: nonpositive-npick n ;
28 MACRO: npick ( n -- quot )
30 { [ dup 0 <= ] [ nonpositive-npick ] }
31 { [ dup 1 = ] [ drop [ dup ] ] }
32 [ 1 - [ dup ] [ '[ _ dip swap ] ] repeat ]
35 MACRO: nover ( n -- quot )
36 dup 1 + '[ _ npick ] n*quot ;
39 [ '[ _ npick ] ] keep call-n ; inline
41 MACRO: dupn ( n -- quot )
43 [ 1 - [ dup ] n*quot ] if-zero ;
45 MACRO: nrot ( n -- quot )
46 1 - [ ] [ '[ _ dip swap ] ] repeat ;
48 MACRO: -nrot ( n -- quot )
49 1 - [ ] [ '[ swap _ dip ] ] repeat ;
52 [ [ dip ] curry ] swap call-n call ; inline
54 : nrotates ( n depth -- quot )
55 '[ _ [ _ nrot ] times ] call ; inline
57 : -nrotates ( n depth -- quot )
58 '[ _ [ _ -nrot ] times ] call ; inline
61 [ drop ] swap call-n ; inline
64 '[ _ ndrop ] dip ; inline
67 dup '[ [ _ ndup ] dip _ ndip ] call ; inline
70 [ curry ] swap call-n ; inline
73 [ with ] swap call-n ; inline
75 : nbi ( quot1 quot2 n -- )
76 [ nip nkeep ] [ drop nip call ] 3bi ; inline
78 MACRO: ncleave ( quots n -- quot )
79 [ '[ _ '[ _ _ nkeep ] ] map [ ] join ] [ '[ _ ndrop ] ] bi
82 MACRO: nspread ( quots n -- quot )
83 over empty? [ 2drop [ ] ] [
87 '[ [ _ _ nspread ] _ ndip @ ]
90 MACRO: spread* ( n -- quot )
92 [1..b) [ '[ [ [ _ ndip ] curry ] dip compose ] ] map [ ] concat-as
96 MACRO: nspread* ( m n -- quot )
98 [ * 0 ] [ drop neg ] 2bi
99 <range> rest >array dup length <iota> <reversed>
100 [ '[ [ [ _ ndip ] curry ] _ ndip ] ] 2map
102 [ length 1 - [ compose ] <array> concat append ] bi
106 MACRO: cleave* ( n -- quot )
108 [ 1 - [ [ [ keep ] curry ] dip compose ] n*quot [ call ] compose ]
111 : napply ( quot n -- )
112 [ dupn ] [ spread* ] bi ; inline
114 : mnapply ( quot m n -- )
115 [ nip dupn ] [ nspread* ] 2bi ; inline
117 : apply-curry ( a... quot n -- )
118 [ currier ] dip napply ; inline
120 : cleave-curry ( a quot... n -- )
121 [ currier ] swap [ napply ] [ cleave* ] bi ; inline
123 : spread-curry ( a... quot... n -- )
124 [ currier ] swap [ napply ] [ spread* ] bi ; inline
126 MACRO: mnswap ( m n -- quot )
127 1 + '[ _ -nrot ] swap '[ _ _ napply ] ;
129 MACRO: nweave ( n -- quot )
130 [ dup <iota> <reversed> [ '[ _ _ mnswap ] ] with map ] keep
134 [ bi-curry ] swap call-n ; inline
136 MACRO: map-compose ( quots quot -- quot' )
137 '[ _ compose ] map '[ _ ] ;