Enabling type checks for Dart

Intro

Dart is an optionally typed language, which means it helps you if you add static types, but doesn't get in the way if you don't. Dart is designed to allow you to scale from simple scripts to large, complex applications, and optional types are a key feature for this vision.

Because types are optional, Dart programs must have the same runtime semantics with or without type statements. If the type statements are ignored during runtime, what good are they?

Think of type statements more like documentation or annotations for your program. Once added, these types are a terse way for you to express your intent to both your fellow humans and your fellow machines. Using the type annotations to express "x is a number" is a great way to clearly indicate what x is so other developers know how to use it. Compilers can use this annotation to warn you if you do something unnatural with x.

Example

Consider the following interface:

interface Util {
  add(a, b);
}

It's very hard to tell what the purpose of the add() method is. What type of arguments does it take?

You might think that adding comments is a good way to indicate your intent:

interface Util {
  /**
   * a is a number
   * b is a number
   */
  add(a, b);
}

Now your fellow humans have a better understanding of what to pass to add(). Unfortunately, the platform can't read those comments, so the compiler and editor can't help other developers with hints, code completion, and early warning.

So we recommend using types in method signatures and interfaces (the "surface area" of your code):

interface Util {
  num add(num a, num b);
}

Now it's clear that add() takes two numbers and return a number. No hidden comments necessary to convey this information, and both humans and machines benefit!

Benefiting from types

Dart programs run in two different modes: production mode and checked mode. In production mode, types annotations are ignored. However, in checked mode, the type annotations spring to life and provide helpful feedback.

To turn on checked mode, following these instructions:


  • for the VM: --enable_type_checks --enable_asserts
  • for Dartium:  DART_FLAGS='--enable_type_checks --enable_asserts' path/chrome
  • for frog: --enable_type_checks
You can find the VM and frog in the SDK. Dartium, which is Chromium with an embedded Dart VM, is available as a binary download.

For the test, I'll use this simple script:

num add(num a, num b) => a + b;

main() {
  print(add("hello", "world"));
}

If you run this in production mode, the program will complete and will print "helloworld". Not exactly what you want, nor what the original developer intended for add().

Note: soon, you won't be able to concatenate Strings with +. The example above is just illustrative.

However, running in checked mode will display this:

Unhandled exception:
'/Users/sethladd/tmp/types/types.dart': Failed type check: line 1 pos 13: type 'OneByteString' is not assignable to type 'num' of 'a'.
 0. Function: '::add' url: '/Users/sethladd/tmp/types/types.dart' line:1 col:13
 1. Function: '::main' url: '/Users/sethladd/tmp/types/types.dart' line:4 col:11


When production mode?

You might be wondering, why should you ever turn on production mode? When is the right time for production mode?

As the name implies, production mode is for running your apps in production. The main benefit is possible performance improvements, due to disabled type assertions.

Summary

Dart's optional typing helps you to scale your program from simple scripts to large complex applications. The types can be considered annotations, helping express your intent to both humans and machines.

Turning on checked mode will enable the type assertions and checks, which help with early warnings if the system detects problems from type mismatches. You can run Dartium, frog (the Dart to JavaScript compiler), and the virtual machine in checked mode.

We highly encourage you to use checked mode during any and all development. Only when you ship to production should you use production mode, where there are possible performance improvements because types checks are disabled.

Popular posts from this blog

Lists and arrays in Dart

Converting Array to List in Scala

Null-aware operators in Dart