polymorphism: better names for .binaryValue and .booleanValue are .asInteger and...
[supercollider.git] / Help / Language / J_concepts_in_SC.html
blobd65ef142cd0b4bd3b423617008be44ad77efbfa0
1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2 <html>
3 <head>
4 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5 <meta http-equiv="Content-Style-Type" content="text/css">
6 <title></title>
7 <meta name="Generator" content="Cocoa HTML Writer">
8 <meta name="CocoaVersion" content="824.42">
9 <style type="text/css">
10 p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #a71e12}
11 p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; min-height: 12.0px}
12 p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco}
13 span.s1 {color: #0019b7}
14 span.s2 {color: #000000}
15 span.s3 {color: #a71e12}
16 span.s4 {color: #606060}
17 span.s5 {color: #326f17}
18 span.Apple-tab-span {white-space:pre}
19 </style>
20 </head>
21 <body>
22 <p class="p1">// The J programming language is a successor of APL. &lt;http://www.jsoftware.com&gt;</p>
23 <p class="p1">// These languages are made for processing arrays of data and are able to express</p>
24 <p class="p1">// complex notions of iteration implicitly.</p>
25 <p class="p1">// The following are some concepts borrowed from or inspired by J.</p>
26 <p class="p1">// Thinking about multidimensional arrays can be both mind bending and mind expanding.</p>
27 <p class="p1">// It may take some effort to grasp what is happening in these examples.</p>
28 <p class="p2"><br></p>
29 <p class="p1">// iota fills an array with a counter</p>
30 <p class="p3">z = <span class="s1">Array</span>.iota(2, 3, 3);</p>
31 <p class="p1"><span class="s2">z.rank; </span>// 3 dimensions</p>
32 <p class="p1"><span class="s2">z.shape; </span>// gives the sizes of the dimensions</p>
33 <p class="p1"><span class="s2">z = z.reshape(3, 2, 3); </span>// reshape changes the dimensions of an array</p>
34 <p class="p1"><span class="s2">z.rank; </span>// 3 dimensions</p>
35 <p class="p3">z.shape;</p>
36 <p class="p2"><br></p>
37 <p class="p1">// fill a 2D array</p>
38 <p class="p3"><span class="s1">Array</span>.fill2D(3,3,{1.0.rand.round(0.01)});</p>
39 <p class="p2"><br></p>
40 <p class="p3"><span class="s1">Array</span>.fill2D(2,3,{<span class="s1">|i,j|</span> i@j});</p>
41 <p class="p2"><br></p>
42 <p class="p1">// fill a 3D array</p>
43 <p class="p3"><span class="s1">Array</span>.fill3D(2,2,2,{1.0.rand.round(0.01)});</p>
44 <p class="p2"><br></p>
45 <p class="p3"><span class="s1">Array</span>.fill3D(2,2,2,{<span class="s1">|i,j,k|</span> `[i,j,k]});</p>
46 <p class="p2"><br></p>
47 <p class="p2"><br></p>
48 <p class="p1">// using dup to create arrays</p>
49 <p class="p3">(1..4) dup: 3;</p>
50 <p class="p3">100.rand dup: 10;</p>
51 <p class="p3">{100.rand} dup: 10;</p>
52 <p class="p3">{100.rand} dup: 3 dup: 4;</p>
53 <p class="p3">{{100.rand} dup: 3} dup: 4;</p>
54 <p class="p3">{<span class="s1">|i|</span> i.squared} dup: 10;</p>
55 <p class="p3">{<span class="s1">|i|</span> i.nthPrime} dup: 10;</p>
56 <p class="p2"><br></p>
57 <p class="p1">// ! is an abbreviation of dup</p>
58 <p class="p3">(1..4) ! 3;</p>
59 <p class="p3">100.rand ! 10;</p>
60 <p class="p3">{100.rand} ! 10;</p>
61 <p class="p3">{100.rand} ! 3 ! 4;</p>
62 <p class="p3">{{100.rand} ! 3} ! 4;</p>
63 <p class="p3">{<span class="s1">|i|</span> i.squared} ! 10;</p>
64 <p class="p3">{<span class="s1">|i|</span> i.nthPrime} ! 10;</p>
65 <p class="p2"><br></p>
66 <p class="p1">// other ways to do the same thing:</p>
67 <p class="p1"><span class="Apple-tab-span"> </span>// partial application</p>
68 <p class="p3"><span class="s1">_</span>.squared ! 10;</p>
69 <p class="p3"><span class="s1">_</span>.nthPrime ! 10;</p>
70 <p class="p2"><br></p>
71 <p class="p1"><span class="Apple-tab-span"> </span>// operating on a list</p>
72 <p class="p3">(0..9).squared;</p>
73 <p class="p3">(0..9).nthPrime;</p>
74 <p class="p2"><br></p>
75 <p class="p1">// operator adverbs</p>
76 <p class="p1">// Adverbs are a third argument passed to binary operators that modifies how they iterate over</p>
77 <p class="p1">// SequenceableCollections or Streams.</p>
78 <p class="p1">// see the Adverbs help file</p>
79 <p class="p3">[10, 20, 30, 40, 50] + [1, 2, 3]; <span class="s3">// normal</span></p>
80 <p class="p3">[10, 20, 30, 40, 50] +.f [1, 2, 3]; <span class="s3">// folded</span></p>
81 <p class="p3">[10, 20, 30, 40, 50] +.s [1, 2, 3]; <span class="s3">// shorter</span></p>
82 <p class="p3">[10, 20, 30, 40, 50] +.x [1, 2, 3]; <span class="s3">// cross</span></p>
83 <p class="p3">[10, 20, 30, 40, 50] +.t [1, 2, 3]; <span class="s3">// table</span></p>
84 <p class="p2"><br></p>
85 <p class="p1">// operator depth.</p>
86 <p class="p1">// J has a concept called verb rank, which is probably too complex to understand and implement<span class="Apple-converted-space"> </span></p>
87 <p class="p1">// in SC, but operator depth is similar and simpler.</p>
88 <p class="p1">// A binary operator can be given a depth at which to operate</p>
89 <p class="p1">// negative depths iterate the opposite operand.</p>
90 <p class="p1">// These are better understood by example.</p>
91 <p class="p1">// It is not currently possible to combine adverb and depth.</p>
92 <p class="p3">z = <span class="s1">Array</span>.iota(3,3);</p>
93 <p class="p3">y = [100, 200, 300];</p>
94 <p class="p3">z + y;</p>
95 <p class="p1"><span class="s2">z +.0 y; </span>// same as the above. y added to each row of z</p>
96 <p class="p1"><span class="s2">z +.1 y; </span>// y added to each column of z</p>
97 <p class="p1"><span class="s2">z +.2 y; </span>// y added to each element of z</p>
98 <p class="p1"><span class="s2">z +.-1 y; </span>// z added to each element of y</p>
99 <p class="p2"><br></p>
100 <p class="p1">// deepCollect operates a function at different dimensions or depths in an array.</p>
101 <p class="p3">z = <span class="s1">Array</span>.iota(3, 2, 3);</p>
102 <p class="p3">f = {<span class="s1">|item|</span> item.reverse };</p>
103 <p class="p3">z.deepCollect(0, f);</p>
104 <p class="p3">z.deepCollect(1, f);</p>
105 <p class="p3">z.deepCollect(2, f);</p>
106 <p class="p2"><br></p>
107 <p class="p3">f = {<span class="s1">|item|</span> item.stutter };</p>
108 <p class="p3">z.deepCollect(0, f);</p>
109 <p class="p3">z.deepCollect(1, f);</p>
110 <p class="p3">z.deepCollect(2, f);</p>
111 <p class="p2"><br></p>
112 <p class="p1">// slice can get sections of multidimensional arrays.</p>
113 <p class="p1">// nil gets all the indices of a dimension</p>
114 <p class="p3">z = <span class="s1">Array</span>.iota(4,5);</p>
115 <p class="p3">z.slice(<span class="s1">nil</span>, (1..3));</p>
116 <p class="p3">z.slice(2, (1..3));</p>
117 <p class="p3">z.slice((2..3), (0..2));</p>
118 <p class="p3">z.slice((1..3), 3);</p>
119 <p class="p3">z.slice(2, 3);</p>
120 <p class="p2"><br></p>
121 <p class="p3">z = <span class="s1">Array</span>.iota(3,3,3);</p>
122 <p class="p3">z.slice([0,1],[1,2],[0,2]);</p>
123 <p class="p3">z.slice(<span class="s1">nil</span>,<span class="s1">nil</span>,[0,2]);</p>
124 <p class="p3">z.slice(1);</p>
125 <p class="p3">z.slice(<span class="s1">nil</span>,1);</p>
126 <p class="p3">z.slice(<span class="s1">nil</span>,<span class="s1">nil</span>,1);</p>
127 <p class="p3">z.slice(<span class="s1">nil</span>,2,1);</p>
128 <p class="p3">z.slice(<span class="s1">nil</span>,1,(1..2));</p>
129 <p class="p3">z.slice(1,[0,1]);</p>
130 <p class="p3">z.flop;</p>
131 <p class="p2"><br></p>
132 <p class="p1">// sorting order</p>
133 <p class="p2"><br></p>
134 <p class="p1"><span class="s2">z = {100.rand}.dup(10); </span>// generate a random array;</p>
135 <p class="p1">// order returns an array of indices representing what would be the sorted order of the array.</p>
136 <p class="p3">o = z.order;<span class="Apple-converted-space"> </span></p>
137 <p class="p1"><span class="s2">y = z[o]; </span>// using the order as an index returns the sorted array</p>
138 <p class="p2"><br></p>
139 <p class="p1">// calling order on the order returns an array of indices that returns the sorted array to the<span class="Apple-converted-space"> </span></p>
140 <p class="p1">// original scrambled order</p>
141 <p class="p3">p = o.order;<span class="Apple-converted-space"> </span></p>
142 <p class="p3">x = y[p];</p>
143 <p class="p2"><br></p>
144 <p class="p1">// bubbling wraps an item in an array of one element. it takes the depth and levels as arguments.</p>
145 <p class="p3">z = <span class="s1">Array</span>.iota(4,4);</p>
146 <p class="p3">z.bubble;</p>
147 <p class="p3">z.bubble(1);</p>
148 <p class="p3">z.bubble(2);</p>
149 <p class="p3">z.bubble(0,2);</p>
150 <p class="p3">z.bubble(1,2);</p>
151 <p class="p3">z.bubble(2,2);</p>
152 <p class="p1">// similarly, unbubble unwraps an Array if it contains a single element.</p>
153 <p class="p3">5.unbubble;</p>
154 <p class="p3">[5].unbubble;</p>
155 <p class="p3">[[5]].unbubble;</p>
156 <p class="p3">[[5]].unbubble(0,2);</p>
157 <p class="p3">[4,5].unbubble;</p>
158 <p class="p3">[[4],[5]].unbubble;</p>
159 <p class="p3">[[4],[5]].unbubble(1);</p>
160 <p class="p3">z.bubble.unbubble;</p>
161 <p class="p3">z.bubble(1).unbubble(1);</p>
162 <p class="p3">z.bubble(2).unbubble(2);</p>
163 <p class="p2"><br></p>
164 <p class="p1">// laminating with the +++ operator</p>
165 <p class="p1">// the +++ operator takes each item from the second list and appends it to the corresponding item</p>
166 <p class="p1">// in the first list. If the second list is shorter, it wraps.</p>
167 <p class="p3">z = <span class="s1">Array</span>.iota(5,2);</p>
168 <p class="p3">z +++ [77,88,99];</p>
169 <p class="p3">z +++ [[77,88,99]];</p>
170 <p class="p3">z +++ [[[77,88,99]]];</p>
171 <p class="p3">z +++ [ [[77]],[[88]],[[99]] ];</p>
172 <p class="p1">// same as:</p>
173 <p class="p3">z +++ [77,88,99].bubble;</p>
174 <p class="p3">z +++ [77,88,99].bubble(0,2);</p>
175 <p class="p3">z +++ [77,88,99].bubble(1,2);</p>
176 <p class="p2"><br></p>
177 <p class="p3">z +++ [11,22,33].pyramidg;</p>
178 <p class="p3">z +++ [11,22,33].pyramidg.bubble;</p>
179 <p class="p3">z +++ [[11,22,33].pyramidg];</p>
180 <p class="p3">z +++ [[[11,22,33].pyramidg]];</p>
181 <p class="p2"><br></p>
182 <p class="p2"><br></p>
183 <p class="p3">(</p>
184 <p class="p3">z = (1..4);</p>
185 <p class="p3">10.do {<span class="s1">|i|</span><span class="Apple-converted-space"> </span></p>
186 <p class="p3"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>z.pyramid(i+1).postln;</p>
187 <p class="p3"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>z.pyramidg(i+1).postln;</p>
188 <p class="p3"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s4">""</span>.postln;</p>
189 <p class="p3">};</p>
190 <p class="p3">)</p>
191 <p class="p2"><br></p>
192 <p class="p1">// reshapeLike allows you to make one nested array be restructured in the same manner as another.</p>
193 <p class="p2"><br></p>
194 <p class="p3">a = [[10,20],[30, 40, 50], 60, 70, [80, 90]];</p>
195 <p class="p3">b = [[1, 2, [3, 4], [[5], 6], 7], 8, [[9]]];</p>
196 <p class="p3">a.reshapeLike(b);</p>
197 <p class="p3">b.reshapeLike(a);</p>
198 <p class="p2"><br></p>
199 <p class="p1">// If the lengths are different, the default behaviour is to wrap:</p>
200 <p class="p2"><br></p>
201 <p class="p3">a = [[10,20],[30, 40, 50]];</p>
202 <p class="p3">b = [[1, 2, [3, 4], [[5], 6], 7], 8, [[9]]];</p>
203 <p class="p3">a.reshapeLike(b);</p>
204 <p class="p2"><br></p>
205 <p class="p1">// but you can specify other index operators:</p>
206 <p class="p2"><br></p>
207 <p class="p3">a.reshapeLike(b, <span class="s5">\foldAt</span>);</p>
208 <p class="p2"><br></p>
209 <p class="p3">a.reshapeLike(b, <span class="s5">\clipAt</span>);</p>
210 <p class="p2"><br></p>
211 <p class="p3">a.reshapeLike(b, <span class="s5">\at</span>);</p>
212 <p class="p2"><br></p>
213 <p class="p1">// allTuples will generate all combinations of the sub arrays</p>
214 <p class="p3">[[1, 2, 3], [4, 5], 6].allTuples;</p>
215 <p class="p3">[[1, 2, 3], [4, 5, 6, 7], [8, 9]].allTuples;</p>
216 <p class="p2"><br></p>
217 <p class="p2"><br></p>
218 <p class="p2"><br></p>
219 </body>
220 </html>