Math operators apply to many classes, including arrays and other collections.
Using a basic math operator on a Symbol swallows the operation (returns the symbol)
\symbol * 5
symbol
number + number
number - number
number * number
number / number
number % number
number ** number
number & number
number | number
number << number
number >> number
number +>> number
object == object
object === object
object != object
object !== object
Objects may be equivalent but not identical.
[1, 2, 3] == [1, 2, 3]
true
[1, 2, 3] === [1, 2, 3]
false // a and b are two different array instances with the same contents
a = b = [1, 2, 3];
a === b;
true // a and b are the same array instance
number < number
number <= number
number > number
number >= number
boolean && boolean
boolean || boolean
When a function is the second operand, these operators perform short-circuiting (i.e., the function is executed only when its result would influence the result of the operation). This is recommended for speed.
With and:
and or:
second-argument functions will be inlined. If you use &&
or ||
, no inlining will be done and performance will be slower.
xxxxxxxxxx
a = 1;
a == 1 and: { "second condition".postln; [true, false].choose }
second condition
true
a == 1 or: { "second condition".postln; [true, false].choose }
true
a != 1 and: { "second condition".postln; [true, false].choose }
false
a != 1 or: { "second condition".postln; [true, false].choose }
second condition
true
In this case, the second condition will cause an error if a is nil, because nil does not understand addition. a.notNil is a safeguard to ensure the second condition makes sense.
xxxxxxxxxx
a = nil;
a.notNil and: { "second condition".postln; (a = a+1) < 5 }
false
a = 10;
a.notNil and: { "second condition".postln; (a = a+1) < 5 }
second condition
false
object ++ object
collection +++ collection
collection @ index
collection @@ integer
collection @|@ integer
collection |@| integer
set & set
set | set
setA - setB
set -- set
xxxxxxxxxx
(setA -- setB) == ((setA - setB) | (setB - setA))
xxxxxxxxxx
a = Set[2, 3, 4, 5, 6, 7];
b = Set[5, 6, 7, 8, 9];
a - b
Set[ 2, 4, 3 ]
b - a
Set[ 8, 9 ]
((a-b) | (b-a))
Set[ 2, 9, 3, 4, 8 ]
a -- b
Set[ 2, 9, 3, 4, 8 ]
number @ number
xxxxxxxxxx
x @ y
// returns:
Point(x, y)
point @ point
xxxxxxxxxx
Point(left, top) @ Point(right, bottom)
// returns:
Rect(left, top, right-left, bottom-top)
ugen @ ugen
rect & rect
rect | rect
stream << object
xxxxxxxxxx
Post << "Here is a random number: " << 20.rand << ".\n";
Here is a random number: 13.
stream <<* collection
xxxxxxxxxx
Post << [0, 1, 2, 3]
[ 0, 1, 2, 3 ]
Post <<* [0, 1, 2, 3]
0, 1, 2, 3
stream <<< object
xxxxxxxxxx
Post <<< "a string"
"a string"
stream <<<* collection
object ? object
object ?? function
xxxxxxxxxx
a = [nil, 5];
10.do({ (a.choose ? 20.rand).postln });
10.do({ (a.choose ?? { 20.rand }).postln });
?? { }
is generally recommended. ?
always evaluates the second expression, even if its value will not be used. ??
evaluates the function conditionally (only when needed). If the function defines no variables, the function will be inlined for speed.
Especially useful when the absence of an object requires a new object to be created. In this example, it's critical that a new Slider not be created if the object was already passed in.
xxxxxxxxxx
f = { |slider, parent|
slider = slider ?? { Slider.new(parent, Rect(0, 0, 100, 20)) };
slider.value_(0);
};
If the first line inside the function instead read
xxxxxxxxxx
slider = slider ? Slider.new(parent, Rect(0, 0, 100, 20));
, a new slider would be created even if it is not needed, or used.
object !? function
xxxxxxxxxx
a = [10, nil].choose;
a !? { "ran func".postln };
// equivalent of:
if (a.notNil) { "ran func".postln };
Used when an operation requires a variable not to be empty.
xxxxxxxxxx
f = { |a| a + 5 };
f.value
// error: nil does not understand +
f = { |a| a !? { a+5 } };
f.value
nil // no error
f.value(2)
7
object ! number
object.dup(number)
xxxxxxxxxx
15 ! 5
[ 15, 15, 15, 15, 15 ]
If the object is a function, it behaves like Array.fill(number, function).
xxxxxxxxxx
{ 10.rand } ! 5
[ 8, 9, 3, 8, 0 ]
object -> object
expression <! expression
xxxxxxxxxx
a = 0;
0
// a is incremented twice, but the return value (1)
// comes from the first increment (0 + 1)
(a = a + 1) <! (a = a + 1)
1
a // a's value reflects both increments
2
function <> function
xxxxxxxxxx
f = { |a| a * 5 } <> {|a| a + 2 };
f.(10);
60 // == (10+2) * 5
An array as argument is passed through the chain:
xxxxxxxxxx
f.([10, 75, 512]);
[ 60, 385, 2570 ] // == ([10, 75, 512]+2) * 5
$
"ABC".at(0) == $A
''
or \
'abc' === \abc
""
"SuperCollider is the best"
[item, item...]
Set[item, item...]
#[item, item...]
(a:1, b:2)
Event[\a -> 1, \b -> 2]
)`
(backtick or backquote)`1 == Ref(1), `(a+1) == Ref(a+1)
\
xxxxxxxxxx
"abc\"def\"ghi"
abc"def"ghi
'abc\'def\'ghi'
abc'def'ghi
\t
\n
\l
\r
\\
{ }
#{ }
(_ * 2)
{ |a| a * 2 }
(see Partial Application)|a, b, c|
|a, b ... c|
#a, b, c = myArray
#a, b ... c = myArray
f.( )
f.(*argList)
f.(anArgName: value)
xxxxxxxxxx
f = { |a, b| a * b };
f.(2, 4);
f.(*[2, 4]);
f.(a: 2, b: 4);
SomeClass.[index]
myObject.method(*array)
obj1 method: obj2
obj1.method(obj2)
or method(obj1, obj2)
. This works only with single-argument methods like binary operators.Inside a class definition (see Writing Classes ):
xxxxxxxxxx
{
classvar <a, // Define a class variable with a getter method (for outside access)
>b, // Define a class variable with a setter method
<>c; // Define a class variable with both a getter and setter method
var <a, // Define an instance variable with a getter method (for outside access)
>b, // Define an instance variable with a setter method
<>c; // Define an instance variable with both a getter and setter method
// methods go here ...
}
These notations do not apply to variables defined within methods.
^someExpression
instVar_ { }
myObject.instVar = x;
(myObject.instVar_(x); x)
(a..b)
(a, b..c)
(..b)
(a..)
a[i..j]
a.copySeries(i, j)
(see ArrayedCollection: -copySeries)a[i, j..k]
a[1, 3..9]
retrieves array elements 1, 3, 5, 7, 9a[..j]
a.copySeries(0, j)
a[j..]
a.copySeries(i, a.size-1)
(this is OK--Array is finite)~
~abc
\abc.envirGet
~abc = value
\abc.envirPut(value)
(see Adverbs for Binary Operators )
e.g.:
xxxxxxxxxx
[1, 2, 3] * [2, 3, 4]
[ 2, 6, 12 ]
[1, 2, 3] *.t [2, 3, 4]
[ [ 2, 3, 4 ], [ 4, 6, 8 ], [ 6, 9, 12 ] ]
.s
.f
.t
.x
.0
.1