Since I understand that there are API changes coming for SC 3.15.0, I wondered if now might be a good time to look at increasing some of the fixed limits within SC.
(Sorry if these have already been discussed somewhere - I am not a developer.)
Classvars
When updating TX Modular (which is a large project with many classes), I found that I had used too many classvars and had to refactor all my classes by using dictionaries to hold multiple class variables within one object (thanks HJH for suggestion). This worked but took a fair bit of time.
I wondered if this limit was fixed or if it could be increased?
Function and Synthdef args/vars/classes
There seems to be a 256 limit to the number of args and vars within a Function. This is also true for the number of classes used.
You can reduce the number of vars by using 1 dictionary to hold many vars. But still sometimes more than 256 args are needed.
This makes it hard to make large synthdefs with lots of controls. I have sometimes had to use multiple Synthdefs to do what I want.
Could this limit be increased (e.g to 256 x 16)?
ServerOptions
I wonder if the defaults should be increased, specifically for:
numWireBufs - I quite often bump into the 64 default limit.
memSize - 8192 seems low for current hardware.
Are there any other (visible/hidden) limits in SC which could also be considered?
Changing the things youāve mentioned requires adding or altering the bytecodes. Iām currently not working on the interpreter, Iām reworking the compiler so we can have good error messages finally. I donāt think this would be high on the priority list though because there are ways around it.
Re: limits on class vars and function args+vars ā one reason why this hasnāt been changed is because: if your class or function is large enough that you need 300 variables, then it almost certainly should be broken down into smaller pieces.
Thereās nothing significant about a 256-var limit, except that the index fits within 8 bits. The issue is really risk vs benefit. Thereās always risk in changing the interpreterās internals. It may be worth it if thereās enough benefit to users.
The benefit would be that users have more freedom to structure their code as they see fit. But the design strategies this would open up are all of a sort that computer science has rejected for decades, and which are universally discouraged.
If you need 300 variables in your class, chances are that itās a god object: āA God Object is a class that knows too much or does too much. It is characterized by having an excessive number of methods, attributes, or dependenciesā¦ā (btw this page looks like AI text, but at least this bit is ok). Hitting a limit is an indication that some redesign, breaking the job down into smaller components, would be a good idea.
Similarly, some professionals say that, ideally, a function or method should fit on one screen (and some are more strict than that, suggesting at most 10-15 lines per function/method). Otherwise, itās too long and complex. I certainly donāt follow this rule to the letter, but if itās passing 100, 150 lines, itās in the back of my mind that āthis functionās a bit out of control.ā If the variable declarations alone fill an editor panel, itās time to modularize and encapsulate.
Iām sympathetic to the case that this perhaps shouldnāt be SCās decision to make. At the same time, enabling the construction of unwieldy, difficult-to-maintain monster functions also strikes me as an illusory benefit.
Ahhhh⦠I had forgotten about SynthDesc msgFuncs.
There is actually no limit on the number of controls in the server:
// barfs with a SynthDesc error,
// but it does actually write the file
(
d = SynthDef(\lottaControls, {
var ctlNames = Array.fill(5000, { |i| ("ctl" ++ i).asSymbol });
var ctls = Control.names(ctlNames).kr(Array.fill(5000, 0));
Out.kr(1000, ctls.sum)
}).writeDefFile;
)
s.boot;
s.sendMsg("/d_load", SynthDef.synthDefDir +/+ "lottaControls.scsyndef");
x = Synth(\lottaControls);
// press ctrl-shift-t
NODE TREE Group 0
1 group
1001 lottaControls
ctl0: 0 ctl1: 0 ctl2: 0 ctl3: 0 ctl4: 0 ctl5 ... ctl4996: 0 ctl4997: 0 ctl4998: 0 ctl4999: 0
x.free;
msgFunc is useful for Events, but not really for any other reason.
So we should probably change that hard error into a warning. SynthDesc and its msgFunc are not strictly required for baseline SynthDef usage.
Edit: I can also see in my head a way to de-optimize msgFunc for large numbers of controls. It would be slower but probably better than just choking with an error. Point being that thereās no reason why a limit on function arguments should limit the number of controls in a SynthDef (and Iām thinking it would be better for the code to make the effort to handle it, rather than just erroring out).
(TBH I donāt know what Iād do with a 300-control SynthDef, though.)
Well, I had a crack at it tonight, but didnāt get all the way there, and now the IDE is in a state where itās refusing to reindent a method after I added a level of braces.
makeOneMsgFunc { |controlNames, suffix, index = 0, limit = 250|
var names = 0;
var string;
if(index < controlNames.size) {
string = String.streamContents {|stream|
var controlName, name, name2;
Tab should obviously push the last line here forward by one tab, but itās not doing anything. Everything compiles, I donāt have broken braces anywhere, just IDE failed.
Not gonna deal with unrelated bugs right now. Will pick this up again maybe tomorrow, maybe Sunday.
Thanks for info and advice.
Good to know about using named controls instead of args.
Iām definitely guilty of god objects - in fact I have a whole pantheon of them!
Sometimes things start small, but keep expanding - I donāt always remember to refactor sooner rather than later.
Best,
Paul