[chuck-users] Static bug

Tom Lieber tom at alltom.com
Thu Nov 26 13:29:46 EST 2009

2009/11/25 Kassen <signal.automatique at gmail.com>:
>> 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! :-)

Hey, it's a holiday here and I feel like rambling. Usually I edit
posts to be as short as possible, but not today! Today I give thanks
-- to words! Sorry, that's just how mailing lists work. Any dude can
just come on by and dump a lot of words into a lot of inboxes whenever
they feel like it. Like this.

So the idiom I follow is the initialize-after one that's been
mentioned a few times:

class War {
  // declarations and instance initialization
  static int foo;
  static Gain @ mix;
  static int bar;

// static initialization
3 => War.bar;
new Gain @=> War.mix;

It's not intuitive to write (until you're used to it), but it is to
read. It's clear that the static initialization happens once, right
after class declaration. The static variables can be considered
initialized anywhere in the class. There's no floating "War war;" to
get things rolling. If it's a public class, it's likely that this is
all that's in the file.

If the compiler can get static initializers working, that'd be great,
although having some statements execute once when the class is loaded
and some when a class is instantiated is weirdly non-regular, and has
issues like Kassen pointed out where it seems like you should be able
to use functions depending on instance variables in static
initializers due to code proximity and seeming scope.

I think other compilers just check that kind of thing. That's where my
rage in Java comes from, when a simple program grows to that breaking
point where it's too big for a single, static main() method and I have
to start making objects that Java will let me instantiate from that
static safety zone that can't be inner classes because those aren't
static, somehow, so I have to either make a second, non-static main or
open a second file to create the classes I need as public, or fill my
original class with a bunch of static methods and variables.

Man, that had absolutely nothing to do with ChucK.

Anyway, "static:" also suffers from this a little since to me it
doesn't imply the one way "can-use" relationship between static and
non-static initializers (non-static can use static, but not the other
way around). Or maybe I'm a little too used to { } being the only
characters that delimit scope. Unfortunately, that preference would
lead to something like:

class War {
  // class initialization
  int foo;
  Gain @ mix;
  3 => int bar;

  instance {
    // instance initialization
    4 => int baz;

    fun void screw_with_your_head() {
      <<< "screwing complete" >>>;

... which even I don't like, but I think is illustrative and funny.
Seems like a great way to make miserable the evenings of the
live-coders and totally break every ChucK class ever written. Or you
could pop everything left one brace level and almost be back to where
we started, except with static declarations outside and before the
class -- which is actually another way to handle static variables by
the way, take note. Less typing to boot.

int foo;
new Gain @=> Gain @ mix;
3 => int bar;

class War {
  4 => int baz;

Well, have a good one!

Tom Lieber

More information about the chuck-users mailing list