Literals are values which have a direct syntactic representation. The following sections describe the types of literals that can be represented.
An integer is any series of digits optionally preceded by a minus sign:
-13 666 2112 96
A float is one or more decimal digits followed by a decimal point followed by one or more decimal digits. You must have digits on both sides of the decimal point. This distinguishes floating point numbers from integer expressions like 8.rand.
Examples of floats:
0.39 98.6 1.0 -0.5
Exponential notation is also supported:
1.2e4 1e-4
The constant pi can be appended to a number to create a floating point constant:
pi 2pi 0.5pi -0.25pi
Numbers can also be written in radices other than base 10 up to base 36. The radix is specified in base 10 followed by the letter 'r' followed by the value written in that radix using characters 0-9,A-Z, or a-z, for digit values from 0 to 35. For example you can write hexidecimal numbers as follows:
16rF0 16rA9FF
Binary numbers can be written as follows:
2r01101011
Floating point values may also be specified in any base:
12r4A.A
Integer numbers as scale degrees supports accidentals notation by adding the suffixes s for sharp and b for flat. Accidentals are represented as floating point values.
2s == 2.1 // scale degree two, sharp 2b == 1.9 // scale degree two, flat 2ss == 2.2 // scale degree two, double sharp 2bb == 1.8 // scale degree two, double flat
Up to four:
2ssss == 2.4 2bbbb == 1.6
With negative scale degrees it reverses:
-2s == -1.9 -2b == -2.1 -2ss == -1.8 -2bb == -2.2
Accidentals can also specify cents deviation up to 499 cents:
2b50 == 1.95 // scale degree two, fifty cents flat 2s204 == 2.204 // scale degree two, 204 cents sharp
Characters are preceded by a dollar sign:
$A $B $C
Tab, linefeed, carriage return, and backslash are preceded by a backslash:
$\t $\n $\r $\\
A symbol is written as a string enclosed in single quotes. examples of symbols:
'x' 'aiff' 'BigSwiftyAndAssoc' 'nowhere here' 'somewhere there' '.+o*o+.'
A symbol consisting of a single word can be written with a preceeding backslash.
\x \aiff \BigSwiftyAndAssoc
Strings are written in double quotes:
"This is a string."
If two or more strings are lexically adjacent, then they combine into a larger string:
"This" " is " "also a " "string."
Strings may span more than one line. If so, then the new line characters become part of the string:
"This is also a string. "
Names of methods and variables begin with a lower case alphabetic character, followed by zero or more alphanumeric characters:
var abc, z123, func;
Class names always begin with a capital letter followed by zero or more alphanumeric characters.
Object Point Synth SinOsc Pan2
The singular instances of the classes True, False and Nil are written as the words true, false, nil and inf.
x = true; y = false; z = nil;
Arrays of literals are created at compile time and are written with a # preceeding the array as follows:
#[1, 2, 'abc', "def", 4]
Literal Arrays must be used as is and may not be altered at run time.
In literal Arrays names are interpreted as symbols. This is not the case in regular Arrays, where they are interpreted as variable names:
#[foo, bar] // this is legal; an Array of Symbols [foo, bar] // this is only legal if foo and bar have been declared as variables
Arrays and other collections may also be created dynamically which is explained in Collection. Using a literal Array is faster than building an array dynamically every time you need it.
When nesting literal arrays, only the outermost literal array needs the '#' character.
#[[1, 2, 3], [4, 5, 6]]
Literal Arrays can be useful for things such as tables of constants, for example note names:
(
// build a table of note names
var table = ();
value {
var semitones = [0, 2, 4, 5, 7, 9, 11];
var naturalNoteNames = ["c", "d", "e", "f", "g", "a", "b"];
(0..9).do {|o|
naturalNoteNames.do {|c, i|
var n = (o + 1) * 12 + semitones[i];
table[(c ++ o).asSymbol] = n;
table[(c ++ "s" ++ o).asSymbol] = n + 1;
table[(c ++ "ss" ++ o).asSymbol] = n + 2;
table[(c ++ "b" ++ o).asSymbol] = n - 1;
table[(c ++ "bb" ++ o).asSymbol] = n - 2;
};
};
};
// translate note names to midi keys
table.atAll(#[c4, e4, gs4, c5, e5, gs5, c6])
)
There is no theoretical limit on the number of literals in a single function, if those literals are used as freestanding objects. (Of course, there remains the practical limits of system memory and the processor time required to keep track of all the objects.)
The following are a special category of literal, called selectors.
{ })Here, there are four selectors: SinOsc, ar, play and the entire function containing SinOsc.
{ SinOsc.ar(440, 0, 0.1) }.play;
A single function may contain no more than 256 selectors. If this limit is exceeded, a compiler error is printed:
ERROR: Selector table too big: too many classes, method selectors or function definitions in this function. Simplify the function.
Selectors are counted only toward the function definition currently being compiled.
{ x.foo };
{ x.bar };
Both functions contain exactly one selector. They are separate functions. The use of "foo" in one function doesn't affect the number of selectors in another function.
{
var f = { |n|
if(n > 1) { n * f.value(n-1) } { 1 }
};
f.value(10);
}.value;
The outer function includes only the selector value. The other selectors -- >, *, - -- belong to the inner function definition and don't affect the outer function's number of selectors.
So, one possible easy way to work around the limitation is to break up a large block of code into several functions that are value'd successively:
{
... a bunch of code ...
}.value;
{
... a bunch of code ...
}.value;
{
... a bunch of code ...
}.value;