• jon@schemawound.com

Supercollider Tweets: Background / Tips

Updated 11/20/2012: Added 7 new tips courtesy of Nathaniel Virgo

I have previously made two blog posts showing some of my Supercollider tweets (Part 1 and Part 2). I posted these up without any real explanation and I wanted to spend a little time talking about why and how I have been creating these.

My main interest has been in the extreme limitation of trying to fit interesting code into 140 characters. Limitations often push you into artistic directions you might have never explored otherwise, this has been the main reason behind my interest in contributing to themed compilations such as SIGNALVOID and those put out by Waxen Wings.

Another benefit is the 140 character limitation forces you to explore areas of Supercollider you may have never explored otherwise. When each character matters you sometimes have to dig through the help files to find an alternate way of accomplishing your goals.

Supercollider is an ideal language for the task, it is full of syntactic sugar allowing you to express the same concept many different way. I have found a number of different useful tricks to use when trying to shorten code to fit within a tweet.


Receiver Notation vs. Functional Notation

In Supercollider you have a choice between two different style of sending messages to objects. You can sometimes save several characters by switching from one form to another.

These two statements are equivalent:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
100.rand
rand(100)
100.rand rand(100)
100.rand
rand(100)

So are these:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
{SinOsc.ar(440)}.play
play{SinOsc.ar(440)}
{SinOsc.ar(440)}.play play{SinOsc.ar(440)}
{SinOsc.ar(440)}.play
play{SinOsc.ar(440)}

Stereo Trick
!2 can be used as a simple trick to make a mono signal into stereo

These two statements are equivalent:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
play{SinOsc.ar([440,440])}
play{SinOsc.ar(440)!2}
play{SinOsc.ar([440,440])} play{SinOsc.ar(440)!2}
play{SinOsc.ar([440,440])}
play{SinOsc.ar(440)!2}

Assigning Ugens to Variables
If you are using the same Ugen several times you may be able to save space by assigning it to a variable and calling your .ar and .kr methods on the variable

These two statements are equivalent:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
play{;DFM1.ar(FreeVerb.ar(FreeVerb.ar(GVerb.ar(Dust.ar(9),10,3,0.5),1,1)*SinOsc.ar(60),1,1)*SinOsc.ar(150),SinOsc.kr([0.1,0.17]).range(900,9999))}
play{x=FreeVerb;y=SinOsc;DFM1.ar(x.ar(x.ar(GVerb.ar(Dust.ar(9),10,3,0.5),1,1)*y.ar(60),1,1)*y.ar(150),y.kr([0.1,0.17]).range(900,9999))}
play{;DFM1.ar(FreeVerb.ar(FreeVerb.ar(GVerb.ar(Dust.ar(9),10,3,0.5),1,1)*SinOsc.ar(60),1,1)*SinOsc.ar(150),SinOsc.kr([0.1,0.17]).range(900,9999))} play{x=FreeVerb;y=SinOsc;DFM1.ar(x.ar(x.ar(GVerb.ar(Dust.ar(9),10,3,0.5),1,1)*y.ar(60),1,1)*y.ar(150),y.kr([0.1,0.17]).range(900,9999))}
play{;DFM1.ar(FreeVerb.ar(FreeVerb.ar(GVerb.ar(Dust.ar(9),10,3,0.5),1,1)*SinOsc.ar(60),1,1)*SinOsc.ar(150),SinOsc.kr([0.1,0.17]).range(900,9999))}
play{x=FreeVerb;y=SinOsc;DFM1.ar(x.ar(x.ar(GVerb.ar(Dust.ar(9),10,3,0.5),1,1)*y.ar(60),1,1)*y.ar(150),y.kr([0.1,0.17]).range(900,9999))}

Changing Values
Sometimes you can save a character by changing a value to take up one less character

These two statements are not equivalent but are close enough for most purposes:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
play{SinOsc.ar(1000)}
play{SinOsc.ar(999)}
play{SinOsc.ar(1000)} play{SinOsc.ar(999)}
play{SinOsc.ar(1000)}
play{SinOsc.ar(999)}

Shortcut Method / Classes
You can often find a shortcut method of class that will allow you to accomplish your goals using much less code.

These two statements are equivalent:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Routine{"x".postln;1.wait;"y".postln}.play
fork{"x".postln;1.wait;"y".postln}
Routine{"x".postln;1.wait;"y".postln}.play fork{"x".postln;1.wait;"y".postln}
Routine{"x".postln;1.wait;"y".postln}.play
fork{"x".postln;1.wait;"y".postln}

