Outdated sclang features: mul/add and Mix



For a somewhat math-centric language like SCLang, the operator precedence rules are pretty evil. I don’t even want to begin counting how often I’ve been bitten by those.

This is a very common complaint. But if you look into higher mathematics, all those elementary mathematics rules are not taken for granted anymore, but had to be made explicit. This is why in languages like APL or Smalltalk, the solution is simply to keep all precedence left to right – you can rely on it. If you want to be clear, use parentheses.

The alternative is something like Haskell, then you can really change how the language looks. But you need to know the definition of an operator in order to be able to know how what argument is called on what function. This is a lot of work, if you are confronted with new libraries all the time…


I’m well aware of the strangeness that exists out there (octonions anyone? who needs associativity anyway), but the overwhelming majority of all supercollider code ever written doesn’t use anything but bread and butter maths. (Except it doesn’t because in sclang universe 1 + 2 * 3 == 9 whereas 2 * 3 + 1 == 7).

There’s really no need to implement haskell to have sane operator precedence rules, as pretty much every “conventional language” out there proves on a daily basis.

That’s not to say that the rules should be changed now, because a lot of code already relies on them (violating the principle of least astonishment if you ask me, but no one ever does :smiley: ), but it’s certainly not a design decision I would have applauded had I had something to say in it…

Or you could write the whole thing in FORTH…

LISP doesn’t have, or need, operator rules. I’d prefer a DSL in LISP for building synth defs, but that might just be my own personal damage.

The reason that SuperCollider has it’s precedence rules is because that’s how UGens work (and pretty much ave to work) - and so the language enforces them universally so that you don’t get inconsistencies.

Years of debugging code in multiple languages has resulted in me using parentheses pretty religiously for anything mathematical to minimize surprises, so it’s never really caused me any issues in SuperCollider. Oddly that goes double for Haskell, even though I’m happy with point free style generally.

For example if I was doing a code review and saw that someone had replaced the top bit of code with the bottom line - I would flag it. The top line is far more readable and is less likely to result in bugs further down the road.

@cian are you aware of overtone written in clojure?

Yeah overtone seems kind of neat.

I want to say that these methods make coding so much easier.

Maybe it would be more correct to say, that .range will take the default output range of the UGen as its expected input? Which is exactly what one usually and most of the time works with. In those other cases, yes, .linlin and its variants are another convenience method everybody should know!

exprange is also useful. Takes a linear range and makes it exponential. Incredibly useful.

also .unipolar and .bipolar are neat when you just want to limit your synth to 0, 1 or make a unipolar ugen to -1, 1

Also cl-collider in Common Lisp:

1 Like

I’ve seen the OM-Sharp project, and the integration of the GUI with Common Lisp is so beautifully done, that I think if J. Bresson or someone integrates the supercollider lisp client there, it will be a masterpiece. I’ve already suggested him.

I’ve been working on extending keyword arguments in the language SCLang, ClassLib: Add *kwargs by JordanHendersonMusic · Pull Request #6339 · supercollider/supercollider · GitHub

With it, we could do something like this, hiding the names…

   ar{ |freq, phase...args, kwargs|
         var kwdic = kwargs.asPairs;

         args[0] !? { |mul| kwdic[\mul]} = mul };
         args[1] !? { |add| kwdic[\add]} = add };

         kwdic[\mul]) !? { |mul| ... };
         kwdic[\add]) !? { |add| ... };

Not saying we should… but that we could.

1 Like