Added help for Pen and updated some other docs
[supercollider.git] / HelpSource / Guides / J-concepts-in-SC.schelp
blob3db66bc77f6a51c646e7a7b4b9075aa2c3e01dfe
1 title:: J concepts in SC
2 summary:: An overview of concepts borrowed from J
3 categories:: Language
5 The J programming language is a successor of APL. (http://www.jsoftware.com)
6 These languages are made for processing arrays of data and are able to express
7 complex notions of iteration implicitly.
9 The following are some concepts borrowed from or inspired by J.
10 Thinking about multidimensional arrays can be both mind bending and mind expanding.
11 It may take some effort to grasp what is happening in these examples.
13 section:: Filling arrays
14 iota fills an array with a counter
15 code::
16 z = Array.iota(2, 3, 3);
17 z.rank; // 3 dimensions
18 z.shape; // gives the sizes of the dimensions
19 z = z.reshape(3, 2, 3); // reshape changes the dimensions of an array
20 z.rank; // 3 dimensions
21 z.shape;
24 fill a 2D array
25 code::
26 Array.fill2D(3,3,{1.0.rand.round(0.01)});
28 Array.fill2D(2,3,{|i,j| i@j});
31 fill a 3D array
32 code::
33 Array.fill3D(2,2,2,{1.0.rand.round(0.01)});
35 Array.fill3D(2,2,2,{|i,j,k| `[i,j,k]});
38 section:: Creating arrays
39 using dup to create arrays
40 code::
41 (1..4) dup: 3;
42 100.rand dup: 10;
43 {100.rand} dup: 10;
44 {100.rand} dup: 3 dup: 4;
45 {{100.rand} dup: 3} dup: 4;
46 {|i| i.squared} dup: 10;
47 {|i| i.nthPrime} dup: 10;
49 ! is an abbreviation of dup
50 code::
51 (1..4) ! 3;
52 100.rand ! 10;
53 {100.rand} ! 10;
54 {100.rand} ! 3 ! 4;
55 {{100.rand} ! 3} ! 4;
56 {|i| i.squared} ! 10;
57 {|i| i.nthPrime} ! 10;
60 other ways to do the same thing:
61 code::
62 // partial application
63 _.squared ! 10;
64 _.nthPrime ! 10;
66 // operating on a list
67 (0..9).squared;
68 (0..9).nthPrime;
71 section:: Operator adverbs
72 Adverbs are a third argument passed to binary operators that modifies how they iterate over
73 SequenceableCollections or Streams. See the link::Reference/Adverbs:: help file for more information.
74 code::
75 [10, 20, 30, 40, 50] + [1, 2, 3]; // normal
76 [10, 20, 30, 40, 50] +.f [1, 2, 3]; // folded
77 [10, 20, 30, 40, 50] +.s [1, 2, 3]; // shorter
78 [10, 20, 30, 40, 50] +.x [1, 2, 3]; // cross
79 [10, 20, 30, 40, 50] +.t [1, 2, 3]; // table
82 section:: Operator depth
83 J has a concept called verb rank, which is probably too complex to understand and implement in SC, but operator depth is similar and simpler.
84 A binary operator can be given a depth at which to operate. Negative depths iterate the opposite operand.
85 These are better understood by example. It is not currently possible to combine adverb and depth.
86 code::
87 z = Array.iota(3,3);
88 y = [100, 200, 300];
89 z + y;
90 z +.0 y; // same as the above. y added to each row of z
91 z +.1 y; // y added to each column of z
92 z +.2 y; // y added to each element of z
93 z +.-1 y; // z added to each element of y
96 subsection:: deepCollect
97 deepCollect operates a function at different dimensions or depths in an array.
98 code::
99 z = Array.iota(3, 2, 3);
100 f = {|item| item.reverse };
101 z.deepCollect(0, f);
102 z.deepCollect(1, f);
103 z.deepCollect(2, f);
105 f = {|item| item.stutter };
106 z.deepCollect(0, f);
107 z.deepCollect(1, f);
108 z.deepCollect(2, f);
111 section:: Sections of multidimensional arrays
112 slice can get sections of multidimensional arrays.
113 nil gets all the indices of a dimension.
114 code::
115 z = Array.iota(4,5);
116 z.slice(nil, (1..3));
117 z.slice(2, (1..3));
118 z.slice((2..3), (0..2));
119 z.slice((1..3), 3);
120 z.slice(2, 3);
122 z = Array.iota(3,3,3);
123 z.slice([0,1],[1,2],[0,2]);
124 z.slice(nil,nil,[0,2]);
125 z.slice(1);
126 z.slice(nil,1);
127 z.slice(nil,nil,1);
128 z.slice(nil,2,1);
129 z.slice(nil,1,(1..2));
130 z.slice(1,[0,1]);
131 z.flop;
134 section:: Sorting order
135 generate a random array:
136 code::
137 z = {100.rand}.dup(10);
139 order returns an array of indices representing what would be the sorted order of the array:
140 code::
141 o = z.order;
142 y = z[o]; // using the order as an index returns the sorted array
144 calling order on the order returns an array of indices that returns the sorted array to the
145 original scrambled order:
146 code::
147 p = o.order;
148 x = y[p];
151 section:: Bubbling
152 bubbling wraps an item in an array of one element. it takes the depth and levels as arguments.
153 code::
154 z = Array.iota(4,4);
155 z.bubble;
156 z.bubble(1);
157 z.bubble(2);
158 z.bubble(0,2);
159 z.bubble(1,2);
160 z.bubble(2,2);
162 similarly, unbubble unwraps an Array if it contains a single element.
163 code::
164 5.unbubble;
165 [5].unbubble;
166 [[5]].unbubble;
167 [[5]].unbubble(0,2);
168 [4,5].unbubble;
169 [[4],[5]].unbubble;
170 [[4],[5]].unbubble(1);
171 z.bubble.unbubble;
172 z.bubble(1).unbubble(1);
173 z.bubble(2).unbubble(2);
176 section:: Laminating with the +++ operator
177 the +++ operator takes each item from the second list and appends it to the corresponding item
178 in the first list. If the second list is shorter, it wraps.
179 code::
180 z = Array.iota(5,2);
181 z +++ [77,88,99];
182 z +++ [[77,88,99]];
183 z +++ [[[77,88,99]]];
184 z +++ [ [[77]],[[88]],[[99]] ];
185 // same as:
186 z +++ [77,88,99].bubble;
187 z +++ [77,88,99].bubble(0,2);
188 z +++ [77,88,99].bubble(1,2);
190 z +++ [11,22,33].pyramidg;
191 z +++ [11,22,33].pyramidg.bubble;
192 z +++ [[11,22,33].pyramidg];
193 z +++ [[[11,22,33].pyramidg]];
197 z = (1..4);
198 10.do {|i|
199     z.pyramid(i+1).postln;
200     z.pyramidg(i+1).postln;
201     "".postln;
206 section:: reshapeLike
207 reshapeLike allows you to make one nested array be restructured in the same manner as another.
208 code::
209 a = [[10,20],[30, 40, 50], 60, 70, [80, 90]];
210 b = [[1, 2, [3, 4], [[5], 6], 7], 8, [[9]]];
211 a.reshapeLike(b);
212 b.reshapeLike(a);
214 If the lengths are different, the default behaviour is to wrap:
215 code:
216 a = [[10,20],[30, 40, 50]];
217 b = [[1, 2, [3, 4], [[5], 6], 7], 8, [[9]]];
218 a.reshapeLike(b);
220 but you can specify other index operators:
221 code::
222 a.reshapeLike(b, \foldAt);
224 a.reshapeLike(b, \clipAt);
226 a.reshapeLike(b, \at);
229 section:: allTuples
230 allTuples will generate all combinations of the sub arrays
231 code::
232 [[1, 2, 3], [4, 5], 6].allTuples;
233 [[1, 2, 3], [4, 5, 6, 7], [8, 9]].allTuples;