SuperCollider? It’s a programming environment designed for live digital signal processing, audio manipulation and algorithmic composition - making music, in other words. It is also contains a fully-fledged, dynamic, object-oriented language strongly influenced by both Smalltalk and functional programming, and as such it has a fair bit in common with Ruby.
There’s nothing like using two languages a lot (which I do) to get you comparing their finer details. Here’s what I have come to see differently about Ruby from coding in SC, and a few things I miss in Ruby that are present in SC. Maybe I’ll follow it up in the future, and do it the other way round.
Punctuation can be beautiful after all
Amongst a beginning Ruby programmer’s first acts, still flushed with the excitement of escaping from Java or PHP, will be to quite consciously throw away the habit of finishing each line of code with a semi-colon. And why not? They bugged me for years too, being obviously unnecessary in 99% of cases, cluttering up the page and and causing countless exceptions and failed builds when misplaced. And basically, for no good reason.
How many semi-colons do you see in Ruby code? Not a whole lot, in my experience. It’s almost like they’re omitted in order to somehow punish Java, perhaps deservedly.
SuperCollider requires the semi-colon at the end of (most) lines, and I used to feel it a bit of a pain. But semi-colons have kind of grown on me. Perhaps it’s because of SC’s strong functional programming paradigms, which means that it’s easier to chain multiple messages together than Ruby, even while splitting them across multiple lines.
SCWindow.new("A window!", Rect(20, 20, 300, 300))
.alwaysOnTop_( true )
.onClose_{ "Goodbye!".postln }
.userCanClose_( false )
.front
;
Most people seem to hide the semi-colon away. I prefer to give it pride of place, hanging it off the end of the indentation like a tear-drop.
The semi-colon is dead… Long live the semi-colon.
Syntactic sugar, SC style
Assuming iteration over a list - or range - makes a lot of sense. Actually, this isn’t syntactic sugar at all - just sensible proxying of messages - but it certainly feels like it.
Ruby:
(1..10).to_a.collect{ |num| num.squared }
# Ruby version >= 1.9
(1..10).to_a.collect(&:squared)
#=> [ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81 ]
SuperCollider:
(1..10).squared #=> [ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81 ]
Also worth a mention is SC’s ! notation, as an alternative to Object#dup. This can often be used to fill an array.
Ruby
Array.new(10){ rand(10) }
SuperCollider
{ 10.rand } ! 10
Partial application
Partial application allows the creation of functions from implicit input data - that is, call a method sending less than the required number of arguments. This is a trick picked up from functional languages such as Haskell. There, however, it’s better known as currying.
It can be (vaguely) comparable, in effect, to Symbol#to_proc in Rails (and Ruby 1.9), but is endlessly more flexible and powerful.
Each pair of lines are equivalent:
(1..10).collect{ |number| number.postln };
(1..10).collect(_.postln);
(1..10).collect {|x| Polar(x, pi) };
(1..10).collect(Polar(_, pi));
There are ways to approximate this kind of thing in Ruby, but none which look (to me) remotely as elegant.
Currying is cool.
Instant API
Why does coding in SC seem so quick and easy?
Maybe, its partly down to the speed of access to the language documentation. And it really is quick. Not sure how to scan each item of array? Just type Array, select it and hit CMD-D - up pops the SC documentation for Array class. Unsure of where a method you are calling is implemented in the class hierarchy? Select it and hit CMD-Y, and up pops a list of classes where the method is implemented, including extensions and plugins.
And best of all, select the name of any class and hit CMD-J. There in front of you is the source code for that actual class.
Now, it would be unfair to use this as a criticism of Ruby, as SC has an integrated editing environment which makes this sort of thing possible to build in as standard. But anybody who created a Ruby version of this system, perhaps as a plugin for TextMate, would be an instant superstar in my eyes, and I would think a good few others too.
My conclusions…
I am increasingly aware of how much Smalltalk is responsible for, and more and more interested in getting to know it a bit better in itself. Learning a new language never did anybody any harm.







2 Comments
Great post Rob, really enjoyed it!
BTW, as I have said before, Netbeans is very impressive with full RoR and SVN support. It’s at 6.1RCx now and it has great ‘intellisense’ behaviour for API lookup. It’s really fast too. Don’t forget to hold down the ctrl key and move the mouse over your code. Blue highlights appear on definitions it recognises. It has refactoring and everything. Just like java even… !
Hehe, a fair point. I meant to go deeper into the pro’s and con’s of IDEs, but it didn’t quite make it in.
I hear only good things about NetBeans. I really should give it a try. Watch this space.