1 Some notes on definitions.
3 Let's work out the definition of the step combinator in Joy:
10 -----------------------
13 In terms of branch and x:
25 First, get the flag value and roll< it to the top for a branch:
31 ---------------------------
33 ---------------------------------------
34 [L] [P] [F′ F″] [?] dipd roll< F″
38 [L] [P] [F] [?] dipd roll< F″
39 [L] ? [P] [F] roll< F″
40 [L] b [P] [F] roll< F″
43 Now we can write a branch:
45 F″ == [Ff] [Ft] branch
48 ------------------------------------
49 [L] [P] [F] b [Ff] [Ft] branch
51 The false case is easy:
56 ... [] [P] [F] pop popop
61 The true case is a little more fun:
65 We need to uncons that first term, run a copy of P, and recur (recurse?
66 I think re-curse means to "curse again" so it must be "recur".)
71 ... [X|Xs] [P] [F] [uncons] dipd Ft″
72 ... [X|Xs] uncons [P] [F] Ft″
73 ... X [Xs] [P] [F] Ft″
75 So now we run a copy of P:
77 ... X [Xs] [P] [F] Ft″
79 Ft″ == [dup dipd] dip Ft‴
81 ... X [Xs] [P] [F] Ft″
82 ... X [Xs] [P] [F] [dup dipd] dip Ft‴
83 ... X [Xs] [P] dup dipd [F] Ft‴
84 ... X [Xs] [P] [P] dipd [F] Ft‴
85 ... X P [Xs] [P] [F] Ft‴
87 And now all that remains is to recur on F:
91 ... X P [Xs] [P] [F] x
94 Collecting the definitions, we have:
97 F == F′ [Ff] [Ft] branch
102 Ft″ == [dup dipd] dip
107 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
122 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
125 3 true [-- [0 >] nullary] loop
127 5 [1 <] [] [dup --] [i +] genrec
131 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
137 -------------------------------------
138 [] [P] [E] [[F] R0] [R1] genrec
139 ------------------------------------- w/ K == [P] [E] [[F] R0] [R1] genrec
140 [] [P] [E] [[F] R0 [K] R1] ifte
143 P is applied nullary so it will just be:
147 to check the non-emptiness of the input list. When the input list is
148 empty, the output list is ready, but in the reverse order, so:
152 That leaves the non-empty case:
154 [X|Xs] [Ys] [F] R0 [K] R1
156 Here we want to uncons that X term, prepend it to a copy of the stack for
157 using infra on F, put the result on [Ys], and recur.
159 Let's keep it simple:
163 [X|Xs] [Ys] [F] [R0′] dipd R0″ [K] R1
164 [X|Xs] R0′ [Ys] [F] R0″ [K] R1
166 Let's concentrate on R0′:
168 R0′ == [stack] dip shift
171 ... [X|Xs] [stack] dip shift
172 ... [...] [X|Xs] shift
177 ... [X|...] [Xs] [Ys] [F] R0″ [K] R1
179 We want to use F on that stack we just made:
181 R0″ == [infra first] cons dipd R0‴
183 ... [X|...] [Xs] [Ys] [F] R0″ R0‴ [K] R1
184 ... [X|...] [Xs] [Ys] [F] [infra first] cons dipd R0‴ [K] R1
185 ... [X|...] [Xs] [Ys] [[F] infra first] dipd R0‴ [K] R1
186 ... [X|...] [F] infra first [Xs] [Ys] R0‴ [K] R1
187 ... [Y|...] first [Xs] [Ys] R0‴ [K] R1
188 ... Y [Xs] [Ys] R0‴ [K] R1
194 ... Y [Xs] [Ys] R0‴ [K] R1
195 ... Y [Xs] [Ys] roll< swons [K] R1
196 ... [Xs] [Ys] Y swons [K] R1
197 ... [Xs] [Y|Ys] [K] R1
203 ... [Xs] [Y|Ys] [K] R1
204 ... [Xs] [Y|Ys] [K] i
206 ... [Xs] [Y|Ys] [P] [E] [[F] R0] [R1] genrec
214 R0′ == [stack] dip shift
215 R0″ == [infra first] cons dipd R0‴
219 Now that we have the parts, we need to make the map combinator that takes
220 [F] and builds the genrec function:
223 -------------------------------------
224 [] [P] [E] [[F] R0] [R1] genrec
228 [] [P] [E] [[F] R0] [R1] genrec
229 [[F] R0] [[] [P] [E]] dip [R1] genrec
230 [F] [R0] cons [[] [P] [E]] dip [R1] genrec
234 map == [R0] cons [[] [P] [E]] dip [R1] genrec
236 So the source would be:
238 map [_map0] cons [[] [_map?] [_mape]] dip [i] genrec
241 _map0 [_map1] dipd _map2
242 _map1 [stack] dip shift
243 _map2 [infra first] cons dipd _map3
247 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
252 This is a tight set of primitives from the POV of implementation. You
253 can get nice performance improvements by implementing some additional
254 words (like uncons and rest) but these along with the defs.txt file are
257 and bool branch concat cons dip dup first i loop or pop stack swaack swap
258 + - * / % < > = >= <= <>
274 dup pop stack swaack swap