Monday, May 21, 2012

Types and casting in Dart

Post by Seth Ladd

Bob Nystrom, engineer on the Dart team, posted a nice response to some questions posed to the mailing list about types, assignments, and casting. I thought this was a good way to phrase the issues, so I am posting here for others to find and enjoy.

Bob's reply to "Using num, one can assign a double to an integer without error or warning?":

"

  num n = 3.56;

Here, we assign a floating point literal whose static type is double to a
variable annotated to be type num. num is a supertype of double so you're
doing an upcast here. Like most languages an upcast is always safe and OK.
No warnings here.

  int x = n;

Here, the static type of n is num and we are assigning it to a variable
whose annotated type is int. int is a *sub*type of num, so in this case we
are doing a downcast. In most statically typed languages, you would need an
explicit cast operator, like:

  int x = (int)n;

Dart is different here. It has something called "assignment compatibility"
to determine which assignments are valid. Most languages just use the
normal subtyping rules for this: an assignment is safe if you assign from a
sub- to a supertype. Dart's assignment compatibility rules also allow
assigning from a super- to a subtype.

In other words, you can *downcast* implicitly in an assignment, without
needing any kind of explicit cast. So there's no *static* warning here.
However, if you run the code in checked mode and that downcast turns out to
be invalid (as it is here), you *will* get a type error at runtime when you
try to assign a double to x.

By analogy to Java, your code is similar to:

Object n = 3.56;
Integer x = (Integer)n;

A Java compiler will allow this, but it will fail at runtime. The main
difference from Dart is that in Java you need that explicit (Integer) cast
to downcast.
"


Thanks to Ross, Ladislav, and Bob, for chiming in and helping with the original question. You can chime in, too, in the Dart mailing list.