Product SiteDocumentation Site

11.3.8.5. "In This Case, Do This"

"Case" and "switch" structures look similar, but work in subtly different way. A "switch" structure is like a railway switch, allowing one train to be routed onto the right track, according to qualities of the train. A "case" structure, on the other hand, works like somebody trying to decide how to get to work. The person might ask themselves how far they are going, how long they have to get to work, how fast the available options are, what the available options cost, and so on. While in a "switch" structure, the path of execution is determined by examining only one Object, a "case" structure determines the path of execution based on any number of things.
Here is the syntax of a "case" structure:
case
   <replaceable>booleanFunction</replaceable> <replaceable>resultFunction</replaceable>
   <replaceable>booleanFunction</replaceable> <replaceable>resultFunction</replaceable>
   <replaceable>booleanFunction</replaceable> <replaceable>resultFunction</replaceable>
   <replaceable>booleanFunction</replaceable> <replaceable>resultFunction</replaceable>
;
Contemplate the following pseudo-code example, which represents a possible musical sitation, and a good use of the "case" structure.
(
   var coolFunction =
   {
      case
         { is there no music playing?
           AND people are in the room } { play music }
         { has the same song been playing for too long?
           OR is the song boring? } { change the song }
         { has everybody left the room? } { turn off the music }
         { has a song been requested? } { change to that song }
         { is the music too loud? } { lower the music's volume }
         { is the music too quiet? } { raise the music's volume }
         { is the music too fast? } { lower the music's tempo }
         { is the music too slow? } { raise the music's tempo }
         { is everything okay? } { wait for 10 seconds }
      ;
   };

   ( 5 == 5 ).while( coolFunction ); // executes coolFunction contiuously
)
It might seem like this example doesn't relate to a real SuperCollider programming situation, but in fact it might. If you could program Function's which determined all of those questions and all of the answers, this sort of "case" structure would be very helpful in a situation where a computer running SuperCollider were left in a room by itself, and expected to play music whenever anybody entered the room. Since five is always equal to five, the interpreter will run coolFunction forever. If the music needs adjustment in some way, the Function will adjust the music. If everything is okay, then the interpreter will wait for 10 seconds, and then the loop will cause the Function to be re-evaluated. Because many different criteria are evaluated in the "case" structure, this represents an efficient use of the structure.
"Case" structures can be used to do the same thing as "switch" structures, but it's usually less elegant solution. Also, it doesn't allow the interpreter to use an speed optimization that it would have used in an equivalent "switch" structure.
(
   var grade  = 11.rand + 1; // pseudo-randomly chooses 0 to 11, then adds 1 to give 1 to 12

   grade =
   case
      { 1 == grade; } { "D-" }
      { 2 == grade; } { "D" }
      { 3 == grade; } { "D+" }
      { 4 == grade; } { "C-" }
      { 5 == grade; } { "C" }
      { 6 == grade; } { "C+" }
      { 7 == grade; } { "B-" }
      { 8 == grade; } { "B" }
      { 9 == grade; } { "B+" }
      { 10 == grade; } { "A-" }
      { 11 == grade; } { "A" }
      { 12 == grade; } { "A+" }
   ;

   ("Your grade is" + grade).postln;
   nil;
)
This example is equivalent to one of the "switch" structure examples. This is not a good use of the "case" structure, because it requires a lot of code repetition.
Unlike a "switch" structure, a "case" structure will always follow the first case that evaluates to "true".
(
   case
      { 5 == 5; } { "one".postln; }
      { 5 == 5; } { "two".postln; }
      { 5 == 5; } { "three".postln; }
   ;

   nil;
)
This example will always result in "one" being printed.