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
thpWhen 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
}
thpWe 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 = Expected an expression here, found a Identifiernull      // Error, we must define the type
                     ╰╴Invalid variable declaration
String? favorite_color = null // Ok
thpOther examples:
fun get_first(Array[String?] values) -> String? {}
╰╴No statement matched
val result = get_first([])
thpOptional 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- If personis null,person?.namewill returnnull
- If personis not null,person?.namewill returnname
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!!
thpYou can use it to chain access:
val children_lastname = Expected an expression here, found a Identifierperson!!.child!!.lastname
                        ╰╴Invalid variable declaration
thpHowever, 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
thpFor the above code:
- If get_score()is not null,??will returnget_score()
- If get_score()is null,??will return0
You can use the Elvis operator to return early
val username = Expected an expression here, found a Identifierget_username() ?? return
               ╰╴Invalid variable declaration
thp