diff --git a/md/learn/adts/union-types.md b/md/learn/adts/union-types.md new file mode 100644 index 0000000..ae653b0 --- /dev/null +++ b/md/learn/adts/union-types.md @@ -0,0 +1,51 @@ +# Union types + +## Basic enums + +```thp +enum Suit +{ + Hearts, + Diamonds, + Clubs, + Spades, +} + +val suit = Suit::Hearts +``` + + +## Enums with values + +```thp +enum IpAddress +{ + V4(String), + V6(String), +} + +val addr_1 = IpAddress::V4("192.168.0.1") + +match addr_1 +| IpAddress::V4(ip) +{ + // code.. +} +| IpAddress::V6(ip) +{ + // more code.. +} + +// Without the full qualifier +match addr_1 +| ::V4(ip) +{ + // code... +} +| ::V6(ip) +{ + // even more code... +} +``` + + diff --git a/md/learn/basics/comments.md b/md/learn/basics/comments.md index 04bdbf7..7965040 100644 --- a/md/learn/basics/comments.md +++ b/md/learn/basics/comments.md @@ -1,80 +1,28 @@ # Comments -You may have noticed that in some code examples there are some -lines of text explaining the code: +Only these two: -```thp -// This is the variable -val person = "John" -``` - -Comments are used to explain what the code does. Anything written -in a comment is ignored by THP. - -## Single line comments - -As the name says, these comments span only 1 line. To create one write -two slashes together `//`. Everything after the slashes and before -the newline will be ignored. +## Single line ```thp // This is a single line comment -// You can write anything you want here, although it's usually -// used to describe the code - -// The commend ends where the line ends, -so this line will not be ignored by THP, and will throw an error ``` - -## Multi line comments - -As the name says, these comments can span multiple lines. - -They have 2 components: a start and a end. To start a multiline comment -write a slash and asterisk `/*`, and to end the comment, the inverse `*/` +## Multi line ```thp /* - This is a multiline comment. - I can write whatever I want here, and across multiple - lines, as long as I'm before the closing characters (* /) + This is a + multiline comment +*/ +``` + +```thp +/* + Multiline comments + can be /* nested */ */ ``` -## Using comments to prevent code execution - -Since comments are ignored by THP, we can use them to prevent certain -parts of the code from running. - -Let's say we have this script: - -```thp -print("Hello John") -print("How's your day going?") -``` - -If I wanted the 2nd line not to execute, I can use a comment: - -```thp -print("Hello John") -// print("How's your day going?") -``` - -Now the second line is ignored, and the message is not printed. - -The same can be done with multiline comments. - - -```thp -print("Hello John") -/* -print("How's your day going?") -*/ -``` - - - - diff --git a/md/learn/basics/datatypes.md b/md/learn/basics/datatypes.md index 119cdd6..4af7ee0 100644 --- a/md/learn/basics/datatypes.md +++ b/md/learn/basics/datatypes.md @@ -1,127 +1,45 @@ # Datatypes -Programming is comprised of 2 basic things: instructions and data. +Datatypes's first character are always uppercase. -If we compare a program to a cake recipe, the instructions are the steps -(**pour** flour, **add** water, **add** egg, **mix**) and the data are the ingredients -themselves (flour, water, egg). +## Int -![Image](Image) - -Then, we can describe the recipe in terms of instructions and data. For example, -"mix flour and egg to produce dough". - -![Image](Image) - -All code is like a recipe: A list of instructions and data that, when combined -correctly, are able to transform a input to an output. Many advanced concepts -are just ways to organize and abstract those instructions and data. - - -## Classifying datatypes - -As with food, datatypes can be classified. Just like there are fruits, vegetables, -oils, there are `numbers`, `text`, `"booleans"`. - - - -### Int - -Int is an abbreviation for "integer numbers", which are numbers without a fractional component. -They can be positive or negative. - -In code, they are written just like numbers: +Same as php int ```thp -val age = 33 -val children = 0 -val money = -15000 -``` - -You can use underscores to help you differentiate thousands, millions, etc. -However, there cannot be spaces in between - -```thp -val studentDebt = 3_500_000_000_000 // Valid -val invalid = 3 500 000 000 000 // Invalid, will throw an error -``` - -The common operations can be done as in math: - -```thp -val result1 = 10 + 20 -val result2 = 1779 * 2 - (55 / 5) +Int age = 32 +Int red = 0xff0000 +Int char_code = 0b01000110 ``` -### Float +## Float -Float is an abbreviation for "floating point numbers". In simplified terms, these are numbers -**with** a fractional component. - -They are written with a dot `.` to separate the whole part and the fraction. - -```thp -val pi = 3.141592 -val epsilon = 2.775557 -``` - -Underscore can also be used: - -```thp -val reallyLongNumber = 23_870_000.443_879 -``` - -Common operations can be performed the same way: - -```thp -val value1 = 552.23 - 32 -val value2 = 3.2 * (-0.22 + 23.334) / 0.5 -// etc. -``` - -### String - -A string of letters (technically, characters). Strings are used to represent text, -and are wrapped in quotation marks. - -```thp -val name = "John" -val lastName = "Doe" - -val greeting = "Hello" -``` - -#### Concatenation - -Strings cannot be added, substracted, multiplied, divided. -They have another operation, called "concatenation". - -Concatenation "joins" two strings, for example, the concatenation of -`"human"` and `"kind"` is `"humankind"`. - -As it is a common operation, string concatenation reuses the operation -for addition `+`. - -```thp -val string = "human" + "kind" -``` - - -### Boolean - -A boolean represents something that can only be in one of two states. - -Booleans are useful in conditionals, which will be explained later. +Same as php float ```thp -val condition = true -val isSunny = false - -if isSunny { - doSomething() -} +Float pi = 3.141592 ``` +## String + +Same as php string + +```thp +String name = "Rose" +``` + + +## Bool + +Same as php bool + +```thp +Bool is_true = true +``` + + + + diff --git a/md/learn/basics/hello-world.md b/md/learn/basics/hello-world.md index 692f34a..4338752 100644 --- a/md/learn/basics/hello-world.md +++ b/md/learn/basics/hello-world.md @@ -1,60 +1,9 @@ # Hello, world! -This pages shows you how to write and run your first THP script. - -## Prerequisites - -You will need to have PHP and THP installed. If you haven't already, see the -install page. - -## Writing the program - -Create a new file called `hello.thp`, and inside write the following (you can -copy and paste): +Create a file named `hello.thp` with the contents: ```thp print("Hello, world!") ``` -Then, save the code. - -## Running the program - -Open a terminal in the folder where you created the file `hello.thp`. -Then write the following command and press enter: - -```sh -thp hello.thp -``` - -This will run the program, and produce the following result: - -```sh -Hello, world! -``` - -Congratulations! You just wrote your first THP program! - -## Explaining the program - -Now let's understand the code. - -```thp -print("Hello, world!") -``` - -There are 2 essential components: - -- `print` - print is a "function", it takes some value and performs some action with it. - In this case, it takes a text and displays it in the terminal. -- `"Hello, world!"` - Is the text that the function `print` takes, and displays in - the terminal. Note that it is enclosed in quotation marks. - -## What to do next - -You can now experiment with the program you wrote. What happens if you change the text? -What if you don't put quotation marks? And what are the parenthesis for? - -To continue learning about THP, continue to the next page, where you'll learn -about "datatypes". - +Then run `thp hello.thp` diff --git a/md/learn/basics/io.md b/md/learn/basics/io.md deleted file mode 100644 index 3c7e574..0000000 --- a/md/learn/basics/io.md +++ /dev/null @@ -1,64 +0,0 @@ -# Input & Output - -At the end of the day, a program takes some input, -and transform it to some output. We will explore how to -receive data, and also present it. - -## Output - -There are many ways to show the result of our programs. -One of them is called `standard output`, which in simplified -terms, is the terminal from where we run our program. - -### `print` - -Create an empty file, and name it `hello.php`. We will create -a program that shows a result to our screen. - -Inside `hello.php` write the following code: - -```thp -print("Hello") -``` - -Then, open a terminal and run the program with the `thp` command. -After you press ENTER, you will see in the terminal the text "Hello". - - -```sh -$ thp hello.thp # Copy this command and run it -Hello # This is the output of our program -``` - -The thp function `print` allows us to display something in the terminal. - -If you change the `hello.php` file, and run it, you'll see how it changes. - -```thp -print(322) -``` -```sh -$ thp hello.php -322 -``` - -Or, if you copy `print` multiple times, each will show something in the screen. - -```thp -print("Hello") -print("This is an example") -print("of having many prints") -``` -```sh -$ thp hello.php -Hello -This is an example -of having many prints -``` - -### Using `print` in a larger program - - - - - diff --git a/md/learn/basics/the-compiler.md b/md/learn/basics/the-compiler.md deleted file mode 100644 index 7b25a20..0000000 --- a/md/learn/basics/the-compiler.md +++ /dev/null @@ -1,72 +0,0 @@ -# The compiler - -The compiler is the program that takes your THP code and converts it -into something that the computer can run (in this case, PHP code). - - - -The compiler reads your code and tries to understand it. -When it can't understand some part, it will ask you to clarify what -you meant, with an error. - - - - - - -## Compile time vs runtime - -Compile time is when you build your program. - -Runtime is when you run your program. - -To make an analogy with cars, compile time would be the factory, -while runtime would be using the finished car. - - - -The compiler is very strict. If it finds any errors during compile time -it will refuse to build the program. - - -### Compile time errors - -Compile time errors are errors that happen while the compiler is -building your program. In the car analogy, a compile error would happen -if there's an error in the "blueprint" - - -### Runtime errors - -These are errors that happen to the built program, or in this case, -the finished car. It would be like the car blowing up while on the highway. - -To minimize the amount of runtime errors the compiler tries to catch them all -during compile time. It's better if it fails in the factory than in the -real world. - - -## The compiler and datatypes - -The first measure the compiler takes is to check that all the datatypes -match. If an operation requires a number, you can't just give it a string. - - - -For example, if we wanted to add a number to a string, we would get an -error: - -```thp -50 + "hello" // Error: The `+` operator expects two Numbers, - // but an String was found. -``` - -This way, we can assure that many errors are avoided (since it doesn't -really make sense to add a number to a text). - - - - - - - diff --git a/md/learn/basics/variables.md b/md/learn/basics/variables.md index 8b8e213..a9906b6 100644 --- a/md/learn/basics/variables.md +++ b/md/learn/basics/variables.md @@ -1,138 +1,55 @@ # Variables -Variables allows us to store values under a name, so that we can use them -later. +thp distinguishes between mutable and immutable variables. -For example, in a program we could have the name of our user, and use it -multiple times: +## Mutable variables + +Defined with `var`, followed by a variable name and a value. ```thp -print("Hello, where's Joe?") -print("How old is Joe?") -print("Do you know if Joe has kids?") +var name = "John" +var age = 32 ``` -We are using the same value `Joe` many times. Each time we use it we have -to type `Joe`. But what happens if we needed to use a different name? -We'd have to change the name everywhere in our code! +### Datatype annotation + +Written after the `var` keyword but before the variable name. ```thp -print("Hello, where's Jane?") -print("How old is Jane?") -print("Do you know if Jane has kids?") +var String name = "John" +var Int age = 32 ``` -## Variables to the rescue +When annotating a mutable variable the keyword `var` is _required_. -With a variable we can store values so we can use them later, or use them -in multiple times. -In the previous code, we can use a variable to store the person's name, -and then use it everywhere. +## Immutable variables + +Defined with `val`, followed by a variable name and a value. ```thp -// This is the variable -val person = "John" - -print("Hello, where's {person}?") -print("How old is {person}?") -print("Do you know if Joe has {person}?") +val surname = "Doe" +val year_of_birth = 1984 ``` -Now, instead of writing `"John"` every time, we write the name of the -variable instead. +### Datatype annotation -If we wanted to change the person's name to "Jane", we just need to change -it in one place: the variable +Same as mutable variables ```thp -// We change this -val person = "Jane" - -// And all these lines will use the new value -print("Hello, where's {person}?") -print("How old is {person}?") -print("Do you know if Joe has {person}?") +val String surname = "Doe" +val Int year_of_birth = 1984 ``` -## Variable rules - -To use a variable we do the following: - -- Write the special word `val` -- Write the name of our variable -- Write the equal sign `=` -- Write the value of our variable +When annotating an immutable variable the `val` keyword is optional ```thp - val person = "Jane" -/* --- ------ - ------ - | | | +- The value of our variable - | | +----- The equal sign - | +---------- The name of our variable - +--------------- The special word (keyword) val -*/ +// Equivalent to the previous code +String surname = "Doe" +Int year_of_birth = 1984 ``` -The value can be anything: ints, floats, string, bools, even other variables and operations! - -```thp -val variable_1 = 322 -val variable_2 = 123.456 -val variable_3 = "a text" -val variable_4 = false -val variable_5 = variable_1 + variable 2 -``` - -## Variable name rules - -- Starts with a lowercase letter (a-z) or underscore (`_`) -- Then can have any letter (a-zA-Z), underscore (`_`) or number (0-9) -- Cannot have spaces -- Cannot have the same name as a keyword (for example, the `val` keyword) - - -Some examples of valid variable names: - -```thp -val name = ... -val age = ... -val my_name = ... -val many_words_joined_by_underscores = ... -val person_2 = ... -val person_3 = ... -``` - -Some invalid variables and why they are invalid: - -```thp -val 1name = ... // Invalid: starts with a number -val 123_person = ... // Invalid: starts with a number -val val = ... // Invalid: same name as a keyword (val) -val Person = ... // Invalid: starts with an uppercase letter -val person name = ... // Invalid: contains whitespace -val +@name = ... // Invalid: contains non-letters (+@) -val name🫠 = ... // Invalid: contains emoji (🫠) -``` - - -## Variable reassignment - -When you create a new variable with the same name of an old variable, -the old is "replaced" with the new one. - -```thp -val person_name = "John" -print(person_name) // Will print "John" - -val person_name = "Jane" -print(person_name) // Will print "Jane" -``` - -This will have some implications on the future, but for now you should -now that you will always use the value of the last variable you define. - - +This means that if a variable has only a datatype, it is immutable. diff --git a/md/learn/classes/definition.md b/md/learn/classes/definition.md new file mode 100644 index 0000000..a591827 --- /dev/null +++ b/md/learn/classes/definition.md @@ -0,0 +1,94 @@ +# Classes + +Basically kotlin syntax. + +Methods have to have a first parameter `$`. + + +## Create a new instance of a class + +`new` not required, in fact, forbidden. + +```thp +val dog = Dog() +``` + +## Simple class + +Why'd you do this tho? + +```thp +class SimpleClass + +val instance = SimpleClass() +``` + +## Properties & methods + +```thp +class SimpleClass +{ + // Properties are private by default + var String? name; + + // Made public with `public` + public var String? surname; + + // Methods are private by default + fun display_name($) + { + // `$` is used instead of $this + print($name) + } + + public fun get_name($) -> String? + { + $name + } +} +``` + +## Static members + +no + + +## Constructor + +Kotlin style + + +```thp +class Cat(val String name) +{ + public fun get_name($) -> String + { + $name + } +} + +val michifu = Cat("Michifu") +print(michifu.get_name()) +``` + +## Inheritance + +Kotlin style + +```thp +class Animal(val String name) +{ + public fun say_name($) + { + print($name) + } +} + +class Cat(String name, Int lives) -> Animal(name) + +Cat("Michi", 9).say_name() +``` + + + + diff --git a/md/learn/classes/static.md b/md/learn/classes/static.md new file mode 100644 index 0000000..7691bd1 --- /dev/null +++ b/md/learn/classes/static.md @@ -0,0 +1,48 @@ +# Static in classes + + +## Class constants + +```thp +static Cat { + const CONSTANT = "constant value" +} + +print(Cat::CONSTANT) +``` + + +## Static methods + +aka. plain, old functions + + +```thp +static Cat { + fun static_method() -> Int { + // ... + } +} + +Cat::static_method() +``` + + +## Static properties + +aka. global variables + + +```thp +static Cat { + public var access_count = 0 +} + +print(Cat::access_count) // 0 +Cat::access_count += 1 +print(Cat::access_count) // 1 +``` + + + + diff --git a/md/learn/collections/arrays.md b/md/learn/collections/arrays.md new file mode 100644 index 0000000..ccfeb6a --- /dev/null +++ b/md/learn/collections/arrays.md @@ -0,0 +1,35 @@ +# Arrays + +No destructuring (for now?). There's no `[]` syntax +for constructing arrays + +## Usage + +```thp +val fruits = Array("apple", "banana", "cherry") +val apple = fruits.[0] + +print(apple) + + +var numbers = Array(0, 1, 2, 3) + +// Note the dot +numbers.[3] = 5 + +print(numbers.[3]) // 5 +``` + + +## Type signature + + +```thp +Array[String] +Array[Int] +``` + + + + + diff --git a/md/learn/collections/maps.md b/md/learn/collections/maps.md new file mode 100644 index 0000000..b6d5e3a --- /dev/null +++ b/md/learn/collections/maps.md @@ -0,0 +1,43 @@ +# Maps + +Also known as Associative Arrays + + +## Usage without a declaration + +```thp +var person = Obj { + name: "John", + surname: "Doe", + age: 33, +} + + +print("Hello {person.name}") + +person.age += 1 + +print("You just turned {person.age}") +``` + + +## Usage with a declaration + +```thp +obj Person = { + String name, + String surname, + Int age, +} + + +val john_doe = Person { + name: "John", + surname: "Doe", + age: 33, +} +``` + + + + diff --git a/md/learn/collections/sets.md b/md/learn/collections/sets.md new file mode 100644 index 0000000..357823a --- /dev/null +++ b/md/learn/collections/sets.md @@ -0,0 +1,11 @@ +# Sets + + +```thp +// Set[Int] +val ages = Set(30, 31, 33, 35) + +for age in ages { + print("{age}") +} +``` diff --git a/md/learn/collections/tuples.md b/md/learn/collections/tuples.md new file mode 100644 index 0000000..3db7b71 --- /dev/null +++ b/md/learn/collections/tuples.md @@ -0,0 +1,22 @@ +# Tuples + +Uses `#()` just to avoid confusion with function +calls (`()`). + +## Definition + +```thp +val person = #("John", "Doe", 32) + +val #(name, surname, age) = person +``` + + +## Signature + +```thp +#(String, String, Int) +``` + + + diff --git a/md/learn/flow-control/conditionals.md b/md/learn/flow-control/conditionals.md index d7e57db..0846b95 100644 --- a/md/learn/flow-control/conditionals.md +++ b/md/learn/flow-control/conditionals.md @@ -1,3 +1,57 @@ # Conditionals +- Only `Bool` are accepted. No truthy/falsy. +- Conditionals are expressions. +- Braces are required +- Paretheses for the condition are not required. +- There's no ternary operator + + +```thp +if condition +{ + // code +} +else if condition2 +{ + // more code +} +else +{ + // even more code +} + + +val result = if condition { value1 } else { value2 } +``` + + + +## Check for datatypes + +```thp +if variable is Datatype +{ + // code using variable +} +``` + + +## If variable is of enum + +```thp +val user_id = POST::get("user_id") + +if Some(user_id) = user_id +{ + print("user_id exists: {user_id}") +} + +if Some(user_id) = user_id && user_id > 0 +{ + print("user_id is greater than 0: {user_id}") +} +``` + + diff --git a/md/learn/flow-control/foreach.md b/md/learn/flow-control/foreach.md deleted file mode 100644 index e69de29..0000000 diff --git a/md/learn/flow-control/if-expresions.md b/md/learn/flow-control/if-expresions.md deleted file mode 100644 index e69de29..0000000 diff --git a/md/learn/flow-control/loops.md b/md/learn/flow-control/loops.md new file mode 100644 index 0000000..709cf07 --- /dev/null +++ b/md/learn/flow-control/loops.md @@ -0,0 +1,82 @@ +# Loops + +## For loop + +Braces are required. + +```thp +val numbers = Array(0, 1, 2, 3) + +for number in numbers +{ + print(number) +} + +for #(index, number) in numbers.entries() +{ + print("{index} => {number}") +} +``` + +```thp +val dict = Obj { + "apple": 10, + "banana": 7, + "cherries": 3, +} + +for #(key, value) in dict +{ + print("{key} => {value}") +} +``` + +```thp +for value in collection +{ + if condition + { + break + } +} +``` + + +## While loop + +```thp +val colors = Array("red", "green", "blue") +var index = 0 + +while index < colors.size() +{ + print("{colors.[index]}") + index += 1 +} +``` + + +## Infinite loop + +Basically Rust's loop. + +```thp +loop +{ + print("looping") + + if condition + { + break + } +} +``` + + + + + + + + + diff --git a/md/learn/flow-control/match.md b/md/learn/flow-control/match.md index e69de29..ed2dc14 100644 --- a/md/learn/flow-control/match.md +++ b/md/learn/flow-control/match.md @@ -0,0 +1,56 @@ +# Match + +## Most likely syntax + +```thp +val user_id = POST::get("user_id") + + +match user_id +| Some(id){ print("user_id exists: {id}") } +| None { print("user_id doesn't exist") } + +match user_id +| Some(id) +{ + print("user_id exists: {id}") +} +| None +{ + print("user_id doesn't exist") +} + + +match user_id +| Some(id) if id > 0 +{ + print("user_id exists: {id}") +} +| _ +{ + print("user_id has other values ") +} + + +``` + +## Alternative syntax? + +```thp +// Alternative syntax? + +match user_id { + Some(id) { print("user_id exists: {id}") } + None { print("user_id doesn't exist") } +} + +match user_id { + Some(id) { + print("user_id exists: {id}") + } + None { + print("user_id doesn't exist") + } +} +``` + diff --git a/md/learn/flow-control/while.md b/md/learn/flow-control/while.md deleted file mode 100644 index e69de29..0000000 diff --git a/md/learn/functions/declaration.md b/md/learn/functions/declaration.md new file mode 100644 index 0000000..fb55aa5 --- /dev/null +++ b/md/learn/functions/declaration.md @@ -0,0 +1,70 @@ +# Declaration + + +## No parameters, no return + +```thp +fun say_hello() +{ + print("Hello") +} + +say_hello() +``` + + +## With return type + +```thp +fun get_random_number() -> Int +{ + Random::get(0, 35_222) +} + +val number = get_random_number() +``` + +## With parameters and return type + +```thp +fun get_secure_random_number(Int min, Int max) -> Int +{ + Random::get_secure(min, max) +} + +val number = get_secure_random_number(0, 65535) +``` + + +## Generic types + +```thp +fun get_first_item[T](Array[T] array) -> T +{ + array.[0] +} + +val first = get_first_item[Int](numbers) +// The type annotation is optional if the compiler can infer the type + +val first = get_first_item(numbers) +``` + + +## Signature + + +```thp +() -> () +() -> Int +(Int, Int) -> Int +[T](Array[T]) -> T +``` + + + + + + + + diff --git a/md/learn/functions/higher-order.md b/md/learn/functions/higher-order.md new file mode 100644 index 0000000..d28394b --- /dev/null +++ b/md/learn/functions/higher-order.md @@ -0,0 +1,28 @@ +# Higher Order functions + + +## Function as parameter + +```thp +fun map[A, B](Array[A] input, (A) -> B function) -> Array[B] +{ + // implementation +} + +``` + +## Function as return + +```thp +fun generate_generator() -> () -> Int +{ + // code... +} + + +val generator = generate_generator() // A function +val value = generate_generator()() // An Int +``` + + + diff --git a/md/learn/functions/lambdas.md b/md/learn/functions/lambdas.md new file mode 100644 index 0000000..02e1bb8 --- /dev/null +++ b/md/learn/functions/lambdas.md @@ -0,0 +1,70 @@ +# Lambdas / Anonymous functions + + +## Anonymous function + +```thp +fun(Int x, Int y) -> Int { + x + y +} + + +numbers.map(fun(x) { + x * 2 +}) +``` + + + +## Closure types + +By default closures **always** capture variables as **references**. + + +```thp +var x = 20 + +val f = fun() { + print(x) +} + +f() // 20 + +x = 30 +f() // 30 +``` + + +You can force a closure to capture variables by value. + +```thp +fun(parameters) clone(variables) { + // code +} +``` + +```thp +var x = 20 + +val f = fun() clone(x) { + print(x) +} + +f() // 20 + +x = 30 +f() // 20 +``` + + +## Lambdas + + +```thp +numbers.map { + it * 2 +} +``` + + + diff --git a/md/learn/functions/parameters.md b/md/learn/functions/parameters.md index 5b2e2fc..62e0e31 100644 --- a/md/learn/functions/parameters.md +++ b/md/learn/functions/parameters.md @@ -24,21 +24,21 @@ fun count(Array[Int] numbers) -> Int { ## Mutable reference ```thp -fun add_25(&Array[Int] numbers) { +fun push_25(&Array[Int] numbers) { numbers.push(25) // Ok, will also mutate the original array } ``` Placing a `&` before the type makes the parameter a mutable reference. Mutable methods can be used, and the original -data **will** be mutated. +data **can** be mutated. -The callee *must* also use `&`. +The caller *must* also use `&`. ```thp -val numbers = Array(1, 2, 3, 4) +val numbers = Array(0, 1, 2, 3) -add_25(&numbers) // Pass `numbers` as reference. +push_25(&numbers) // Pass `numbers` as reference. print(numbers(4)) // `Some(25)` ``` @@ -54,13 +54,13 @@ fun add_25(clone Array[Int] numbers) { ``` Using the `clone` keyword before the type creates a mutable copy -of the parameter. The original data will **not** be mutated. +of the parameter (CoW). The original data will **not** be mutated. ```thp val numbers = Array(1, 2, 3, 4) -add_25(&numbers) // Pass `numbers` as reference. +add_25(numbers) // Pass `numbers` as clone. print(numbers(4)) // None ``` diff --git a/md/learn/index.md b/md/learn/index.md index 88c5f7c..a22181e 100644 --- a/md/learn/index.md +++ b/md/learn/index.md @@ -1,3 +1,6 @@ +![Accurate visual description of THP](/img/desc_thp.jpg) + + # Welcome Welcome to the documentation of the THP programming languague. @@ -7,7 +10,7 @@ THP is a new programming language that compiles to PHP.
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 install THP go to the [installation guide](/installation-guide) If you want to learn the language, go to the learn section. diff --git a/md/learn/index.yaml b/md/learn/index.yaml index b4aab1d..a84823a 100644 --- a/md/learn/index.yaml +++ b/md/learn/index.yaml @@ -11,14 +11,10 @@ children: children: - path: hello-world name: Hello, world! - - path: datatypes - name: Datatypes - - path: the-compiler - name: The compiler - name: Variables path: variables - - path: io - name: Input & Output + - path: datatypes + name: Datatypes - path: comments name: Comments - name: Flow control @@ -26,3 +22,41 @@ children: children: - name: Conditionals path: conditionals + - name: Loops + path: loops + - name: Match + path: match +- name: Collections + path: collections + children: + - name: Tuples + path: tuples + - name: Arrays + path: arrays + - name: Maps + path: maps + - name: Sets + path: sets +- name: Functions + path: functions + children: + - name: Declaration + path: declaration + - name: Parameter references + path: parameters + - name: Higher-order functions + path: higher-order + - name: Lambdas + path: lambdas +- name: ADTs + path: adts + children: + - name: Union types + path: union-types +- name: Classes + path: classes + children: + - name: Definition + path: definition + - name: Static + path: static diff --git a/static/img/desc_thp.jpg b/static/img/desc_thp.jpg new file mode 100644 index 0000000..b0c3a5b Binary files /dev/null and b/static/img/desc_thp.jpg differ diff --git a/static/index.html b/static/index.html index 36ecb46..9060513 100644 --- a/static/index.html +++ b/static/index.html @@ -16,12 +16,23 @@ +
-

