Chapter 2. Getting to Work with Dart

In this chapter, you will get a firm grasp on how to program in Dart. The code and data structures in Dart and its functional principles are explained by exploring practical examples. We will look at the following topics:

  • Variables: if, how, and when to type them
  • What are the basic types that you can use?
  • Documenting your programs
  • How to influence the order of execution of a program
  • Using functions in Dart
  • How to recognize and catch errors and exceptions

You will see plenty of examples, we will also be revisiting the code from Chapter 1, Dart – A Modern Web Programming Language. Because most of this will be familiar to you, we will discuss these topics succinctly and emphasize only on the ones which are new or different. You can refer to http://www.dartlang.org/docs/dart-up-and-running/contents/ch02.html if you need more detailed explanations. We encourage you to play with the code examples, it is the best way to become familiar with Dart. The full API reference documentation is available at http://api.dartlang.org. Experiment in the Dart Editor to find out more if in doubt!

Variables – to type or not to type

In our first example (raising rabbits) in Chapter 1, Dart – A Modern Web Programming Language, we started by declaring a rabbitCount variable dynamically with var. Then, in the second version, we gave it a static int type (refer to the prorabbits_v1.dart and prorabbits_v2.dart files in Chapter 1, Dart – A Modern Web Programming Language) and concluded that typing is optional in Dart. This seems confusing and it has provoked a lot of discussion: "is Dart a dynamic language like Ruby or JavaScript, or a static language like Java or C#?" After all, some of us were raised in the (static) belief that typed variables are absolutely necessary to check whether a program is correct, a task mainly performed by the compiler (however, the Dart VM has no separate compiler step, and dart2js, the Dart to JS compiler, doesn't check types because JS is fully dynamic).

It turns out that no mainstream language actually has a perfect type system (static types don't guarantee program correctness) and that not letting a program run, because of an obscure type error, blocks the programmer's creativity. However, it is true that static type checks can prevent bugs. On the other hand, the dynamic belief states that typing variables hinders the programmer's fantasy (and wears out the fingers). In their world, grave errors due to wrong types occur only when the program is running; to avoid such calamities, they have to rely on a rigorous unit testing discipline.

Dart takes a pragmatic middle stand: web programming is already accustomed to dynamically typed languages that are more flexible. Dart honors this and adheres to a system of optional or loose typing. You can start out by writing your code without types while you're still experimenting and doing quick prototyping. In a more advanced stage, you can annotate (some of) the code with types. This will enhance the readability of your code for your fellow developers and, as such, it will be additional documentation. Furthermore, it will allow the Dart analyzer tools to check the code for the types used and report possible errors, so it makes more useful developer tools as possible.

As the app becomes larger and more stable, types can be added to aid debugging and impose structure where desired, making the code more robust, documented, and more maintainable. Dart code can evolve from a simple, untyped experimental prototype to a complex, modular application with types. Moreover, as you will experience while working in the Dart Editor, with types, the IDE (Integrated Development Environment) will be able to suggest better autocompletion for the properties and methods of any code object. The two extremes (no typing or everything typed) are not encouraged.

Tip

In general, give everything in your code that can be seen publicly, a type (in the sense that it is visible in and can be used from outside the code, sometimes called the interface) such as top-level variables and functions, including their arguments. This way, other apps can use your code with increased safety.

Using var (or final or const) for an object leaves it untyped. However, in fact, Dart internally considers this object to be of type dynamic, the unknown type. The dynamic keyword is rarely seen in the code: it is used to denote a type that can change over the course of the running program or when the developer does not know the type of the variable.

To cope with this dilemma, Dart has two runtime modes (ways of executing programs):

  • Checked mode: This is typically used when you develop, debug, and test. The IDE will warn you when you misuse variables in a typed context (a tool called the dartanalyzer continuously checks your code, while saving and even while you type). The types are checked while executing assignments, passing arguments to a function, and returning a result from a function. By default, your program will also run in this mode, breaking the execution when a (typing) error occurs (you can change this behavior by navigating to Run | Manage Launches | VM settings and unchecking the Run in checked mode checkbox).
  • Production mode: This is when your program runs for real, that is, it is used by customers. Then, Dart runs as a fully dynamic language and ignores type information, giving a performance boost because the checks don't need to be performed.

Errors (indicated in the Editor by a white x in a red circle) prevent you from running the program. For example, delete an ; or } ending from some source code and see what happens.

Warnings (a black ! in a yellow triangle) indicate that the code might not work. For example, in the following code snippet (from chapter_2checked_mode.dart), a warning is indicated in line (1):

int age = 'Dart';                  (1)
print('$age'),

The warning sign is shown in front of the line and the string with the value 'Dart' underlined in yellow. If you hover the cursor over one of these, you will see the message: A value of type 'String' is not assignable to 'int'. If you try to run this example in the default checked mode in Dart Editor, you'll get the following output:

Unhandled exception:
type 'String' is not a subtype of type 'int' of 'age'.
#0  main (file:///E:/dart/Book/code/chapter_2/checked_mode/bin/checked_mode.dart:2:14)

However, if you uncheck and let it run in the production mode, it will run and the normal Dart output will appear in the console. Dart expects the developer to have thoroughly checked and tested the program.

Note

Warnings do not prevent you from running a program in the production mode in most cases.

A variable is just a nickname of an object; the same object can have multiple variables referring to it and a variable name can also switch from one object to another, like in the following code:

var name = 'John';
name = 'Lucy';    // name now refers to another String object

However, sometimes, you don't want this to happen, you want a variable to always point at the same object (such as immutable variables in functional languages or, in other words, a read-only variable). This is possible in Dart using the final keyword, like in the following code (refer to final.dart):

final name = 'John';
name = 'Lucy';         //   (1)  warning!

Now, line (1) generates a warning: Final variables cannot be assigned a value, but the execution is stopped even in the production mode! The var and final keywords used as such refer to a dynamic untyped variable, but final can also be used together with a type, as shown in the following code:

final String name = 'John';

The const keyword (which we used already in prorabbits_v2.dart in Chapter 1, Dart – A Modern Web Programming Language) like final also refers to something whose value cannot change, but it is more restricted. It must be a literal value (such as 100, Dart, or another const) or a calculation with known numbers, a so-called compile-time constant. For example, see the following code:

const NO_SECINMIN = 60;
const NO_SECINDAY = NO_SECINMIN * 60 * 24;

The following is an example that shows the difference:

int daysInWeek = 7;
final fdaysInYear = daysInWeek * 52;
const DAYSINYEAR =  daysInWeek * 52;  //  (2) error!

Now, line (2) gives an error:

'const' variables must be constant value.

To summarize it, types are not used for performance optimization and they don't change the program behavior, but they can help you write and maintain your code; a little typing goes a long way. A combination of tool support, static analysis, checked mode assertions, and unit tests can make you feel just as safe in Dart as in any statically typed language while being more productive.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.114.28