On 11/7/2010 1:02 AM, Walter Bright wrote: > Jonathan M Davis wrote: >> Going C# or Java's route forces the programmer to initialize variables >> even in cases where they know that it's not necessary (which is >> annoying but may or may not be worth it), > > Correct. It's not that doing flow analysis is hard, it's that it's > impossible to do it correctly. So you wind up with wishy-washy messages > that p "might not" be initialized, which is what the Java compiler does > for this: > > class A > { > public void foo() > { > Object p; > if (m) > p = new Object(); > if (m) > p.toString(); // <-- p might not have been initialized > } > boolean m; > } > > It even errors out if you write it as: > > class A > { > public void foo() > { > Object p; > if (m) > p = new Object(); > if (p != null) // <-- p might not have been initialized > p.toString(); > } > boolean m; > } > > Note that the error message is on the null check!
I know what your mean, but the example is flawed: public void foo() { if (m) { Object p = new Object(); p.toString(); } } ... Thing is, I don't think you really _need_ flow analysis to implement nonnulity. The simplest way is to disallow creation of unitialized nonnull variables. I think it would work, but without some clever syntax such rule would be painful to follow for the programmers. Things like these would be prohibited, for example Duck d; if (b) d = new Duck(); else d = new DuckSubclass(); Seems like a big loss, but it really isn't. Duck d = b ? new Duck() : new DuckSubclass(); But ternary ops are not generic, unless you chain them which is super-ugly. Is there nothing that can fix this? Delegates probably can: enum Dri { one, two, three}; Dri s = Dri.two; int x = { if (s == Dri.one) return 1; else if (s == Dri.two) return 2; else return 3; }(); This works. I'm not sure how efficient it is, but that would solve the issue with initialization without any path analysis. If there was a clearer, more efficient syntax for this, it would work even better. int x = do { if (s == Dri.one) return 1; else if (s == Dri.two) return 2; else return 3; };