Each type (except the special type Nothing) belongs to one of two categories: Value Types or Reference Types. If a variable has a value type, then storage for an instance of that type is held inside the variable itself. For example, a variable with type Number is allocated storage which is used to hold number values. However, if a variable has a reference type, then storage for its value is allocated on the heap and the variable holds a reference to that heap storage.
2.2.1 The Invalid value
Every datatype (except the special type Nothing) has a special value Invalid in addition to all its normal values. This special value is normally used to indicate that a global data variable has not been initialized or that a method in the API was unable to return a value. TouchDevelop provides a method for testing a value of any datatype (except Nothing) to test whether it is the Invalid value. There are also API methods for obtaining the Invalid value for any desired type.
If a data structure (such as a tree or linked list) is constructed using Object types declared in the Records section of a script, the Invalid value would usually be used to play the role of a null reference value.
Some code to demonstrate the use of Invalid values appears below.
numUsers := 0
connection failure detected
numUsers := invalid → number
numUsers → is invalid
“Script is terminating” → post to wall
The Nothing type
A method or an operation which does not return a usable result, but which otherwise succeeded, actually returns a value of type Nothing. For example, the post to wall method which is provided for every datatype returns a result of type Nothing. In some languages, such as F#, the Unit type is the equivalent of the Nothing type in TouchDevelop. There is a single value with type Nothing. No operations at all are provided for this type; it is similar to the void type in languages like C/C++ and Java.
The basic types or elementary types provided in the TouchDevelop scripting language are Number, Boolean, and String. These are all Value Types. There are also several composite types which are value types. All the value types are listed in Table 2-2. Here are some further details about the Number and String types.
The Number type combines the integer and floating-point types found in other languages. Values are held in double-precision floating point format, consistent with the IEEE 754 standard. This implies that the special values plus infinity, minus infinity and NaN (not-a-number) can be computed as the result of a calculation.
When a Number value is used in a context where an integer is needed, such as when selecting the k-th value in a collection, the value is rounded to the closest integer. A value exactly half-way between is rounded up; for example, 1.5 is rounded up to 2 while 1.49 is rounded down to 1.
A string may contain zero or more Unicode characters. When a string constant is shown as part of a TouchDevelop script, double-quote characters are used to enclose the string and a backslash character is used to escape a double-quote character or a special character which appears inside the string. However, when using the editor to enter a string constant, no backslash characters should be entered (unless a backslash character itself is wanted inside the string constant).
It should be noted that TouchDevelop does not provide the char type for working with single characters. Instead a string of length one should be used.
Storage for an instance of a reference type is allocated in a different place from a variable declared with that type. A local variable with a reference type is implemented as a pointer (a reference) to the actual value which is stored elsewhere.
In TouchDevelop, two kinds of reference types are provided. If the value represents an entity which exists outside TouchDevelop, such as a song on a Windows phone, then storage is allocated outside the TouchDevelop application. Otherwise the storage is allocated within an area of memory controlled by TouchDevelop which is called the heap. When there are no more references to a value on the heap, the storage used by that value is automatically reclaimed. It is garbage collected. The language facilities and the operations which can be performed on reference types in a TouchDevelop script depend on whether the values are external to the script or are internal.
When one variable with a reference type is assigned to another variable, both variables will become references to the same instance. A simple example to illustrate this sharing of one instance between two variables is provided by the following code.
// Set x to refer to a value of type Contact
x := social → choose contacts
y := x
x → set title(“His Excellency”)
y → title → post to wall
In this example, the title displayed on the screen by the last statement will always be ‘His Excellency’ because x and y are both references to the same instance on the heap, in which the title field of an instance of the Contact type has been set to that string.
Reference types provided by the API
Excluding the collection types (which are covered in the next subsection of this chapter below), Table 2-3 lists the reference types implemented by the API and available to TouchDevelop scripts. The table explicitly indicates whether storage for an instance of each type is allocated on the heap or is external to the TouchDevelop script.
The API also provides homogeneous collections. A collection contains zero or more elements whose type is one of the value types or one of the reference types listed in Table 2-2. Collections are provided for many of the possible element types. When a collection type has not been provided, an equivalent list type can be defined instead using an Object declaration (see Objects and Decorators, below).
Some collections correspond to resources provided on a Windows Phone (and therefore may not be supported on other platforms), such as a collection of stored songs, and such collections are immutable. Other collections are mutable, meaning that new elements can be inserted into the collection and/or elements may be deleted.
The collection types provided by the API are listed in Table 2-4 and Table 2-5. Three of the collection types have been tagged as special and are listed separately in Table 2-5. These three collection types have some special properties not possessed by the other collection types and need some additional explanation.
Tables and indexes
The Records section of a TouchDevelop script can contain definitions of Tables. Each Table type is a datatype with a single instance and is globally visible. It corresponds to a database table which consists of rows and whose fields are organized into columns. The Records section can also contain definitions for Index types.
The Records section of a script can include declarations for Object types. Each Object type is a new datatype which is composed from named fields, similar to a struct or class type in other languages. Storage for instances of Object types is allocated on the heap and is garbage collected. Since it is heap allocated, every Object type is a Reference type.
Decorators may be declared in the Records section of a script. A decorator is used to associate extra information with instances of some reference types. The types which can be decorated are Appointment, Board, Json Object, Link, Map, Message, Page, Page Button, Place, Sound, Sprite, TextBox, Tile, Web Request, Web Response, Xml Object and Sprite Set. User-defined objects can be decorated as well.
Global persistent data
The Data section of a TouchDevelop script may contain declarations for global variables. Each of these variables has a datatype which must be one of the types provided in the language or API or one of the Object types declared in the Records section of the script.
Any global variable declared to have a simple type or the DateTime type is initialized to a neutral value. The neutral values are 0 for a Number, false for a Boolean, “” for a String, and 1/1/0001 12:00:00 AM for a DateTime variable. A variable with any other type is initialized to a special invalid value.
The is invalid method is provided for every datatype and may be used to test whether a global variable has not yet been initialized or a value was unobtainable. For example, if the Data section of the script contains a declaration for the global variable MyFriends with the type String Collection, then this script might contain statements like the following to check whether the variable needs to be initialized.
◳MyFriends → is invalid
// it’s the first use of this script, initialize the global variable
◳MyFriends := collections → create string collection
// do nothing
The values held by many of the global variables persist from one execution of the script to the next because they are held in the phone’s memory. The only ways to ‘forget’ these values are to uninstall the script or edit the script and delete the global variables.
Some scripts need to display pictures or to produce sounds. These pictures or sounds can be added to the script as global constants and become part of the script. Such items are held in the Art section of the script. In addition, the Art section can contain definitions for particular colors which will be needed by the script.
The Art section of the script is similar to the Data section except that the items are restricted to having one of the datatypes Color, Picture or Sound, and these items are initialized. Initialization for a Color value is provided via an ARGB (alpha, red, green, blue) value; initialization for Picture or Sound values is obtained by downloading the desired value from a web site.