Section III: Computer Assisted Composition 
19 -Numbers, Operators, Music Functions 

Operators, Precedence 

The examples below combine numbers with operators +, /, -, and *. Evaluate (press Enter) 
each line separately. 

19.1. Operators (+, /, -, *) 
1+4 
8*9-5 
9-5*8 
9-(5*8) 

The last three expressions look similar, but have different results. The third is 8*9, then -5 = 
67, the fourth is 9-5 then * 8 = 32. The difference is precedence. Precedence is the order in 
which each operator and value is realized in the expression. Precedence in SC is quite simple; 
enclosures first, then left to right. Since the 8*9 comes first in the third expression it is 
calculated before the -5. In the line below it 9-5 is calculated first then multiplied by 8. The 
last line demonstrates how parentheses force precedence. First 5*8, then that result is 
subtracted from 9. 

Can you predict the result of each line before you evaluate the code? 

19.2. More operators 
1+2/4*6 
2/4+2*6 
(2 * 6) -5 
2 * (6 -5) 
Try these other binary operators and see what SC returns: > greater than, < less than, == 
equals, % modulo. 

19.3. Binary operators (>, <, ==, %) 
10 > 5 
170

5<1 

12 == (6*2) 

106%30 

The > (greater than) and < (less than) symbols return: true and false. SC understands that the 
number 10 is greater than 5 (therefore true) and 5 is not less than 1 (false). We will use this 
logic in later chapters. 

Modulo (%) is a very useful operator that returns the remainder of the first number after 
dividing by the second. For example, 43%10 will reduce 43 by increments of 10 until it is 
less than 10, returning what is left. 12946%10 is 6. A common musical application is a 
modulo 12, which reduces numbers to below 12, or an octave. 

Can you predict the results of these expressions? 

19.4. Predict 
(8+27)%6 

((22 + 61) * 10 )%5 

All of these examples use integers. Integers are whole numbers. (If you don't remember 
math, that's numbers used for counting items, without the decimal point: 1, 2, 3, 4, etc.) 
Numbers that use a decimal are called floating-point values. In SC you express integers by 
just writing the number (7, 142, 3452). Floating point values must have the decimal with 
numbers on both sides, even for values below 1: 5.142, 1.23, 456.928, 0.0001, 0.5 (not .0001 
or .5) 

Messages, Arguments, Receivers 

The way you get things done in smalltalk is to combine messages with arguments. The 
message usually has a meaningful name such as sum and is followed by parentheses that 
enclose arguments separated by commas. Following are typical messages used in computer 
music followed by a comment (//) that describes the returned value. In preveious chapters 
messages have used the syntax Object.message. This is called receiver notation. In the 
examples below I use functional notation: message(Object). 

19.5. Music related messages 
cos(34) //returns cosine 

abs(-12) //returns absolute value 

sqrt(3) //square root 

171

midicps(56) //given a midi number, this returns 
//the cycles per second in an equal tempered scale 
cpsmidi(345) //given cps, returns midi 
midiratio(7) //given a midi interval, returns ratio 
ratiomidi(1.25) //given a ratio, returns midi number 
rand(30) //returns a random value between 0 and 29 
rand2(20) //returns a random value between -30 and 30 
rrand(20, 100) //returns a random value between 20 and 100 

There are a few special terms in computer languages. Among them are nil, true, and false. 
These terms are used to test a value and have the computer do one operation if the outcome is 
true, and another if it is false. Try running this line of code 10 or 20 times and see how often 
it returns true, how often false. 

19.6. Coin 
coin(0.7) //returns a true 70% of the time, false 30% 
The examples above are all in functional notation. For receiver notation put the first 
argument (the first number in the parentheses) before the function name separated by a 
period (dot). 

19.7. Reciever notation (cos, coin, rand) 
30.cos //same as cos(30) 
0.7.coin //same as coin(0.7) 
20.rand //same as rand(20) 
7.midiratio 
// Binary functions have two arguments. 
min(6, 5) //returns the minimum of two values 
max(10, 100) //returns maximum 
round(23.162, 0.1) //rounds first argument to second argument 
// Arguments can be expressions 
min(5*6, 35) 
172

max(34 -10, 4) //returns the maximum of two values 
// Receiver notation 
6.min(5) //same as min(6, 5) 

It is also possible to nest functions and messages. Instead of two numbers as arguments 
inside the max function I can nest another function inside the parentheses. In the example 
below SC first calculates the maximum of 10 and 4, then the minimum of 2 and 5. The 
results, or the return of those two functions are used as arguments in the outer max. The 
second example chooses a random number between 0 and 100, then another random number 
between 0 and 13 (these are in receiver notation), then finds the maximum of those two 
values, then calculates the cycles per second using that number as a MIDI pitch. 

19.8. nesting (max, min, midicps, rand) 
max(max(10, 4), min(2, 5)) 
midicps(max(13.rand, 100.rand)) 
Practice, Music Calculator 

SC is useful even when you're not producing music34. I think of it as a music calculator. What 
was the frequency of an equal tempered Ab? Just launch SC and type 68.midicps. Here are 
some examples. 

19.9. Music calculator 
// Major scale frequencies 
([0, 2, 4, 5, 7, 9, 11, 12] + 60).midicps.round(0.01) 
// Major scale interval ratios 

[0, 2, 4, 5, 7, 9, 11, 12].midiratio.round(0.001) 

// Phrygian scale frequencies 
([0, 1, 3, 5, 7, 8, 10, 12] + 60).midicps.round(0.01) 
// Phrygian scale interval ratios 

[0, 1, 3, 5, 7, 8, 10, 12].midiratio.round(0.001) 

// Equal and Just Mixolydian scale compared
[0, 2, 3, 4, 5, 7, 9, 10, 12].midiratio.round(0.001)
[1/1, 9/8, 6/5, 5/4, 4/3, 3/2, 8/5, 7/4, 2/1].round(0.001)
// Just ratios (mixolydian) in equal tempered cents

34 Or should I say sound? These examples fall under the category of imaginary music. 

173

// (and therefor their deviation from equal temperament)
[1/1, 9/8, 6/5, 5/4, 4/3, 3/2, 8/5, 7/4, 2/1].ratiomidi.round(0.01)

// Retrograde of a 12-tone set
[0, 11, 10, 1, 9, 8, 2, 3, 7, 4, 6, 5].reverse

// Inversion of a 12-tone set
12 -[0, 11, 10, 1, 9, 8, 2, 3, 7, 4, 6, 5]

// And of course, retrograde inversion (see where I'm heading?
)
(12 -[0, 11, 10, 1, 9, 8, 2, 3, 7, 4, 6, 5]).reverse

// Random transpositions of a 12-tone set
([0, 11, 10, 1, 9, 8, 2, 3, 7, 4, 6, 5] + 12.rand)%12

// Random permutation of a 12-tone set (out of 479,001,600)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11].permute(479001600.rand) + 60

174

19. Exercises 
19.1. What is the result of each of these expressions?
9*10-20/
5
4+6*10
8*(5+10)
5*20%
4
20%4*
5
19.2. Change these to receiver notation (if functional) or functional (if receiver) 
20.max(5) 
rrand(10, 100) 
[10, 20, 40].choose 
175