Array Shortcuts
You can save quite a lot of space by creating arrays in the following way

These two statements are equivalent:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
[1,2,3,4,5,6,7,8,9,10]
(1..10)
[1,2,3,4,5,6,7,8,9,10] (1..10)
[1,2,3,4,5,6,7,8,9,10]
(1..10)

So are these:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
[3,6,9,12,15,18,21,24,27,30]
(1..10)*3
[3,6,9,12,15,18,21,24,27,30] (1..10)*3
[3,6,9,12,15,18,21,24,27,30]
(1..10)*3

Method Chaining
Look for opportunities to chain methods

These two statements are equivalent:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
play{x=SinOsc.ar(100);x.clip2(0.5)}
play{SinOsc.ar(100).clip2(0.5)}
play{x=SinOsc.ar(100);x.clip2(0.5)} play{SinOsc.ar(100).clip2(0.5)}
play{x=SinOsc.ar(100);x.clip2(0.5)}
play{SinOsc.ar(100).clip2(0.5)}

Shortcut Syntax for Functions
The shortcut syntax for functions can save quite a lot of space when used properly.

These two statements are equivalent:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
{|x|x.isPrime}!10
_.isPrime!10
{|x|x.isPrime}!10 _.isPrime!10
{|x|x.isPrime}!10
_.isPrime!10

So are these:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
play{Mix(SinOsc.ar((0..100)))}
play{Mix(SinOsc.ar(_)!100)}
play{Mix(SinOsc.ar((0..100)))} play{Mix(SinOsc.ar(_)!100)}
play{Mix(SinOsc.ar((0..100)))}
play{Mix(SinOsc.ar(_)!100)}

Take Advantage Of The Lack Of Operator Precedence (Submitted by Nathaniel Virgo)
Supercollider reads all math equations from left to right instead of following operator precedence, this can allow you to avoid adding parenthesis in many places.

These two statements are equivalent:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
a*(b+c)
b+c*a
a*(b+c) b+c*a
a*(b+c)
b+c*a

Use Exponentiation Instead Of .exprange (Submitted by Nathaniel Virgo)
Supercollider reads all math equations from left to right instead of following operator precedence, this can allow you to avoid adding parenthesis in many places.

These two statements are equivalent:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
SinOsc.kr(1).exprange(10,40)
2**SinOsc.kr(1)*20
SinOsc.kr(1).exprange(10,40) 2**SinOsc.kr(1)*20
SinOsc.kr(1).exprange(10,40)
2**SinOsc.kr(1)*20

it can be fiddly to work out the parameters, but you can evaluate the following 2 statements to get the min and max values:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
2**-1*20
2**1*20
2**-1*20 2**1*20
2**-1*20
2**1*20

Use CuspN.ar Or CuspL.ar Instead Of WhiteNoise.ar (Submitted by Nathaniel Virgo)
It doesn’t sound quite the same but it has a much shorter name.


Use Scientific Notation (Submitted by Nathaniel Virgo)
These two statements are equivalent:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
2000
2e3
2000 2e3
2000
2e3

And these:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
0.001
1e-3
0.001 1e-3
0.001
1e-3

Use Division (Submitted by Nathaniel Virgo)
These two statements are equivalent:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
x*0.1
x/10
x*0.1 x/10
x*0.1
x/10

And this might be close enough:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
x/9
x/9
x/9

Assign Variables Inside Statements (Submitted by Nathaniel Virgo)
These two statements are equivalent:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
play{x=Saw.ar;RLPF.ar(x)+x}
play{RLPF.ar(x=Saw.ar)+x}
play{x=Saw.ar;RLPF.ar(x)+x} play{RLPF.ar(x=Saw.ar)+x}
play{x=Saw.ar;RLPF.ar(x)+x}
play{RLPF.ar(x=Saw.ar)+x}

Use Weird Syntax For Methods (Submitted by Nathaniel Virgo)
This one is only useful occasionally, because it only works if the method has exactly one argument, but these are equivalent:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
play{SinOsc.ar(440)}
play{SinOsc ar:440}
play{SinOsc.ar(440)} play{SinOsc ar:440}
play{SinOsc.ar(440)}
play{SinOsc ar:440}

Conclusion
While many of these tips are useful for shortening code to fit within a tweet they can also make your code much more difficult to read. I would recommend you take care if you choose to implement these techniques in your regular Supercollider code. Please feel free to share any other tips you have in the comments.