195 lines
3.6 KiB
Markdown
195 lines
3.6 KiB
Markdown
![Accurate visual description of THP](/img/desc_thp.jpg)
|
|
|
|
|
|
# Welcome
|
|
|
|
Welcome to the documentation of the THP programming languague.
|
|
|
|
THP is a new programming language that compiles to PHP.
|
|
|
|
<br>
|
|
|
|
This page discusses some of the design decitions of the language,
|
|
if you want to install THP go to the [installation guide](/installation-guide)
|
|
|
|
If you want to learn the language, go to the learn section.
|
|
|
|
## Goals
|
|
|
|
- Bring static typing to PHP: Not just type hints, not just `mixed` for everything
|
|
that isn't a primitive type.
|
|
- Generics & ADTs
|
|
- Avoid implicit type conversion.
|
|
- Remove the inconsistencies in the language.
|
|
- Organize the stdlib into modules.
|
|
- Differentiate between Arrays, Tuples, Maps and Sets.
|
|
- Create a **consistent** language.
|
|
- Have typings for popular libraries (like TS's `.d.ts`).
|
|
- Have a simple instalation and configuration (requiring just Composer).
|
|
- Ship a fast, native binary (written in Rust) (why use PHP when we can go **_blazingly fast_**?).
|
|
- Support in-place compilation.
|
|
- (Try to) emit readable PHP.
|
|
- Implement an LSP server.
|
|
- Implement a formatter.
|
|
|
|
|
|
## Not goals
|
|
|
|
These are **not** aspects that THP looks to solve or implement.
|
|
|
|
- Be what TypeScript is for JavaScript (PHP with types).
|
|
- Use PHP syntax/conventions.
|
|
- Be familiar for PHP developers.
|
|
|
|
|
|
## Philosophy
|
|
|
|
- Consistency over familiarity
|
|
- Change over conventions
|
|
- Explicit over implicit
|
|
|
|
|
|
## 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
|
|
.{
|
|
names: #("Toni", "Stark"), // Tuple
|
|
age: 33,
|
|
numbers: [32, 64, 128]
|
|
}
|
|
```
|
|
|
|
- Tuples, Arrays, Sets, Maps are clearly different
|
|
- JSON-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
|
|
- Explicit module declaration
|
|
- PSR-4 required
|
|
- No `include`, `include_once`, `require` or `require_once`
|
|
|
|
---
|
|
|
|
Other things:
|
|
|
|
- Pattern matching
|
|
- ADTs
|
|
|
|
|
|
## Runtime changes
|
|
|
|
Where possible THP will compile to available PHP functions/classes/methods/etc.
|
|
|
|
For example:
|
|
|
|
```thp
|
|
// This expression
|
|
val greeting =
|
|
match get_person()
|
|
| Some(person) if person.age > 18
|
|
{
|
|
"Welcome, {person.name}"
|
|
}
|
|
| Some(person)
|
|
{
|
|
"I'm sorry {person.name}, you need to be 18 or older"
|
|
}
|
|
| None
|
|
{
|
|
"Nobody is here"
|
|
}
|
|
|
|
|
|
// Would compile to:
|
|
$greeting = null;
|
|
$_person = get_person();
|
|
if ($_person !== null) {
|
|
if ($_person["age"] > 18) {
|
|
$greeting = "Welcome, " . $_person["name"];
|
|
}
|
|
else {
|
|
$greeting = "I'm sorry " . $_person["name"] . ", you need to be 18 or older";
|
|
}
|
|
}
|
|
else {
|
|
$greeting = "Nobody is here";
|
|
}
|
|
```
|
|
|
|
However, more advanced datatypes & helper functions will require a sort of
|
|
runtime (new classes/functions/etc) or abuse the language's syntax/semantics.
|
|
|
|
|
|
```thp
|
|
// TBD: Enum compilation
|
|
enum IpAddress {
|
|
V4(String),
|
|
V6(String),
|
|
}
|
|
|
|
val ip_1 = IpAddress::V4("255.255.0.0")
|
|
|
|
|
|
// Would possibly compile to:
|
|
enum IpAddress {
|
|
V4,
|
|
V6,
|
|
}
|
|
|
|
$ip_1 = [IpAddress::V4, "255.255.0.0"]
|
|
```
|
|
|
|
Such changes will be documented
|
|
|
|
|