diff --git a/src/components/Sidebar.astro b/src/components/Sidebar.astro index 62aac52..b7b65be 100644 --- a/src/components/Sidebar.astro +++ b/src/components/Sidebar.astro @@ -4,10 +4,15 @@ import type { PageEntry } from "../layouts/PagesLayout.astro"; const entry: PageEntry = Astro.props.entry; const basePath: string = Astro.props.basePath; -const entryPath = entry.path === "index"? "": entry.path; +const entryPath = is_index_file(entry.path)? "": entry.path; const entryUrl = basePath + entryPath + (entryPath.endsWith("/")? "" : "/"); +function is_index_file(p) { + return p.endsWith("index") + || p.endsWith("index.md") + || p.endsWith("index.mdx") +} --- { diff --git a/src/layouts/DocsLayout.astro b/src/layouts/DocsLayout.astro index 2d6102f..47096c0 100644 --- a/src/layouts/DocsLayout.astro +++ b/src/layouts/DocsLayout.astro @@ -3,7 +3,7 @@ import PagesLayout from "./PagesLayout.astro"; const { frontmatter, headings } = Astro.props; -const posts = await Astro.glob("../pages/learn/**/*.{md,mdx}"); +const posts = await Astro.glob("@/pages/learn/**/*.{md,mdx}"); const indexSubpath = `/learn/index.mdx`; --- diff --git a/src/layouts/NewDocsLayout.astro b/src/layouts/NewDocsLayout.astro new file mode 100644 index 0000000..efabf4e --- /dev/null +++ b/src/layouts/NewDocsLayout.astro @@ -0,0 +1,106 @@ +--- +import Navbar from "../components/Navbar.astro"; +import BaseLayout from "./BaseLayout.astro"; +import TOC from "../components/TOC.astro"; +import Sidebar from "../components/Sidebar.astro"; + +export type PageEntry = { + path: string; + title?: string; + children?: Array; +}; + +export interface AstroFile { + frontmatter: Frontmatter + __usesAstroImage: boolean + url: string + file: string + relative_file: string +} + +export interface Frontmatter { + layout: string + title: string +} + +type Props = { + /** The directory where all the md/mdx files start from */ + base_dir: string + frontmatter: Frontmatter; + headings: any; + posts: Array; +}; + +const { + base_dir, + frontmatter, + headings, + posts +}: Props = Astro.props; + +const base_dir_end = base_dir.length; + +const posts_2 = posts.map(post => ({ + ...post, + relative_file: post.file.substring(base_dir_end), + path: post.file.substring(base_dir_end), + title: post.frontmatter.title, +})) + +const index_page = posts_2.find(post => post.relative_file === "/index.md" || post.relative_file === "/index.mdx"); +const basePath = index_page.url; + +console.log(JSON.stringify(index_page, null, 4)); + +const pagesIndex = posts_2; +--- + + + + +
+ + +
+ +
+ + +
+ + + +
diff --git a/src/pages/en/latest/learn/_wrapper.astro b/src/pages/en/latest/learn/_wrapper.astro new file mode 100644 index 0000000..0b4cda3 --- /dev/null +++ b/src/pages/en/latest/learn/_wrapper.astro @@ -0,0 +1,19 @@ +--- +import path from "path"; +import NewDocsLayout from "@/layouts/NewDocsLayout.astro"; + +const { frontmatter, headings } = Astro.props; +// Get all the posts from this dir +const posts = await Astro.glob("./**/*.{md,mdx}"); +// Current dir +const current_dir = import.meta.dirname; +--- + + + + diff --git a/src/pages/en/latest/learn/index.mdx b/src/pages/en/latest/learn/index.mdx new file mode 100644 index 0000000..5b29523 --- /dev/null +++ b/src/pages/en/latest/learn/index.mdx @@ -0,0 +1,246 @@ +--- +layout: "./_wrapper.astro" +title: Welcome +--- +import InteractiveCode from "@/components/InteractiveCode.astro"; +import Code from "@/components/Code.astro" + + +# Welcome + +Welcome to the documentation of the THP programming languague. + +THP is a new programming language that compiles to PHP. + +![Accurate visual description of THP](/img/desc_thp.jpg) + + +This page details the main design desitions of the language, +if you want to install THP go to the [installation guide](install) + + +## Why? + +PHP is an old language. It has been growing since 1995, adopting a +lot of features from many places like C, Perl, Java, etc. This was +done in a very inconsistent way, as detailed by Eevee in their article +[PHP: a fractal of bad design.](https://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/) + +Along the years PHP has been improving. PHP added classes, exceptions, +interfaces, traits, type hints and checks, functional features, +reflection, etc., etc. However, by building on top of the existing +language without a clear design philosophy, and by keeping backwards +compatibility, we ended up with a messy language. The article +above goes into detail about this. + +In spite of this, PHP has remained widely used and loved, in a +weird way (I'd say in the same way that people love JavaScript), +and at the time of writing PHP 8.3 is available. However, +PHP is to my eyes fundamentally flawed, and cannot get up to +date without completely breaking what came before. + +This is where THP comes in. I wanted a modern language +that could run in the same environment that PHP does. +And I quickly realized that building on top of PHP +in the same way that TypeScript did for JavaScript would be +detrimental. It would be better to create a completely new +language, treat PHP source code as a "low level" compilation +target, and focus entirely on the new language. + +This new language would be mainly inspired by what **I** consider the best +designed languages out there: Rust as a baseline, Zig for +its null and error handling and Kotlin for its OOP features. +In a way, PHP will be adapted to, say, Rust's syntax and semantics, +instead of having Rust adapt to PHP. + +In pursue of this THP **will** ditch many things about PHP, +in name of consistency. These are things that PHP devs are +used to doing, but that I consider bad practices, hacks or +workarounds. One example of this are variable variables on PHP: +`$$variable`. + +Another critical point of THP is type safety. It is a goal +to approach the same level of type safety that have compiled +languages like Java/Go/Rust, and leave aside dynamic typing +as much as possible. Types cannot be turned off, you cannot +use `Any` to avoid typechecking, and so on. + +Finally, there are some additions to the language that I consider +essential today: A good, unified LSP, type definitions, +accesible documentation, an opinionated code formatter +and plugins for major editors like VSCode and Neovim. + + + + + +## Goals + +- Bring static typing to PHP: Generics, type checks at compile and runtime, etc. +- Reduce implicit type conversion to a minimum. +- Remove the inconsistencies in the language. +- Organize the PHP stdlib. +- Have a clear distinctions between Arrays, Tuples, Maps and Sets. +- Implement Union types +- Create a **consistent** language. +- Have typings for popular libraries (like TS's `.d.ts`). +- Have a simple instalation and configuration (requiring just Composer or a binary). +- Ship a **_blazingly fast_**, native binary, ~~written in Rust~~ now rewritten in Zig!. +- Support in-place compilation. +- Implement a Language Server. +- Implement an opinionated code formatter. + +![Friendship ended with Rust, now Zig is my best friend.](/img/mudasir.jpg) + + +## Not goals + +These are **not** things that THP wants to solve or implement + +- Be what TypeScript is for JavaScript (PHP with types). +- Strictly adhere to PHP syntax/conventions. + +THP **_intentionally_** uses a different syntax from PHP to signal +that it is a different language, and has different semantics. + + +## Some differences with PHP + +```php +// PHP +$has_key = str_contains($haystack, 'needle'); +print("has key? " . $has_key); +``` + + + +- Explicit variable declaration +- No `$` for variable names (and thus no `$$variable`, use a map instead) +- No semicolons +- Use methods on common datatypes +- Strings use only double quotes +- String concatenation with `+` + + +
+
+ +```php +// PHP +$obj = [ + 'names' => ['Toni', 'Stark'], + 'age' => 33, + 'numbers' => [32, 64, 128] +] +``` + + + +- Tuples, Arrays, Sets, Maps are clearly different +- JSON-like object syntax + +
+
+ +```php +// PHP +$cat = new Cat("Michifu", 7); +$cat->meow(); +``` + + + + +- Instantiate classes without `new` +- Use dot `.` instead of arrow `->` syntax + +
+
+ +```php +// PHP +use \Some\Deeply\Nested\Class +use \Some\Deeply\Nested\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: + + 18 + { + "Welcome, {person.name}" + } + case Some(person) + { + "I'm sorry {person.name}, you need to be 18 or older" + } + case None + { + "Nobody is here" + } +`} /> + +```php +// 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. + + diff --git a/tsconfig.json b/tsconfig.json index 3fd7ae6..f58a004 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,3 +1,9 @@ { - "extends": "astro/tsconfigs/strictest" -} \ No newline at end of file + "extends": "astro/tsconfigs/strictest", + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@/*": ["src/*"], + } + } +}