Classes

Syntax and semantics heavily inspired by Kotlin.

Classes in THP are significantly different than PHP.

Definition

A class is defined as follows:

class Animalthp
    
Syntax error: Unexpected token `Animal`, expected a new line at line 1:6

The name of the class MUST begin with an uppercase letter.

Instanciation

To create an instance of a class call it as if it was a function, without new.

val animal = Animal()thp
    
Syntax error: Expected an expression after the equal `=` operator at line 1:11

Properties

Properties are declared with var/val inside a block. They must explicitly declare their datatype.

class Person
{
    // This is an error. Properties must declare their datatype,
    // even if the compiler can infer it.
    val name = "Jane Doe"

    // This is correct
    val String name = "Jane Doe"

    // This is also okay
    String name = "Jane Doe"
}thp
    
Syntax error: Unexpected token `Person`, expected a new line at line 1:6

Properties are private by default, but can be made public with pub.

class Person
{
    // Properties are private by default
    val String name = "John Doe"

    // To make a property public use `pub`
    pub var Int age = 30
}

val p = Person()
print(p.name)    // Compile error: `name` is private
print(p.age)     // 30thp
    
Syntax error: Unexpected token `Person`, expected a new line at line 1:6

Unlike PHP, to access properties and methods use dot notation . instead of an arrow ->.

Static properties are explained in the Static page.

Readonly properties are explained in the Readonly page.

The interaction between properties and the constructor is explained in the Constructor page.

Methods

Methods are declared with fun, as regular functions.

class Person
{
    fun greet()
    {
        print("Hello")
    }
}thp
    
Syntax error: Unexpected token `Person`, expected a new line at line 1:6

Methods are private by default, and are made public with pub.

class Person
{
    // This method is private
    fun private_greet()
    {
        print("Hello from private method")
    }

    // Use `pub` to make a method public
    pub fun greet()
    {
        print("Hello from greet")
    }
}

val p = Person()
p.greet()           //: Hello from greet
p.private_greet()   // Compile time error. Private method.thp
    
Syntax error: Unexpected token `Person`, expected a new line at line 1:6

Unlike PHP, in THP a method cannot have the same name as a property and viceversa. Doing so is a compile error.

class Person
{
    String name = "Rose"

    // This is a compile error
    fun name() -> String {
        "Rose"
    }
}thp
    
Syntax error: Unexpected token `Person`, expected a new line at line 1:6

This

THP uses the dollar sign $ as this inside classes. It is required when using a class property/method.

class Person
{
    val String name = "Jane Doe"

    pub fun get_name() -> String
    {
        return $name
    }

    pub fun greet()
    {
        val person_name = $get_name()
        print("Hello, I'm {person_name}")
    }
}thp
    
Syntax error: Unexpected token `Person`, expected a new line at line 1:6

Mutable methods

By default methods cannot mutate the state of the object.

class Animal(var String name)
{
    pub fun set_name(String new_name)
    {
        $name = new_name    // Error: Cannot mutate $
    }
}thp
    
Syntax error: Unexpected token `Animal`, expected a new line at line 1:6

To do so the method must be annotated. The caller must also declare a mutable variable.

class Animal(var String name)
{
    pub mut fun set_name(String new_name)
    {
        $name = new_name    // Ok
    }
}

var michi = Animal("Michifu")
michi.set_name("Garfield")thp
    
Syntax error: Unexpected token `Animal`, expected a new line at line 1:6

Class constructor that may return an error

Working theory:

class Fish(
    val String name,
    var Int lives = 9,
)
extends Animal(name)
throws Error

val fish_result = Fish("bubble")   // fish_result will be a `Result[Fish,Error]`
val fish = try fish_resultthp
    
Syntax error: Unexpected token `Fish`, expected a new line at line 1:6