(Jonathan and I are preparing to write a tutorial. We're trying to collect and confirm some key points of X10 programming that will need to go in the tutorial. Here's one. Igor fixed some problems in it, and Vijay asked us to post it here, so here it is. Comments welcome: places where I've gotten it wrong, questions that I ought to answer and haven't, or your own experiences.)
I keep getting this one wrong, myself, and it's endlessly frustrating. Guideline: X10 coding generally goes better if you don't write types when you can avoid it. The reason is: X10 infers better types than you're likely to come up with ... usually. For example: val R1 : Rail[Int] = Rail.make[Int](3); The type I wrote isn't the best description -- it omits some information that the compiler knows, and will want to have to use later on. (R1 is correct code, because the value of Rail.make[Int](3) is -- among other things -- a Rail[Int].) In this case, it omits the fact that [1,2,3] is *here*, and that it's three elements long. So the best type is: val R2 : Rail[Int]!{length==3} = Rail.make[Int](3); The difference isn't obvious until you go to use them: You can't call methods on R1 because the compiler doesn't know where it is. You can call methods on R2 because it's here, from that '!' qualifier. When the type inference engine is firing on all cylinders, it will write down everything that the compiler knows about values. So, val R3 = [1,2,3]; will automatically pick up the best type that the compiler can figure out, which in this case is the same as R2's type. So, most of the time, when you write a 'val', you should leave off the type -- unless you're prepared to write down the type and all the constraints you're going to need later on. Caveats: * This doesn't work for vars, just vals. Vars don't do type inference. * It probably doesn't always get all relevant information -- e.g., you need to put output constraints on constructors you write to make info clear. [This needs tutorial examplage.] Fortunately the X10 library has fully-detailed constructors. Unfortunately some operations on library objects don't preserve all the type information: val R = ([1..2,3..4] as Region) || [5..6,7..8]; // oops, the type of R is now Region, not Region(2){rect} * If you want type information for some reason of your own, like documenting your code or making your hypotheses explicit, you have to be prepared to write the full types. (In 2.0.1 we may get a variant of 'val' which lets you write partial types and still get the benefits of automatically-inferred types; stay tuned.) ------------------------------------------------------------------------------ This SF.Net email is sponsored by the Verizon Developer Community Take advantage of Verizon's best-in-class app development support A streamlined, 14 day to market process makes app distribution fast and easy Join now and get one step closer to millions of Verizon customers http://p.sf.net/sfu/verizon-dev2dev _______________________________________________ X10-users mailing list X10-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/x10-users