×

Type System in Dart

Dart language is a type safety enabled language that uses static and dynamic type checking to match the value of the variable with its data type at the compile-time. This is also known as sound typing. Although the types are mandatory, data type annotations are optional because of the type interference.

The static type checking is really advantageous as it has the ability to find the errors at the compile time using the static analyser of Dart. Most of the bugs interpreted by the static analyser can be fixed by declaring the generic classes along with the type annotations.

The most common generic classes are the collection types which are as follows :

  1. List< T >
  2. Map< K, V >.

For example, in the following code the int_list( ) function prints an integer list, and main( ) functions creates a list and passes it to the int_list( ) function.

Consider the following code in Dart that uses collection types :

Example – 1 :

void int_list( List< int > a) => print( a ) ;
void main( ) 
{
  var list = [ ] ;
  list.add( 5 ) ;
  list.add( ' Yukta ' ) ;
  int_list( list ) ;
}

Output :

The code did not compile as it resulted in a type error on the list when the function int_list( ) function is called.

Error :

Error compiling to JavaScript:
Info: Compiling with sound null safety
Warning: Interpreting this as package URI, 'package:dartpad_sample/main.dart'.
lib/main.dart:7:13:
Error: The argument type 'List<dynamic>' can't be assigned to the parameter type 'List<int>'.
 - 'List' is from 'dart:core'.
  int_list( list ) ;
            ^
Error: Compilation failed.

The error highlights an unsound implicit cast from List< dynamic > to List< int >. The list variable has static type List< dynamic >. The definition of the list as

var list = [   ] 

does not provide clear information to the type analyzer to interpret the type argument more specific than dynamic. The int_list( ) function expects a parameter of type List< int >, causing a mismatch of types.

Let us try to debug the above code.

We must begin with specifying a type annotation ( < int > ) while defining that list. It should be like :

var list = < int >[  ] ;

But still, the problem isn't solved completely.  The analyzer throws an error that the string type value can not be assigned to the integer type parameters as in the line :

list.add( ' Yukta ' ) ;

To solve this problem as well, we must add only the integer value like :

list.add( 2 ) ;

This will result in code passing static analysis and running with no errors or warnings.

void int_list( List< int > num ) => print( num ) ;
void main( ) 
{
  var list = < int >[  ] ;
  
  // adding the integer elements to the list
  list.add( 5 ) ;
  list.add( 10 ) ;
  list.add( 15 ) ;
  
  // printing the list
  int_list( list ) ;
}

Output :

[5, 10, 15]

What is soundness?

Soundness helps to ensure that the program successfully gets over the invalid states. A sound type system used in the program enables that the program never gets into a state where an expression is evaluated to a value that doesn't match the static type of the expression. For example, if an expression has a type ' String ' at the time of compilation, you are guaranteed only to get a string when you evaluate it at the run time.

Like in any other programming language such as Java and C#, the type system of Dart is sound. It enforces soundness using a combination of static checking ( compile - time errors ) and dynamic checking ( at runtime ). For example, assigning a String to int is a compile - time error. Casting an object to a String using as String fails with a runtime error if the object isn't a String.

The benefits of soundness

Sound type system has many benefits. Some of them are as follows :

  • Revealing type-related bugs at compile time : A sound type system ensures that the code is unambiguous with respect to the data types, such that the type - related bugs that might be difficult to find at runtime are successfully revealed at compile time.
  • More readable code: Code becomes more readable with the sound type safety because one can rely on a value actually having the exact specified data type. In sound Dart, types can’t lie.
  • More maintainable code : With a sound type system, whenever a piece of code is changed let us say the data type of a variable, the type system highlights and warns the programmer about the other places where the data type is still the old one.
  • Better ahead of time (AOT) compilation: While AOT compilation is possible without types; the generated code is much less efficient.

Tips for passing static analysis

Most of the rules for static types are easy to understand. Here are some of the less obvious rules:

  • Use sound return types when overriding methods.
  • Use sound parameter types when overriding methods.
  • Don’t use a dynamic list as a typed list.

Related Topics

Dart - extends, with and implements Keywords

The application development in Dart programming language using the Flutter framework, regularly experience different usage of the implements, extends and with keywords. Dart has full support for inheritance that is...

5 minutes read.

Dart Operators Precedence and Associativity

Precedence of operators determines the order in which the operators are evaluated if they are grouped together in a sentence. If two operators share an operand then the one with...

5 minutes read.

Dart Inheritance

Inheritance is a promising concept of any programming language. It is a property by which a class inherits the property of another class. Moreover, the class deriving the properties of...

5 minutes read.

Dart Anonymous Function

Dart functions are the user defined functions that are designed to perform specific task. The use case of the functions is that they can be directly called any number of...

3 minutes read.

Typedef in Dart

In Dart, typedef is used to generate a function type that we can use as a type annotation for declaring variables and return types of the function type. An alias...

4 minutes read.

Type System in Dart

Dart language is a type safety enabled language that uses static and dynamic type checking to match the value of the variable with its data type at the compile-time. This...

4 minutes read.

Dart Comments

Comments are the statements that are used to enhance the readability and understandability of the code. The compiler does not execute these lines. It simply ignores these comments when it scans...

2 minutes read.

Unit Testing in Dart

Typing testing ensures that your app keeps working as you add more features or change existing functionality. Unit testing helps to confirm the behavior of a single function, method, or...

4 minutes read.

Dart Numbers

Dart provides an in-built data type ‘Numbers’ that provides two types of values: intdouble 1. int data type int data type supports integer values, and their size or values range is platform-dependent. Integers...

4 minutes read.

Dart Basics

Dart, as earlier mentioned multiple times, is very similar to C, C++ and Java. It is an object-oriented, garbage collecting and class-based programming language. Let’s look further and see what Dart has...

10 minutes read.

Dart Assignment Operator

Assignment operators are the operators that assign value to the variables. The value on the right-hand side is assigned to the variable on the left-hand side. We can also use...

4 minutes read.

Dart Tutorial

Dart is an open-source, structured programming language developed by Google. It is a high-level programming language that emerged in 2011, but its stable version emerged in 2017. It is largely used...

4 minutes read.

Callable Classes in Dart

Just like the functions, we can also call the instances of classes in Dart. Such classes are also known as “callable ” classes. We need to use the “call( )”...

3 minutes read.

Dart Logical Operators

Logical operators are the operators that combine two or more conditions, and accordingly return a Boolean value : true or false. Assume the value of variable A is 25 and B...

2 minutes read.

Dart Packages

Every programming language has some in-built functions stored inside the header files that makes the task much easier for the programmer. The Dart Packages refer to the compilation of a...

4 minutes read.

Dart Method Overriding

Before understanding method overriding, it is important to clear the concept of polymorphism. Polymorphism is derived from two Greek words 'Poly' which means many and 'morphs' which means many forms....

5 minutes read.

Dart Construtors

Constructors are the very important concept in any programming language. They are the special functions created in the classes to allocate memory to the objects of that class when created...

4 minutes read.

main function in Dart

The main( ) function is a predefined method in Dart that is also known as the entry-point of the program. The compiler begins the execution only when it comes across...

3 minutes read.

Dart Loops

Looping refers to repeating or reusing the same lines of code repeatedly until a particular test condition evaluates to true. It is also known as iterating.  It is effectively used when...

4 minutes read.

Abstract Classes in Dart

Abstract classes in Dart are those classes that only contain abstract methods  (methods that do not contain any implementation). These classes are specifically designed for the purpose of inheritance. We...

4 minutes read.