2023-10-02 01:41:38 +00:00
|
|
|
![Accurate visual description of THP](/img/desc_thp.jpg)
|
|
|
|
|
|
|
|
|
2023-06-27 03:11:02 +00:00
|
|
|
# Welcome
|
|
|
|
|
|
|
|
Welcome to the documentation of the THP programming languague.
|
|
|
|
|
2023-07-01 01:00:17 +00:00
|
|
|
THP is a new programming language that compiles to PHP.
|
|
|
|
|
2023-09-15 03:15:35 +00:00
|
|
|
<br>
|
|
|
|
|
|
|
|
This page discusses some of the design decitions of the language,
|
2023-10-02 01:41:38 +00:00
|
|
|
if you want to install THP go to the [installation guide](/installation-guide)
|
2023-09-15 03:15:35 +00:00
|
|
|
|
|
|
|
If you want to learn the language, go to the learn section.
|
|
|
|
|
2023-06-27 03:11:02 +00:00
|
|
|
## Goals
|
|
|
|
|
2023-07-01 01:00:17 +00:00
|
|
|
- Bring static typing to PHP: Not just type hints, not use `mixed` for everything
|
|
|
|
that isn't a primitive type.
|
|
|
|
- Avoid automatic type conversion.
|
|
|
|
- Remove the inconsistencies in the language.
|
|
|
|
- Organize the stdlib.
|
|
|
|
- Differentiate between Arrays, Tuples, Maps and Sets.
|
|
|
|
- Create a **consistent** language.
|
|
|
|
- Create typings for popular libraries (like TS's `.d.ts`).
|
|
|
|
- Have a simple instalation and configuration (requiring just Composer).
|
2023-12-17 01:33:55 +00:00
|
|
|
- Ship a fast, native binary (written in Rust) (why use PHP when we can go native?).
|
2023-07-01 01:00:17 +00:00
|
|
|
- Sub 10ms watch mode.
|
|
|
|
- Support in-place compilation.
|
2023-07-01 01:55:29 +00:00
|
|
|
- Emit readable PHP code.
|
2023-07-01 01:00:17 +00:00
|
|
|
- Implement a LSP server.
|
|
|
|
|
|
|
|
|
|
|
|
## Not goals
|
|
|
|
|
|
|
|
These are **not** aspects that THP looks to solve or implement.
|
|
|
|
|
2023-07-01 01:55:29 +00:00
|
|
|
- Be what TypeScript is for JavaScript (PHP with types).
|
2023-07-01 01:00:17 +00:00
|
|
|
- Use PHP syntax/conventions.
|
2023-07-01 01:55:29 +00:00
|
|
|
- Be familiar for PHP developers.
|
2023-07-01 01:00:17 +00:00
|
|
|
|
|
|
|
|
2023-06-27 03:11:02 +00:00
|
|
|
## Philosophy
|
|
|
|
|
2023-07-01 01:55:29 +00:00
|
|
|
- Consistency over familiarity
|
|
|
|
- Change over conventions
|
|
|
|
- Explicit over implicit
|
2023-07-01 01:00:17 +00:00
|
|
|
|
|
|
|
|
2023-12-17 01:33:55 +00:00
|
|
|
## Some differences with PHP
|
|
|
|
|
|
|
|
```thp
|
|
|
|
// PHP
|
|
|
|
$has_key = str_contains($haystack, 'needle');
|
|
|
|
|
|
|
|
// THP
|
|
|
|
val has_key = haystack.contains("needle")
|
|
|
|
```
|
|
|
|
|
|
|
|
- Explicit variable declaration
|
|
|
|
- No `$` for variable names (and thus no `$$variable`)
|
|
|
|
- No semicolons
|
|
|
|
- Use methods on common datatypes
|
|
|
|
- Strings use only double quotes
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
```thp
|
|
|
|
// PHP
|
|
|
|
[
|
|
|
|
'names' => ['Toni', 'Stark'],
|
|
|
|
'age' => 33,
|
|
|
|
'numbers' => [32, 64, 128]
|
|
|
|
]
|
|
|
|
|
|
|
|
// THP
|
|
|
|
Obj {
|
|
|
|
names: #("Toni", "Stark"), // Tuple
|
|
|
|
age: 33,
|
|
|
|
numbers: [32, 64, 128]
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
- Tuples, Arrays, Sets, Maps are clearly different
|
|
|
|
- JS-like object syntax
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
```thp
|
|
|
|
// PHP
|
|
|
|
$cat = new Cat("Michifu", 7);
|
|
|
|
$cat->meow();
|
|
|
|
|
|
|
|
// THP
|
|
|
|
val cat = Cat("Michifu", 7)
|
|
|
|
cat.meow();
|
|
|
|
```
|
|
|
|
|
|
|
|
- No `new` for classes
|
|
|
|
- Use dot `.` instead of arrow `->` syntax
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
```thp
|
|
|
|
// PHP
|
|
|
|
use \Some\Deeply\Nested\Class
|
|
|
|
use \Some\Deeply\Nested\Interface
|
|
|
|
|
|
|
|
// THP
|
|
|
|
use Some::Deeply::Nested::{Class, Interface}
|
|
|
|
```
|
|
|
|
|
|
|
|
- Different module syntax
|
|
|
|
- PSR-4 required
|
|
|
|
- No `include` or `require`
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
Other things:
|
|
|
|
|
|
|
|
- Pattern matching
|
|
|
|
- ADTs
|
|
|
|
|
|
|
|
|
|
|
|
### Runtime changes
|
|
|
|
|
|
|
|
THP should add as little runtime as possible.
|
|
|
|
|
|
|
|
```thp
|
|
|
|
// ===== current =======
|
|
|
|
val name = "John"
|
|
|
|
var name = "John"
|
|
|
|
|
|
|
|
String name = "John"
|
|
|
|
var String name = "John"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ===== new? =======
|
|
|
|
let name = "John"
|
|
|
|
let mut name = "John"
|
|
|
|
|
|
|
|
String name = "John"
|
|
|
|
mut String name = "John"
|
|
|
|
|
|
|
|
|
|
|
|
// For primitive datatypes (Int, Float, Bool, String?)
|
|
|
|
|
|
|
|
// Cloned
|
|
|
|
fun add(Int x)
|
|
|
|
// Still cloned, but the x **binding** can be mutated, not the original variable
|
|
|
|
fun add(mut Int x)
|
|
|
|
// Same as 1st
|
|
|
|
fun add(clone Int x)
|
|
|
|
|
|
|
|
|
|
|
|
// For other datatypes
|
|
|
|
|
|
|
|
// Pass an immutable reference
|
|
|
|
fun add(Obj o)
|
|
|
|
// Pass a mutable reference
|
|
|
|
fun add(mut Obj o)
|
|
|
|
// Clone the argument
|
|
|
|
fun add(clone Obj o)
|
|
|
|
|
|
|
|
|
|
|
|
// Only references are passed, not "variables" (as PHP calls them)
|
|
|
|
let john = Obj {name: "John"}
|
|
|
|
/*
|
|
|
|
john --------> {name: "John"}
|
|
|
|
*/
|
|
|
|
|
|
|
|
fun set_empty(mut Obj person) {
|
|
|
|
/*
|
|
|
|
john ------┬--> {name: "John"}
|
|
|
|
person ----┘
|
|
|
|
*/
|
|
|
|
|
|
|
|
// This creates a **new** Obj, and the variable `person` now points to it.
|
|
|
|
person = Obj {name: "Alex"}
|
|
|
|
/*
|
|
|
|
john ---------> {name: "John"}
|
|
|
|
person -------> {name: "Alex"}
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
set_empty(mut obj)
|
|
|
|
|
|
|
|
print(obj) // Obj {name: "John"}
|
|
|
|
|
|
|
|
```
|
2023-06-27 03:11:02 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2023-12-17 01:33:55 +00:00
|
|
|
## Example
|
2023-06-27 03:11:02 +00:00
|
|
|
|
2023-10-02 02:26:57 +00:00
|
|
|
```thp
|
2023-06-27 03:11:02 +00:00
|
|
|
use PDO
|
|
|
|
use Globals::Env
|
|
|
|
|
|
|
|
val (Some(dbUri) Some(dbUser) Some(dbPassword)) = (
|
|
|
|
Env::get("DB_URI")
|
|
|
|
Env::get("DB_USERNAME")
|
|
|
|
Env::get("DB_PASSWORD")
|
|
|
|
)
|
|
|
|
else {
|
|
|
|
die("All 3 db environment variables must be set.")
|
|
|
|
}
|
|
|
|
|
2023-10-02 02:26:57 +00:00
|
|
|
match PDO(dbUri dbUser dbPassword)
|
|
|
|
| Ok(connection) { /* db operations */ }
|
|
|
|
| Err(pdoException) { /* handle exception */ }
|
2023-06-27 03:11:02 +00:00
|
|
|
```
|
|
|
|
|