]> gitweb.factorcode.org Git - factor.git/blob - core/generalizations/generalizations.factor
d03bba74b1d8135c3410fad7796caf33f754b174
[factor.git] / core / generalizations / generalizations.factor
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 ;
6 IN: generalizations
7
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.
12 <<
13
14 ALIAS: n*quot (n*quot)
15
16 MACRO: call-n ( n -- quot )
17     [ call ] <repetition> '[ _ cleave ] ;
18
19 : repeat ( n obj quot -- ) swapd times ; inline
20
21 >>
22
23 MACRO: nsum ( n -- quot )
24     1 - [ + ] n*quot ;
25
26 ERROR: nonpositive-npick n ;
27
28 MACRO: npick ( n -- quot )
29     {
30         { [ dup 0 <= ] [ nonpositive-npick ] }
31         { [ dup 1 = ] [ drop [ dup ] ] }
32         [ 1 - [ dup ] [ '[ _ dip swap ] ] repeat ]
33     } cond ;
34
35 : ndup ( n -- )
36     [ '[ _ npick ] ] keep call-n ; inline
37
38 MACRO: dupn ( n -- quot )
39     [ [ drop ] ]
40     [ 1 - [ dup ] n*quot ] if-zero ;
41
42 MACRO: nrot ( n -- quot )
43     1 - [ ] [ '[ _ dip swap ] ] repeat ;
44
45 MACRO: -nrot ( n -- quot )
46     1 - [ ] [ '[ swap _ dip ] ] repeat ;
47
48 : ndip ( n -- )
49     [ [ dip ] curry ] swap call-n call ; inline
50
51 : ndrop ( n -- )
52     [ drop ] swap call-n ; inline
53
54 : nnip ( n -- )
55     '[ _ ndrop ] dip ; inline
56
57 DEFER: -nrotd
58 MACRO: nrotd ( n d -- quot )
59     over 0 < [
60         [ neg ] dip '[ _ _ -nrotd ]
61     ] [
62         [ 1 - [ ] [ '[ _ dip swap ] ] repeat ] dip '[ _ _ ndip ]
63     ] if ;
64
65 MACRO: -nrotd ( n d -- quot )
66     over 0 < [
67         [ neg ] dip '[ _ _ nrotd ]
68     ] [
69         [ 1 - [ ] [ '[ swap _ dip ] ] repeat ] dip '[ _ _ ndip ]
70     ] if ;
71
72 MACRO: nrotated ( nrots depth dip -- quot )
73     [ '[ [ _ nrot ] ] replicate [ ] concat-as ] dip '[ _ _ ndip ] ;
74
75 MACRO: -nrotated ( -nrots depth dip -- quot )
76     [ '[ [ _ -nrot ] ] replicate [ ] concat-as ] dip '[ _ _ ndip ] ;
77
78 MACRO: nrotate-heightd ( n height dip -- quot )
79     [ '[ [ _ nrot ] ] replicate concat ] dip '[ _ _ ndip ] ;
80
81 MACRO: -nrotate-heightd ( n height dip -- quot )
82     [
83         '[ [ _ -nrot ] ] replicate concat
84     ] dip '[ _ _ ndip ] ;
85
86 : ndupd ( n dip -- ) '[ [ _ ndup ] _ ndip ] call ; inline
87
88 MACRO: ntuckd ( ntuck ndip -- quot )
89     [ 1 + ] dip '[ [ dup _ -nrot ] _ ndip ] ;
90
91 MACRO: nover ( n -- quot )
92     dup 1 + '[ _ npick ] n*quot ;
93
94 MACRO: noverd ( n depth dip -- quot' )
95     [ + ] [ 2drop ] [ [ + ] dip ] 3tri
96     '[ _ _ ndupd _ _ _ nrotated ] ;
97
98 MACRO: mntuckd ( ndup depth ndip -- quot )
99     { [ nip ] [ 2drop ] [ drop + ] [ 2nip ] } 3cleave
100     '[ _ _ ndupd _ _ _ -nrotated ] ;
101
102 : nkeep ( n -- )
103     dup '[ [ _ ndup ] dip _ ndip ] call ; inline
104
105 : ncurry ( n -- )
106     [ curry ] swap call-n ; inline
107
108 : nwith ( n -- )
109     [ with ] swap call-n ; inline
110
111 : nbi ( quot1 quot2 n -- )
112     [ nip nkeep ] [ drop nip call ] 3bi ; inline
113
114 MACRO: ncleave ( quots n -- quot )
115     [ '[ _ '[ _ _ nkeep ] ] map [ ] join ] [ '[ _ ndrop ] ] bi
116     compose ;
117
118 MACRO: nspread ( quots n -- quot )
119     over empty? [ 2drop [ ] ] [
120         [ [ but-last ] dip ]
121         [ [ last ] dip ] 2bi
122         swap
123         '[ [ _ _ nspread ] _ ndip @ ]
124     ] if ;
125
126 MACRO: spread* ( n -- quot )
127     [ [ ] ] [
128         [1..b) [ '[ [ [ _ ndip ] curry ] dip compose ] ] map [ ] concat-as
129         [ call ] compose
130     ] if-zero ;
131
132 MACRO: nspread* ( m n -- quot )
133     [ drop [ ] ] [
134         [ * 0 ] [ drop neg ] 2bi
135         <range> rest >array dup length <iota> <reversed>
136         [ '[ [ [ _ ndip ] curry ] _ ndip ] ] 2map
137         [ [ ] concat-as ]
138         [ length 1 - [ compose ] <array> concat append ] bi
139         [ call ] compose
140     ] if-zero ;
141
142 MACRO: cleave* ( n -- quot )
143     [ [ ] ]
144     [ 1 - [ [ [ keep ] curry ] dip compose ] n*quot [ call ] compose ]
145     if-zero ;
146
147 : napply ( quot n -- )
148     [ dupn ] [ spread* ] bi ; inline
149
150 : mnapply ( quot m n -- )
151     [ nip dupn ] [ nspread* ] 2bi ; inline
152
153 : apply-curry ( a... quot n -- )
154     [ currier ] dip napply ; inline
155
156 : cleave-curry ( a quot... n -- )
157     [ currier ] swap [ napply ] [ cleave* ] bi ; inline
158
159 : spread-curry ( a... quot... n -- )
160     [ currier ] swap [ napply ] [ spread* ] bi ; inline
161
162 MACRO: mnswap ( m n -- quot )
163     1 + '[ _ -nrot ] swap '[ _ _ napply ] ;
164
165 MACRO: nweave ( n -- quot )
166     [ dup <iota> <reversed> [ '[ _ _ mnswap ] ] with map ] keep
167     '[ _ _ ncleave ] ;
168
169 : nbi-curry ( n -- )
170     [ bi-curry ] swap call-n ; inline
171
172 MACRO: map-compose ( quots quot -- quot' )
173     '[ _ compose ] map '[ _ ] ;