104 lines
2.9 KiB
Text
104 lines
2.9 KiB
Text
title:: Adverbs for Binary Operators
|
|
summary:: modify behaviour of binary operators
|
|
categories:: Language, Collections
|
|
related:: Classes/SequenceableCollection, Classes/Stream
|
|
|
|
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.
|
|
|
|
section:: Adverbs and SequenceableCollections
|
|
|
|
Normally when you add two arrays like this:
|
|
code::
|
|
[10, 20, 30, 40, 50] + [1, 2, 3]
|
|
::
|
|
You get this result:
|
|
code::
|
|
[ 11, 22, 33, 41, 52 ]
|
|
::
|
|
A new array is created which is the length of the longer array and items from each array are added together by wrapped indexing.
|
|
|
|
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.
|
|
|
|
subsection:: adverb 's'
|
|
|
|
The first adverb is 's' which means 'short'. The add operation now returns the shorter of the two arrays.
|
|
code::
|
|
[10, 20, 30, 40, 50] +.s [1, 2, 3]
|
|
::
|
|
returns:
|
|
code::
|
|
[ 11, 22, 33 ]
|
|
::
|
|
|
|
subsection:: adverb 'f'
|
|
|
|
Another adverb is 'f' which uses folded indexing instead of wrapped:
|
|
code::
|
|
[10, 20, 30, 40, 50] +.f [1, 2, 3]
|
|
::
|
|
returns:
|
|
code::
|
|
[ 11, 22, 33, 42, 51 ]
|
|
::
|
|
|
|
subsection:: adverb 't'
|
|
|
|
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.
|
|
code::
|
|
[10, 20, 30, 40, 50] +.t [1, 2, 3]
|
|
::
|
|
returns:
|
|
code::
|
|
[ [ 11, 12, 13 ], [ 21, 22, 23 ], [ 31, 32, 33 ], [ 41, 42, 43 ], [ 51, 52, 53 ] ]
|
|
::
|
|
|
|
subsection:: adverb 'x'
|
|
|
|
The cross adverb 'x' is like table, except that the result is a flat array:
|
|
code::
|
|
[10, 20, 30, 40, 50] +.x [1, 2, 3]
|
|
::
|
|
returns:
|
|
code::
|
|
[ 11, 12, 13, 21, 22, 23, 31, 32, 33, 41, 42, 43, 51, 52, 53 ]
|
|
::
|
|
|
|
section:: Adverbs and Streams
|
|
|
|
There is currently one adverb defined for streams. This is the cross adverb, 'x'.
|
|
|
|
Normally when you add two streams like this:
|
|
code::
|
|
p = (Pseq([10, 20]) + Pseq([1, 2, 3])).asStream;
|
|
Array.fill(3, { p.next });
|
|
::
|
|
you get this:
|
|
code::
|
|
[ 11, 22, nil ]
|
|
::
|
|
The items are paired sequentially and the stream ends when the earliest stream ends.
|
|
|
|
The cross adverb allows you to pair each item in the first stream with every item in the second stream.
|
|
code::
|
|
p = (Pseq([10, 20]) +.x Pseq([1, 2, 3])).asStream;
|
|
Array.fill(7, { p.next });
|
|
::
|
|
the result is:
|
|
code::
|
|
[ 11, 12, 13, 21, 22, 23, nil ]
|
|
::
|
|
|
|
You can string these together. Every item in the left stream operand is "ornamented" by the right stream operand.
|
|
code::
|
|
p = (Pseq([100, 200]) +.x Pseq([10, 20, 30]) +.x Pseq([1, 2, 3, 4])).asStream;
|
|
Array.fill(25, { p.next });
|
|
|
|
[ 111, 112, 113, 114, 121, 122, 123, 124, 131, 132, 133, 134,
|
|
211, 212, 213, 214, 221, 222, 223, 224, 231, 232, 233, 234, nil ]
|
|
::
|
|
|
|
Sound example:
|
|
code::
|
|
Pbind(\dur, 0.17, \degree, Pwhite(0, 6) +.x Pseq([[0, 2, 4], 1, [0, 2], 3])).trace.play
|
|
::
|
|
|