+

Typed
Hypertext @@ -33,32 +44,34 @@

-
+ + +
-
use Globals::POST
-use JSON
-
-val person_id = POST::get("person_id") ?: die
-
-match Person::find_by_id(person_id) {
-    Ok(person) => {
-        JSON::encode(person)
-    }
-    Err(e) => {
-        JSON::encode(Obj {"error": e})
-    }
-}
-
- +
+                    
+                        val person_id = POST::get("person_id") ?: die
+                        
+                        match Person::find_by_id(person_id)
+                        | Ok(person)
+                        {
+                            JSON::encode(person)
+                        }
+                        | Err(e)
+                        {
+                            JSON::encode(Obj {"error": e})
+                        }                        
+                    
+                
-
+ + + \ No newline at end of file diff --git a/static/js/prism.min.js b/static/js/prism.min.js new file mode 100644 index 0000000..0e561df --- /dev/null +++ b/static/js/prism.min.js @@ -0,0 +1,4 @@ +/* PrismJS 1.29.0 +https://prismjs.com/download.html#themes=prism&plugins=normalize-whitespace */ +var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(e){var n=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,r={},a={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function e(n){return n instanceof i?new i(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&").replace(/=g.reach);A+=w.value.length,w=w.next){var E=w.value;if(n.length>e.length)return;if(!(E instanceof i)){var P,L=1;if(y){if(!(P=l(b,A,e,m))||P.index>=e.length)break;var S=P.index,O=P.index+P[0].length,j=A;for(j+=w.value.length;S>=j;)j+=(w=w.next).value.length;if(A=j-=w.value.length,w.value instanceof i)continue;for(var C=w;C!==n.tail&&(jg.reach&&(g.reach=W);var z=w.prev;if(_&&(z=u(n,z,_),A+=_.length),c(n,z,L),w=u(n,z,new i(f,p?a.tokenize(N,p):N,k,N)),M&&u(n,w,M),L>1){var I={cause:f+","+d,reach:W};o(e,n,t,w.prev,A,I),g&&I.reach>g.reach&&(g.reach=I.reach)}}}}}}function s(){var e={value:null,prev:null,next:null},n={value:null,prev:e,next:null};e.next=n,this.head=e,this.tail=n,this.length=0}function u(e,n,t){var r=n.next,a={value:t,prev:n,next:r};return n.next=a,r.prev=a,e.length++,a}function c(e,n,t){for(var r=n.next,a=0;a"+i.content+""},!e.document)return e.addEventListener?(a.disableWorkerMessageHandler||e.addEventListener("message",(function(n){var t=JSON.parse(n.data),r=t.language,i=t.code,l=t.immediateClose;e.postMessage(a.highlight(i,a.languages[r],r)),l&&e.close()}),!1),a):a;var g=a.util.currentScript();function f(){a.manual||a.highlightAll()}if(g&&(a.filename=g.src,g.hasAttribute("data-manual")&&(a.manual=!0)),!a.manual){var h=document.readyState;"loading"===h||"interactive"===h&&g&&g.defer?document.addEventListener("DOMContentLoaded",f):window.requestAnimationFrame?window.requestAnimationFrame(f):window.setTimeout(f,16)}return a}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism); +!function(){if("undefined"!=typeof Prism){var e=Object.assign||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e},t={"remove-trailing":"boolean","remove-indent":"boolean","left-trim":"boolean","right-trim":"boolean","break-lines":"number",indent:"number","remove-initial-line-feed":"boolean","tabs-to-spaces":"number","spaces-to-tabs":"number"};n.prototype={setDefaults:function(t){this.defaults=e(this.defaults,t)},normalize:function(t,n){for(var r in n=e(this.defaults,n)){var i=r.replace(/-(\w)/g,(function(e,t){return t.toUpperCase()}));"normalize"!==r&&"setDefaults"!==i&&n[r]&&this[i]&&(t=this[i].call(this,t,n[r]))}return t},leftTrim:function(e){return e.replace(/^\s+/,"")},rightTrim:function(e){return e.replace(/\s+$/,"")},tabsToSpaces:function(e,t){return t=0|t||4,e.replace(/\t/g,new Array(++t).join(" "))},spacesToTabs:function(e,t){return t=0|t||4,e.replace(RegExp(" {"+t+"}","g"),"\t")},removeTrailing:function(e){return e.replace(/\s*?$/gm,"")},removeInitialLineFeed:function(e){return e.replace(/^(?:\r?\n|\r)/,"")},removeIndent:function(e){var t=e.match(/^[^\S\n\r]*(?=\S)/gm);return t&&t[0].length?(t.sort((function(e,t){return e.length-t.length})),t[0].length?e.replace(RegExp("^"+t[0],"gm"),""):e):e},indent:function(e,t){return e.replace(/^[^\S\n\r]*(?=\S)/gm,new Array(++t).join("\t")+"$&")},breakLines:function(e,t){t=!0===t?80:0|t||80;for(var n=e.split("\n"),i=0;it&&(o[l]="\n"+o[l],a=s)}n[i]=o.join("")}return n.join("\n")}},"undefined"!=typeof module&&module.exports&&(module.exports=n),Prism.plugins.NormalizeWhitespace=new n({"remove-trailing":!0,"remove-indent":!0,"left-trim":!0,"right-trim":!0}),Prism.hooks.add("before-sanity-check",(function(e){var n=Prism.plugins.NormalizeWhitespace;if((!e.settings||!1!==e.settings["whitespace-normalization"])&&Prism.util.isActive(e.element,"whitespace-normalization",!0))if(e.element&&e.element.parentNode||!e.code){var r=e.element.parentNode;if(e.code&&r&&"pre"===r.nodeName.toLowerCase()){for(var i in null==e.settings&&(e.settings={}),t)if(Object.hasOwnProperty.call(t,i)){var o=t[i];if(r.hasAttribute("data-"+i))try{var a=JSON.parse(r.getAttribute("data-"+i)||"true");typeof a===o&&(e.settings[i]=a)}catch(e){}}for(var l=r.childNodes,s="",c="",u=!1,m=0;m]=?|[!=]=?=?|--?|\$|\+\+?|&&?|\|\|?|[?*/~^%]/, + "punctuation": /[{}[\];(),.]/, + "boolean": /\b(?:false|true)\b/, + "class-name": /\b[A-Z][a-zA-Z_0-9]+\b/, + "variable": /\b[a-z_0-9][a-zA-Z_0-9]+:/, +}; \ No newline at end of file