This is indeed actually a bug, not a feature! Static variables are not initialized correctly (and currently need to be explicited initialized outside the class definition). We hope to address this in the near future!
Ge,
I suspect you misread the exact issue under debate here. Consider;
class War
{
static int foo;
static Gain mix;
3 => static int bar;
}
foo is perfectly fine, I'm sure we all agree there. mix is a a problem and that line in that form won't fly; it needs to be initialised from outside of the class. We can get around that using something like this;
class War
{
static Gain @ mix;
static fun void init() {new Gain @=> mix;}
}
...that way we at least keep all of the definitions inside of the class and only need to call init() from outside. I think this is what you are refering to; this needs a fix and correct behaviour is quite clear.
The problem under debate is the "bar case". bar, as a member, will be initialised at the definition of the class, it just won't have the value 3 without a instance of the class. Maybe I'm misreading your post here, and you do see the setting of the value 3 as part of initialising bar in this case? As pointed out earlier, doing so is not without questions as we may also set the value using something like;
myFun() => static int bar; //or
myStaticFun() => static int bar; // or
myNonMemberFun() => static int bar;
...assuming all of those return a int. No problem arrises if all those do is return a int, but they may have side effects and might, in their definition, refer to non-build-in types, potentially leading to circular definitions and much more complicated demands on the order things are parsed in. Allowing this may lead to syntactically correct files that still can't be executed.
I think it may be fine if we only allow static member functions (of the given class) to set such values, but that would mean a extra syntactical constraint. That said; setting static constants would be very handy in -for example- determining the length of static UGen arrays for vm-wide routing without getting into magic numbers. Right now we can't do that and such numbers can't be defined as a part of the class they belong to without instantiating the class as well. This leads to some important numbers getting defined outside of the context in which they are important, which won't win any beauty awards; for that reason I sugest currently using something like my "init()" example above as that structure really helps when returning to code weeks later.
We can call the current situation a "bug" on the grounds of a line of code being only partially executed, but I don't think it's a simple bug where we can effortlessly say what should happen instead. One of my concerns is that we are very concerned with deterministic execution order in ChucK but that's no good if the execution order is very hard to predict.
Phew! :-)
Yours,
Kas.