Nullable types

All datatypes in THP disallow the usage of null by default. To represent null we must use nullable types, represented by the question mark ? character.

For instance, a POST request may have a username parameter, or it may not. This can be represented with an String?.


String? new_username = POST::get("username")
╰╴No statement matched
thp

When we have a ?Type we cannot use it directly. We must first check if the value is null, and then use it.

The syntax ? returns true if the value is not null.


if new_username? {
╰╴No statement matched
// Here `new_username` is automatically casted to String } // you can also manually check for null if new_username == null { // This is the same as above }
thp

We must check explicitly that the value is not null. Doing if new_username {} alone is not allowed.

Usage

To create a nullable type we must explicitly annotate the type.


val favorite_color = null      // Error, we must define the type
╰╴No statement matched
String? favorite_color = null // Ok
thp

Other examples:


fun get_first(Array[String?] values) -> String? {}
╰╴No statement matched
val result = get_first([])
thp

Optional chaining

If you have a Type? and you wish to access a field of Type if it exists, you can use the optional chaining operator ?..


Person? person = ...
╰╴No statement matched
val name = person?.name
thp

Null unboxing

The !! operator transforms a Type? into Type.

If you are sure that a value cannot be null, you can force the compiler to treat it as a regular value with the !! operator. Note the two exclamation marks.


String? lastname = find_lastname()
╰╴No statement matched
// Tell the compiler trust me, // I know this is not null String s = lastname!!
thp

You can use it to chain access:


val children_lastname = person!!.child!!.lastname
╰╴No statement matched
thp

However, if at runtime you use !! on a null value, the null value will be returned and your program will blow up later. So make sure to use this operator only when you are sure a value cannot be null.

Elvis operator

The Elvis operator ?? is used to give a default value in case a null is found.


// This is a function that may return a Int
  ╰╴No statement matched
fun get_score() -> Int? {...} val test_score = get_score() ?? 0
thp

For the above code:

You can use the Elvis operator to return early


val username = get_username() ?? return
╰╴No statement matched
thp