thp-lang.org/src/pages/index.astro

226 lines
6.9 KiB
Plaintext
Raw Normal View History

2024-04-23 15:16:51 +00:00
---
import BaseLayout from "../layouts/BaseLayout.astro";
import Navbar from "../components/Navbar.astro";
2024-06-20 22:29:30 +00:00
import CodeEditor from "../components/CodeEditor.astro";
2024-06-29 02:37:20 +00:00
import HeroSection from "../components/HeroSection.astro";
2024-04-23 15:16:51 +00:00
---
<BaseLayout>
2024-06-29 02:37:20 +00:00
<Navbar showSidebarButton={false} />
<div
class="container mx-auto lg:py-16 pb-2 pt-20 lg:grid 2xl:grid-cols-[auto_32rem] lg:grid-cols-[auto_36rem] gap-4 lg:px-10 px-2 min-h-[85vh]"
>
<div class="lg:pl-10 table">
<div class="table-cell align-middle">
<h1
class="font-display font-bold text-c-text-2 lg:text-5xl text-3xl lg:text-left text-center leading-tight"
>
A modern, type safe,
<br class="hidden lg:inline-block" />
secure language
<br class="hidden lg:inline-block" />
compiled to PHP
</h1>
<p class="font-display text-c-text text-xl pt-6 lg:pr-12">
Inspired by Rust, Zig and Kotlin, THP has a modern syntax,
semantics, type system and stdlib.
</p>
<br />
<br />
<div class="text-center">
<a
class="inline-block font-display text-lg rounded-full border-2 border-pink-400 py-2 px-8
2024-04-23 15:16:51 +00:00
transition-colors hover:text-black hover:bg-pink-400"
2024-06-29 02:37:20 +00:00
href="/learn/"
>
Tutorial
</a>
2024-04-23 15:16:51 +00:00
2024-06-29 02:37:20 +00:00
<a
class="inline-block font-display text-lg border-2 border-sky-400 py-2 px-8 mx-6 rounded-full
2024-04-23 15:16:51 +00:00
transition-colors hover:text-black hover:bg-sky-400"
2024-06-29 02:37:20 +00:00
href="/install/"
>
Install
</a>
</div>
</div>
</div>
<div class="table">
<div class="table-cell align-middle">
<div
class="bg-[var(--code-theme-bg-color)] lg:p-6 p-2 rounded-lg relative w-full"
>
<span
class="absolute lg:inline-block hidden h-[35rem] w-[35rem] -z-10 top-1/2 left-1/2 rounded-full
2024-06-20 22:29:30 +00:00
transform -translate-x-1/2 -translate-y-1/2"
2024-06-29 02:37:20 +00:00
style="background-image: conic-gradient(from 180deg at 50% 50%,#5BCEFA 0deg,#a853ba 180deg,#F5A9B8 1turn);
2024-06-20 22:29:30 +00:00
filter: blur(75px); opacity: 0.75;"
2024-06-29 02:37:20 +00:00
>
</span>
<svg
xmlns="http://www.w3.org/2000/svg"
width="54"
height="14"
viewBox="0 0 54 14"
>
<g
fill="none"
fill-rule="evenodd"
transform="translate(1 1)"
>
<circle
cx="6"
cy="6"
r="6"
fill="#FF5F56"
stroke="#E0443E"
stroke-width=".5"></circle>
<circle
cx="26"
cy="6"
r="6"
fill="#FFBD2E"
stroke="#DEA123"
stroke-width=".5"></circle>
<circle
cx="46"
cy="6"
r="6"
fill="#27C93F"
stroke="#1AAB29"
stroke-width=".5"></circle>
</g>
</svg>
<div class="h-1"></div>
<div id="editor" class="font-mono language-thp"></div>
</div>
</div>
</div>
</div>
<HeroSection
2024-06-29 03:11:27 +00:00
subtitle="We've got"
title="generics"
2024-06-29 02:37:20 +00:00
thpcode={`
Array[Int] numbers = [0, 1, 2, 3, 4, 5]
numbers.push("7") // Compile error: expected an Int, found a String
// Runtime type checking
val object = try JSON::decode(data)
val name = try object.get[String]("name")
// Any is available, but it's not usable without an explicit cast
fun mock() -> Any { ... }
// Compile error: Cannot use \`Any\` without an explicit cast
val result = mock()
// Ok
val result = mock() as String
`}
>
THP enforces type safety at compile time and, at the programmer's
request, at runtime.
<br />
<br />
Everything has a type. There are generics. No implicit type conversions.
No <code>mixed</code>. No client <code>Any</code> .Type inference included.
<br />
<br />
All possible checks are made at compile time. Runtime checks have a small
performance penalty.
</HeroSection>
<HeroSection
2024-06-29 03:11:27 +00:00
subtitle="We've got"
title="tagged unions"
2024-06-29 02:37:20 +00:00
thpcode={`
2024-06-29 03:11:27 +00:00
union DirEntry {
File(String),
Dir(String),
}
val root = DirEntry::Dir("/")
`}
>
Make invalid state irrepresentable.
<br>
Model data in a type-safe way.
<br>
Ensure all cases are handled.
</HeroSection>
<HeroSection
subtitle="We've got"
title="pattern matching"
thpcode={`
match test_file
case DirEntry::File(filename)
if !filename.starts_with(".")
2024-06-29 02:37:20 +00:00
{
2024-06-29 03:11:27 +00:00
print(filename)
}
else
{
print("A valid file was not found")
}
`}
>
Match on values, tuples, enums, unions, types etc.
<br>
Guards available!
</HeroSection>
<HeroSection
subtitle="We've got"
title="null safety"
thpcode={`
String? username = Globals::Post::get("username")
if username? {
// username is a \`String\` here
print("Hello, {username}")
2024-06-29 02:37:20 +00:00
}
`}
>
2024-06-29 03:11:27 +00:00
Nulls are explicit and require handling.
2024-06-29 02:37:20 +00:00
</HeroSection>
<script>
import { thp_highlighter, CodeJar } from "../lexer/highlighter";
let jar = CodeJar(document.getElementById("editor")!, thp_highlighter, {
tab: " ",
});
jar.updateCode(
`union Animal {
2024-05-26 21:08:11 +00:00
Dog(String),
Cat(String, Int),
2024-04-23 15:16:51 +00:00
}
2024-06-20 22:29:30 +00:00
val cat_name = Post::get("cat_name") ?? "Michifu"
val my_cat = Animal::Cat(cat_name, 9)
2024-05-26 21:08:11 +00:00
2024-06-20 22:29:30 +00:00
try change_fur_color(cat) else die("Not a cat")
2024-05-26 21:08:11 +00:00
match random_animal()
2024-06-20 22:29:30 +00:00
case Dog(name)
{
print("{name} has 1 live ")
}
case Cat(name, lives) {
print("{name} has {lives}")
}`,
2024-06-29 02:37:20 +00:00
);
</script>
<script>
import { highlightOnDom } from "../layouts/thpHighlighter";
2024-06-20 22:29:30 +00:00
document.addEventListener("DOMContentLoaded", highlightOnDom);
2024-06-29 02:37:20 +00:00
</script>
2024-04-23 15:16:51 +00:00
</BaseLayout>