Keywords in supercollider are weird

Continuing the discussion from How to get the method name in a method in a sc file?:

So supercollider actually has a load a keywords, by which I mean, identifiers (variables) that don’t need to be declared, but always have a value, some of these are more like global variables, but not environmental variables. In fact you can add your own very ‘keywords’ easily, as I’ll show in a moment.

I might have missed some off the list so do let me know!

First there are the psuedo-vars:

  • thisFunction
  • thisFunctionDef
  • thisMethod
  • thisProcess
  • thisThread

Then there are the grammar defined literals:

  • false
  • true
  • nil
  • inf
  • pi
  • while — this has a special implementation

Then there are grammar defined special identifiers:

  • this
  • super

Now things get interesting…

Turns out, anything declared as a const or classvar in Object is immediately accessible as a keyword in all contexts.

The classvars are:

  • currentEnvironment
  • topEnvironment
  • dependantsDictionary
  • uniqueMethods

Scary thing is you can reassign these even though they aren’t marked as writable.

a = 3;
a.addUniqueMethod(\foo, { 42 })
a.foo // 42
uniqueMethods = nil; // yes this line is valid in all contexts
a.foo // ERROR: Message 'foo' not understood.

The consts in Object are:

  • nl

Yes, nl is a keyword that you can type anywhere.

This means you can trivially add new const entries to Object to create your own keywords, with the caveat that they must be literals.

Object {
   ...
   const foo = \foo
}
// anywhere at any time
foo // \foo

You can’t easily add classvars to object as you need to edit the C++, but it is only one line in the initClasses function.

5 Likes

This is my new favourite way to break supercollider

Object {
   const thisProcess = \meow;
}
3 Likes

pi is another… - I knew 2pi worked but I didn’t realize 999pi was legal as well…