refactor: latest docs
This commit is contained in:
parent
c26251567c
commit
a1641046cb
@ -18,8 +18,7 @@ THP enums are a 1 to 1 map of PHP enums, with a slightly different syntax.
|
|||||||
Enums don't have a scalar value by default.
|
Enums don't have a scalar value by default.
|
||||||
|
|
||||||
<Code thpcode={`
|
<Code thpcode={`
|
||||||
enum Suit
|
enum Suit {
|
||||||
{
|
|
||||||
Hearts,
|
Hearts,
|
||||||
Diamonds,
|
Diamonds,
|
||||||
Clubs,
|
Clubs,
|
||||||
@ -36,8 +35,7 @@ Backed enums can have a scalar for each case. The scalar values can only be
|
|||||||
|
|
||||||
<Code
|
<Code
|
||||||
thpcode={`
|
thpcode={`
|
||||||
enum Suit(String)
|
enum Suit(String) {
|
||||||
{
|
|
||||||
Hearts = "H",
|
Hearts = "H",
|
||||||
Diamonds = "D",
|
Diamonds = "D",
|
||||||
Clubs = "C",
|
Clubs = "C",
|
||||||
|
@ -10,8 +10,7 @@ import Code from "@/components/Code.astro";
|
|||||||
Tagged unions can hold a value from a fixed selection of types.
|
Tagged unions can hold a value from a fixed selection of types.
|
||||||
|
|
||||||
<Code thpcode={`
|
<Code thpcode={`
|
||||||
union Shape
|
union Shape {
|
||||||
{
|
|
||||||
Dot,
|
Dot,
|
||||||
Square(Int),
|
Square(Int),
|
||||||
Rectangle(Int, Int),
|
Rectangle(Int, Int),
|
||||||
@ -27,12 +26,10 @@ val rectangle1 = Shape::Rectangle(5, 15)
|
|||||||
<Code
|
<Code
|
||||||
thpcode={`
|
thpcode={`
|
||||||
match shape_1
|
match shape_1
|
||||||
case ::Square(side)
|
case ::Square(side) {
|
||||||
{
|
|
||||||
print("Area of the square: {side * side}")
|
print("Area of the square: {side * side}")
|
||||||
}
|
}
|
||||||
case ::Rectangle(length, height)
|
case ::Rectangle(length, height) {
|
||||||
{
|
|
||||||
print("Area of the rectangle: {length * height}")
|
print("Area of the rectangle: {length * height}")
|
||||||
}
|
}
|
||||||
`}
|
`}
|
||||||
@ -47,8 +44,7 @@ are contained as part of an array.
|
|||||||
|
|
||||||
```php
|
```php
|
||||||
// The first snippet is compiled to:
|
// The first snippet is compiled to:
|
||||||
enum Shape
|
enum Shape {
|
||||||
{
|
|
||||||
case Dot;
|
case Dot;
|
||||||
case Square;
|
case Square;
|
||||||
case Rectangle;
|
case Rectangle;
|
||||||
|
@ -18,7 +18,6 @@ val result = {
|
|||||||
val temp = 161
|
val temp = 161
|
||||||
|
|
||||||
temp * 2 // This will be assigned to \`result\`
|
temp * 2 // This will be assigned to \`result\`
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
print(result) // 322
|
print(result) // 322
|
||||||
|
@ -17,8 +17,7 @@ The following code shows a function without parameters
|
|||||||
and without return type:
|
and without return type:
|
||||||
|
|
||||||
<Code thpcode={`
|
<Code thpcode={`
|
||||||
fun say_hello()
|
fun say_hello() {
|
||||||
{
|
|
||||||
print("Hello")
|
print("Hello")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,8 +33,7 @@ type is **mandatory**, and it's done by placing an
|
|||||||
arrow `->` followed by the return datatype:
|
arrow `->` followed by the return datatype:
|
||||||
|
|
||||||
<Code thpcode={`
|
<Code thpcode={`
|
||||||
fun get_random_number() -> Int
|
fun get_random_number() -> Int {
|
||||||
{
|
|
||||||
return Random::get(0, 35_222)
|
return Random::get(0, 35_222)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,8 +45,7 @@ a return type:
|
|||||||
|
|
||||||
<Code
|
<Code
|
||||||
thpcode={`
|
thpcode={`
|
||||||
fun get_random_number()
|
fun get_random_number() {
|
||||||
{
|
|
||||||
// Error: the function does not define a return type
|
// Error: the function does not define a return type
|
||||||
return Random::get(0, 35_222)
|
return Random::get(0, 35_222)
|
||||||
}
|
}
|
||||||
@ -60,8 +57,7 @@ expression on the function:
|
|||||||
|
|
||||||
<Code
|
<Code
|
||||||
thpcode={`
|
thpcode={`
|
||||||
fun get_random_number() -> Int
|
fun get_random_number() -> Int {
|
||||||
{
|
|
||||||
// The last expression of a function is
|
// The last expression of a function is
|
||||||
// automatically returned
|
// automatically returned
|
||||||
Random::get(0, 35_222)
|
Random::get(0, 35_222)
|
||||||
@ -75,8 +71,7 @@ Parameters are declared like C-style languages:
|
|||||||
`Type name`, separated by commas.
|
`Type name`, separated by commas.
|
||||||
|
|
||||||
<Code thpcode={`
|
<Code thpcode={`
|
||||||
fun add(Int a, Int b) -> Int
|
fun add(Int a, Int b) -> Int {
|
||||||
{
|
|
||||||
return a + b
|
return a + b
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,8 +91,7 @@ The following example declares a generic `T` and uses it
|
|||||||
in the parameters and return type:
|
in the parameters and return type:
|
||||||
|
|
||||||
<Code thpcode={`
|
<Code thpcode={`
|
||||||
fun get_first_item[T](Array[T] array) -> T
|
fun get_first_item[T](Array[T] array) -> T {
|
||||||
{
|
|
||||||
array[0]
|
array[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,8 +128,7 @@ fun html_special_chars(
|
|||||||
Int? flags,
|
Int? flags,
|
||||||
String? encoding,
|
String? encoding,
|
||||||
Bool? double_encoding,
|
Bool? double_encoding,
|
||||||
) -> String
|
) -> String {
|
||||||
{
|
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,8 +143,7 @@ TBD: If & how named arguments affect the order of the parameters
|
|||||||
fun greet(
|
fun greet(
|
||||||
String name,
|
String name,
|
||||||
String from: city,
|
String from: city,
|
||||||
)
|
) {
|
||||||
{
|
|
||||||
print("Hello {name} from {city}!")
|
print("Hello {name} from {city}!")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,8 +10,7 @@ import Code from "@/components/Code.astro";
|
|||||||
## Function as parameters
|
## 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] {
|
||||||
{
|
|
||||||
// implementation
|
// implementation
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,8 +19,7 @@ fun map[A, B](Array[A] input, (A) -> (B) function) -> Array[B]
|
|||||||
## Function as return
|
## Function as return
|
||||||
|
|
||||||
<Code thpcode={`
|
<Code thpcode={`
|
||||||
fun generate_generator() -> () -> Int
|
fun generate_generator() -> () -> Int {
|
||||||
{
|
|
||||||
// code...
|
// code...
|
||||||
return fun() {
|
return fun() {
|
||||||
322
|
322
|
||||||
|
@ -12,11 +12,11 @@ To represent `null` we must use nullable types, represented
|
|||||||
by the question mark `?` character.
|
by the question mark `?` character.
|
||||||
|
|
||||||
For instance, a POST request may have a `username` parameter,
|
For instance, a POST request may have a `username` parameter,
|
||||||
or it may not. This can be represented with an `?String`.
|
or it may not. This can be represented with an `String?`.
|
||||||
|
|
||||||
<Code
|
<Code
|
||||||
thpcode={`
|
thpcode={`
|
||||||
?String new_username = POST::get("username")
|
String? new_username = POST::get("username")
|
||||||
`}
|
`}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@ -26,14 +26,12 @@ check if the value is null, and then use it.
|
|||||||
The syntax `?` returns `true` if the value is not null.
|
The syntax `?` returns `true` if the value is not null.
|
||||||
|
|
||||||
<Code thpcode={`
|
<Code thpcode={`
|
||||||
if new_username?
|
if new_username? {
|
||||||
{
|
|
||||||
// Here \`new_username\` is automatically casted to String
|
// Here \`new_username\` is automatically casted to String
|
||||||
}
|
}
|
||||||
|
|
||||||
// you can also manually check for null
|
// you can also manually check for null
|
||||||
if new_username == null
|
if new_username == null {
|
||||||
{
|
|
||||||
// This is the same as above
|
// This is the same as above
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,24 +47,24 @@ To create a nullable type we must explicitly annotate the type.
|
|||||||
<Code thpcode={`
|
<Code thpcode={`
|
||||||
val favorite_color = null // Error, we must define the type
|
val favorite_color = null // Error, we must define the type
|
||||||
|
|
||||||
?String favorite_color = null // Ok
|
String? favorite_color = null // Ok
|
||||||
`} />
|
`} />
|
||||||
|
|
||||||
Other examples:
|
Other examples:
|
||||||
|
|
||||||
<Code thpcode={`
|
<Code thpcode={`
|
||||||
fun get_first(Array[?String] values) -> ?String {}
|
fun get_first(Array[String?] values) -> String? {}
|
||||||
|
|
||||||
val result = get_first([])
|
val result = get_first([])
|
||||||
`} />
|
`} />
|
||||||
|
|
||||||
## Optional chaining
|
## Optional chaining
|
||||||
|
|
||||||
If you have a `?Type` and you wish to access a field of `Type` if it exists,
|
If you have a `Type?` and you wish to access a field of `Type` if it exists,
|
||||||
you can use the optional chaining operator `?.`.
|
you can use the optional chaining operator `?.`.
|
||||||
|
|
||||||
<Code thpcode={`
|
<Code thpcode={`
|
||||||
?Person person = ...
|
Person? person = ...
|
||||||
|
|
||||||
val name = person?.name
|
val name = person?.name
|
||||||
`} />
|
`} />
|
||||||
@ -76,14 +74,14 @@ val name = person?.name
|
|||||||
|
|
||||||
## Null unboxing
|
## Null unboxing
|
||||||
|
|
||||||
The `!!` operator transforms a `?Type` into `Type`.
|
The `!!` operator transforms a `Type?` into `Type`.
|
||||||
|
|
||||||
If you are sure that a value cannot be `null`, you can force the
|
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.
|
compiler to treat it as a regular value with the `!!` operator.
|
||||||
Note the two exclamation marks.
|
Note the two exclamation marks.
|
||||||
|
|
||||||
<Code thpcode={`
|
<Code thpcode={`
|
||||||
?String lastname = find_lastname()
|
String? lastname = find_lastname()
|
||||||
|
|
||||||
// Tell the compiler trust me,
|
// Tell the compiler trust me,
|
||||||
// I know this is not null
|
// I know this is not null
|
||||||
@ -109,7 +107,7 @@ The Elvis operator `??` is used to give a default value in case a `null` is foun
|
|||||||
|
|
||||||
<Code thpcode={`
|
<Code thpcode={`
|
||||||
// This is a function that may return a Int
|
// This is a function that may return a Int
|
||||||
fun get_score() -> ?Int {...}
|
fun get_score() -> Int? {...}
|
||||||
|
|
||||||
val test_score = get_score() ?? 0
|
val test_score = get_score() ?? 0
|
||||||
`} />
|
`} />
|
||||||
|
@ -13,42 +13,41 @@ and handled.
|
|||||||
|
|
||||||
## Declare that a function returns an exception
|
## Declare that a function returns an exception
|
||||||
|
|
||||||
Possible errors have their own syntax: `Error!Type`.
|
Possible errors have their own syntax: `Type!Error`.
|
||||||
This means: This may be an `Error`, or a `Type`.
|
This means: This may be a `Type`, or an `Error`.
|
||||||
|
|
||||||
For example, a function that returned a `DivisionByZero`
|
For example, a function that returned a `DivisionByZero`
|
||||||
may be written like this:
|
may be written like this:
|
||||||
|
|
||||||
<Code thpcode={`
|
<Code thpcode={`
|
||||||
fun invert(Int number) -> DivisionByZero!Int
|
fun invert(Int number) -> Int!DivisionByZero {
|
||||||
{
|
|
||||||
if number == 0
|
if number == 0
|
||||||
{
|
{
|
||||||
return DivisionByZero()
|
throw DivisionByZero()
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1 / number
|
return 1 / number
|
||||||
|
|
||||||
}
|
}
|
||||||
`} />
|
`} />
|
||||||
|
|
||||||
In the previous segment, `DivisionByZero!Int` denotates
|
In the previous segment, `Int!DivisionByZero` denotates
|
||||||
that the function may return either a `DivisionByZero` error
|
that the function may return either a `DivisionByZero` error
|
||||||
or an `Int`.
|
or an `Int`.
|
||||||
|
|
||||||
There is no `throw` keyword, errors are just returned.
|
The `throw` keyword is used to denotate that an error is being
|
||||||
|
returned.
|
||||||
|
|
||||||
### Multiple error returns
|
### Multiple error returns
|
||||||
|
|
||||||
TODO: properly define syntax, how this interacts with type unions.
|
TODO: properly define syntax, how this interacts with type unions.
|
||||||
|
|
||||||
Multiple errors are chained with `!`. The last one is always
|
Multiple errors are chained with `!`.
|
||||||
the success value.
|
|
||||||
|
|
||||||
<Code
|
<Code
|
||||||
thpcode={`
|
thpcode={`
|
||||||
fun sample() -> Error1!Error2!Error3!Int
|
fun sample() -> Int!Error1!Error2!Error3 {
|
||||||
{ /* ... */}
|
/* ... */
|
||||||
|
}
|
||||||
`}
|
`}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@ -66,14 +65,13 @@ Use a naked `try` when you want to rethrow an error, if there is any.
|
|||||||
|
|
||||||
<InteractiveCode
|
<InteractiveCode
|
||||||
code={`
|
code={`
|
||||||
fun dangerous() -> Exception!Int
|
fun dangerous() -> Int!Exception { // May throw randomly
|
||||||
{ // May throw randomly
|
|
||||||
return if Math.random() < 0.5 { 50 }
|
return if Math.random() < 0.5 { 50 }
|
||||||
else { Exception("Unlucky") }
|
else { Exception("Unlucky") }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun run() -> Exception!
|
fun run() -> Void!Exception {
|
||||||
{ // If \`dangerous()\` throws, the function exits with the same error.
|
// If \`dangerous()\` throws, the function exits with the same error.
|
||||||
// Otherwise, continues
|
// Otherwise, continues
|
||||||
val result = try dangerous()
|
val result = try dangerous()
|
||||||
print("The result is {result}")
|
print("The result is {result}")
|
||||||
|
Loading…
Reference in New Issue
Block a user