feat: alter classes syntax and add docs

This commit is contained in:
Araozu 2024-09-30 21:17:22 -05:00
parent 62cc887797
commit 4dcfc72c58
9 changed files with 117 additions and 50 deletions

View File

@ -29,6 +29,15 @@ val surname = "Doe"
val year_of_birth = 1984 val year_of_birth = 1984
`} /> `} />
It's a compile error to attempt to modify it
<Code level={2} thpcode={`
val surname = "Doe"
surname = "Dane" // Error
`} />
### Datatype annotation ### Datatype annotation
Written after the `val` keyword but before the variable name. Written after the `val` keyword but before the variable name.
@ -64,6 +73,8 @@ Defined with `var`, followed by a variable name and a value.
<Code level={2} thpcode={` <Code level={2} thpcode={`
var name = "John" var name = "John"
var age = 32 var age = 32
age = 33
`} /> `} />
### Datatype annotation ### Datatype annotation

View File

@ -67,6 +67,21 @@ class Dog(String name)
} }
`} /> `} />
This would be equilavent to the following PHP code:
```php
class Dog {
public string $name;
private int $name_len;
public function __construct(string $name) {
$this->name = $name;
$this->name_len = size($name);
print("Dog created: $name");
}
}
```
@ -115,41 +130,33 @@ print(a2.name_length) //: 3
### Constructor that may fail ### Constructor that may fail
A constructor may only fail if there is code
that can fail on the `init` block.
TBD TBD
Proposal 1: Proposal 1:
<Code thpcode={`
class PrayingMantis(String name) -> self!Error
`} />
Proposal 2:
<Code thpcode={` <Code thpcode={`
class PrayingMantis(String name) class PrayingMantis(String name)
throws Error throws Error
`} />
Proposal 3:
<Code thpcode={`
class PrayingMantis(String name)
{ {
init -> self!Error init -> Error!
{ {
// Something that may fail // Initialization code that may fail
} }
} }
`} /> `} />
## Destructor ## Destructor
The destructor in THP is the same as PHP. The destructor in THP is the same as PHP.
<Code thpcode={` <Code thpcode={`
class Owl class Owl()
{ {
pub fun __destruct() pub fun __destruct()
{ {

View File

@ -15,11 +15,13 @@ Classes in THP are significantly different than PHP.
A class is defined as follows: A class is defined as follows:
<Code thpcode={` <Code thpcode={`
class Animal class Animal() {}
`} /> `} />
The name of the class **MUST** begin with an uppercase letter. The name of the class **MUST** begin with an uppercase letter.
Classes have a parameter list even if they have no parameters
for consistency sake.
## Instanciation ## Instanciation
@ -38,7 +40,7 @@ Properties are declared with `var`/`val` inside a block.
They **must** explicitly declare their datatype. They **must** explicitly declare their datatype.
<Code thpcode={` <Code thpcode={`
class Person class Person()
{ {
// This is an error. Properties must declare their datatype, // This is an error. Properties must declare their datatype,
// even if the compiler can infer it. // even if the compiler can infer it.
@ -55,7 +57,7 @@ class Person
**Properties are private by default**, but can be made public with `pub`. **Properties are private by default**, but can be made public with `pub`.
<Code thpcode={` <Code thpcode={`
class Person class Person()
{ {
// Properties are private by default // Properties are private by default
val String name = "John Doe" val String name = "John Doe"
@ -86,7 +88,7 @@ in the Constructor page.
Methods are declared with `fun`, as regular functions. Methods are declared with `fun`, as regular functions.
<Code thpcode={` <Code thpcode={`
class Person class Person()
{ {
fun greet() fun greet()
{ {
@ -98,7 +100,7 @@ class Person
**Methods are private by default**, and are made public with `pub`. **Methods are private by default**, and are made public with `pub`.
<Code thpcode={` <Code thpcode={`
class Person class Person()
{ {
// This method is private // This method is private
fun private_greet() fun private_greet()
@ -123,7 +125,7 @@ in THP a method cannot have the same name as a property and viceversa.
Doing so is a compile error. Doing so is a compile error.
<Code thpcode={` <Code thpcode={`
class Person class Person()
{ {
String name = "Rose" String name = "Rose"
@ -141,7 +143,7 @@ THP uses the dollar sign `$` as this inside classes.
It is **required** when using a class property/method. It is **required** when using a class property/method.
<Code thpcode={` <Code thpcode={`
class Person class Person()
{ {
val String name = "Jane Doe" val String name = "Jane Doe"
@ -168,7 +170,7 @@ class Animal(var String name)
{ {
pub fun set_name(String new_name) pub fun set_name(String new_name)
{ {
$name = new_name // Error: Cannot mutate $ $name = new_name // Error: Cannot mutate $name
} }
} }
`} /> `} />
@ -189,21 +191,3 @@ var michi = Animal("Michifu")
michi.set_name("Garfield") michi.set_name("Garfield")
`} /> `} />
## Class constructor that may return an error
Working theory:
<Code thpcode={`
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_result
`} />

View File

@ -6,7 +6,7 @@ import Code from "../../../components/Code.astro"
# Inheritance # Inheritance
A class inherits from another using the `extends` keyword.
<Code thpcode={` <Code thpcode={`
// Base class // Base class
@ -20,7 +20,34 @@ class Animal(var String name)
// Child class // Child class
class Cat(String name, Int lives) class Cat(String name, Int lives)
extends Animal(name) extends Animal(name) {}
Cat("Michi", 9).say_name() Cat("Michi", 9).say_name()
`} /> `} />
The call to the parent constructor is done right there, after
the parent class name.
<Code thpcode={`
class Dog(String name)
extends Animal(name) {}
// |----|
// This is the call to the parent constructor
`} />
You must always call super, even if the parent doesn't
define any parameters:
<Code thpcode={`
class Parent() {}
class Child()
extends Parent() {}
`} />

View File

@ -6,7 +6,10 @@ import Code from "../../../components/Code.astro"
# Arrays # Arrays
Use square brackets as usual. Arrays in THP use exclusively square brackets.
More importantly, Arrays and Maps are different.
Arrays only store values of a single datatype.
## Usage ## Usage
@ -16,7 +19,7 @@ val apple = fruits[0]
print(apple) // apple print(apple) // apple
// To mutate an array, you need to declare it as var
var numbers = [0, 1, 2, 3] var numbers = [0, 1, 2, 3]
numbers[3] = 5 numbers[3] = 5

View File

@ -35,6 +35,8 @@ val result = if condition { value1 } else { value2 }
## Check for datatypes ## Check for datatypes
TBD
<Code thpcode={` <Code thpcode={`
if variable is Datatype if variable is Datatype
{ {

View File

@ -7,7 +7,7 @@ import Code from "../../../components/Code.astro"
# Higher Order functions # Higher Order functions
## Function as parameter ## Function as parameters
<Code thpcode={` <Code thpcode={`
fun map[A, B](Array[A] input, (A) -> (B) function) -> Array[B] fun map[A, B](Array[A] input, (A) -> (B) function) -> Array[B]

View File

@ -9,18 +9,48 @@ import Code from "../../../components/Code.astro"
## Anonymous function ## Anonymous function
An anonymous function is declared with `fn`.
Other than not having a name, it can declare parameter
and return types.
<Code thpcode={` <Code thpcode={`
fun(Int x, Int y) -> Int { fn(Int x, Int y) -> Int {
x + y x + y
} }
`} />
Anonymous function can omit declaring those types as well:
<Code thpcode={`
numbers.map(fun(x) { numbers.map(fun(x) {
x * 2 x * 2
}) })
`} /> `} />
## Anonymous function short form
If you need an anonymous function that returns a single
expression you can write it like this:
<Code thpcode={`
fun(x, y) = x + y
`} />
It uses an equal `=` instead of an arrow. It can contain
only a single expression.
This is common when declaring functions that immediately
return a map.
<Code thpcode={`
fn(value) = .{
value
}
`} />
## Closure types ## Closure types

View File

@ -41,10 +41,11 @@ Placing a `mut` before the type makes the parameter a mutable
reference. Mutable methods can be used, and the original reference. Mutable methods can be used, and the original
data **can** be mutated. data **can** be mutated.
The caller *must* also use `mut`. The caller must define the value as `var`, and when calling
must use `mut`.
<Code thpcode={` <Code thpcode={`
val numbers = Array(0, 1, 2, 3) var numbers = Array(0, 1, 2, 3)
push_25(mut numbers) // Pass \`numbers\` as reference. push_25(mut numbers) // Pass \`numbers\` as reference.
@ -64,6 +65,8 @@ fun add_25(clone Array[Int] numbers) {
Using the `clone` keyword before the type creates a mutable copy Using the `clone` keyword before the type creates a mutable copy
of the parameter (CoW). The original data will **not** be mutated. of the parameter (CoW). The original data will **not** be mutated.
The caller must also use `clone` when calling the function.
<Code thpcode={` <Code thpcode={`
val numbers = Array(1, 2, 3, 4) val numbers = Array(1, 2, 3, 4)