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")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? {
  // 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

String? favorite_color = null // Okthp

Other examples:

fun get_first(Array[String?] values) -> String? {}

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 = ...

val name = person?.namethp

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()

// 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!!.lastnamethp

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
fun get_score() -> Int? {...}

val test_score = get_score() ?? 0thp

For the above code:

You can use the Elvis operator to return early

val username = get_username() ?? returnthp