(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

Reply via email to