1 title:: Adverbs for Binary Operators
2 summary:: modify behaviour of binary operators
3 categories:: Language, Collections
4 related:: Classes/SequenceableCollection, Classes/Stream
6 Adverbs are a third argument passed to binary operators that modifies how they iterate over link::Classes/SequenceableCollection::s or link::Classes/Stream::s. The idea for adverbs is taken from the J programming language which is a successor of APL.
8 section:: Adverbs and SequenceableCollections
10 Normally when you add two arrays like this:
12 [10, 20, 30, 40, 50] + [1, 2, 3]
16 [ 11, 22, 33, 41, 52 ]
18 A new array is created which is the length of the longer array and items from each array are added together by wrapped indexing.
20 Using adverbs can change this behavior. Adverbs are symbols and they follow a '.' (dot) after the binary operator. Adverbs can be applied to all binary operators.
22 subsection:: adverb 's'
24 The first adverb is 's' which means 'short'. The add operation now returns the shorter of the two arrays.
26 [10, 20, 30, 40, 50] +.s [1, 2, 3]
33 subsection:: adverb 'f'
35 Another adverb is 'f' which uses folded indexing instead of wrapped:
37 [10, 20, 30, 40, 50] +.f [1, 2, 3]
41 [ 11, 22, 33, 42, 51 ]
44 subsection:: adverb 't'
46 The table adverb 't' makes an array of arrays where each item in the first array is added to the whole second array and the resulting arrays are collected.
48 [10, 20, 30, 40, 50] +.t [1, 2, 3]
52 [ [ 11, 12, 13 ], [ 21, 22, 23 ], [ 31, 32, 33 ], [ 41, 42, 43 ], [ 51, 52, 53 ] ]
55 subsection:: adverb 'x'
57 The cross adverb 'x' is like table, except that the result is a flat array:
59 [10, 20, 30, 40, 50] +.x [1, 2, 3]
63 [ 11, 12, 13, 21, 22, 23, 31, 32, 33, 41, 42, 43, 51, 52, 53 ]
66 section:: Adverbs and Streams
68 There is currently one adverb defined for streams. This is the cross adverb, 'x'.
70 Normally when you add two streams like this:
72 p = (Pseq([10, 20]) + Pseq([1, 2, 3])).asStream;
73 Array.fill(3, { p.next });
79 The items are paired sequentially and the stream ends when the earliest stream ends.
81 The cross adverb allows you to pair each item in the first stream with every item in the second stream.
83 p = (Pseq([10, 20]) +.x Pseq([1, 2, 3])).asStream;
84 Array.fill(7, { p.next });
88 [ 11, 12, 13, 21, 22, 23, nil ]
91 You can string these together. Every item in the left stream operand is "ornamented" by the right stream operand.
93 p = (Pseq([100, 200]) +.x Pseq([10, 20, 30]) +.x Pseq([1, 2, 3, 4])).asStream;
94 Array.fill(25, { p.next });
96 [ 111, 112, 113, 114, 121, 122, 123, 124, 131, 132, 133, 134,
97 211, 212, 213, 214, 221, 222, 223, 224, 231, 232, 233, 234, nil ]
102 Pbind(\dur, 0.17, \degree, Pwhite(0, 6) +.x Pseq([[0, 2, 4], 1, [0, 2], 3])).trace.play