Array

A THP array is an abstraction on top of PHP arrays.

THP Arrays contain an ordered list of values of a unique datatype, that is to say, you cannot store values of different datatypes inside an Array.

If you need to store values of different types, see Tuples.

THP arrays are 0-indexed.

Signature

type Array[T] = Map[Int, T]thp
    
Syntax error: Unexpected token `Array`, expected a new line at line 1:5

Where T is the datatype that the Array stores. For example:

Array[Int]              // An array of integers
Array[Float]            // An array of floats
Array[Array[String]]    // A 2-dimensional array of stringsthp
    
Syntax error: There should be an identifier after a binding at line 1:5

PHP array internals

Warning

TL;DR: Never assign to an array using an invalid index. If you do the program will not crash, instead it will not behaved as expected (this is a common problem in PHP). THP tries its best to solve such behavior.

Since THP compiles down to PHP, it’s important to understand how PHP represents arrays internally. PHP doesn’t have arrays. Instead, PHP has ordered maps and syntax sugar to make them look like arrays.

When declaring an array like:

var arr = ["a", "b", "c"]thp
    

in reality what goes into memory is a map with numbers as keys:

array(
    0 => "a",
    1 => "b",
    2 => "c",
);

As long as this map contains valid keys, it can be treated as an array. We can loop over it, read and write.

However, once we assign to an invalid index, it cannot be treated as an array anymore.

Invalid indexes are:

Problems with iterations

PHP maps preserve insertion order. This means that when iterating over a PHP map, values are processed in FIFO.

var numbers = ["a", "b", "c"]
numbers[-10] = "?"    // Assign to a negative index

// Now the array will be (using thp notation):
// .{
//     0: "a",
//     1: "b",
//     2: "c",
//   -10: "?",
// }

numbers[7] = "!"    // Out of bounds assignment

// Now the array will be:
// .{
//     0: "a",
//     1: "b",
//     2: "c",
//   -10: "?",
//     7: "!",
// }

// In this loop, values will be printed following when
// they were inserted, not by order of the index.
for #(_, value) in numbers
{
    print("{value} ")   // Will print: a b c ? !
}

numbers[-4] = "???"
// .{
//     0: "a",
//     1: "b",
//     2: "c",
//   -10: "?",
//     7: "!",
//    -4: "???",
// }

// When pushing, the value will be assigned to the highest key + 1
numbers.push("/")   // This will be at position 8

// .{
//     0: "a",
//     1: "b",
//     2: "c",
//   -10: "?",
//     7: "!",
//    -4: "???",
//     8: "/",
// }thp
    
Syntax error: Unexpected token `[`, expected a new line at line 2:8

This is one of many fundamental flaws with PHP. The only way to solve it would be to check every insertion at runtime, and this would have a performance penalty.

From now on, the documentation will continue to work with the Array abstraction, as if all indexes were valid.

Usage

Empty array

To create an empty array use square brackets. If you create an empty array, you need to specify the datatype.

Array[Int] empty = []thp
    
Syntax error: There should be an identifier after a binding at line 1:5

Creation

To create an array use square brackets notation:

val numbers = [0, 1, 2, 3, 4, 5]thp
    

When the array is not empty, you don’t need to specify a datatype.

When the Array is declared over many lines, the last item should have a trailing comma:

val colors = [
    "red",
    "blue",
    "green",  // trailing comma
]thp
    

If it doesn’t, the code formatter will automatically insert one for you.

Assignment to elements

Use square brackets notation to insert into an array or modify it:

To modify an array it must be mutable, that is, assigned to a var instead of a val.

// This array cannot be modified, as it's declared with `val`
val immutable = [1, 2, 3]
// This is a compile time error
immutable[0] = 322

// This array can be modified, as it's declared with `var`
var mutable = [1, 2, 3]
// Ok
mutable[0] = 322thp
    
Syntax error: Unexpected token `[`, expected a new line at line 4:10

To append an element to an array, use the method push():

mutable.push(4)thp
    
Syntax error: Unexpected token `.`, expected a new line at line 1:7

Do not insert into an invalid index. See PHP array internals to learn why.

Iteration

Use a for loop to iterate over the elements of an array:

val colors = ["red", "green", "blue"]

for c in colors
{
    print("{c} ")
}thp
    
red green blue

A for loop automatically declares new immutable variables. It is a compile error to attempt to modify those, as in the following snippet:

val colors = ["red", "green", "blue"]

for c in colors
{
    c = "orange"    // Compile error: Can't assign to an immutable variable
    print("{c} ")
}thp
    
Syntax error: Expected a closing brace after the block body. at line 5:7

You can also declare an index along with the value:

val colors = ["red", "green", "blue"]

for index, color in colors
{
    println("item {index}: {c}")
}thp
    
item 0: red
item 1: green
item 2: blue

Access

To access a value of the array use square brackets notation:

print(colors[0])thp
    
Syntax error: Expected an statement or an expresion at the top level. at line 1:0

Since the index might not exist, this will return a nullable type that you have to handle.

Destructuring

THP arrays don’t have destructuring, since the values can all be null. If you know that the number of elements is fixed and valid, use Tuples instead.

Operators

While PHP allows using certain operators with arrays, THP disallows that. Methods that perform comparisons should be used instead.

Assignment

// TODO: Detail that assignment of arrays is copy on write

Methods

In the parameters, self is the array to operate on.

MethodDescription
fun concat[T]( self, Array[T]... arrays, ) -> Array[T]

Concatenate with other arrays, and return the result as a new array.

fun filter[T]( self, (T) -> (Bool) callback, ) -> Array[T]

Filters elements using a callback function, and returns them in a new array.

fun push[T](self, T... elements) -> Int

Appends one or more elements to the end of the array. Returns the new length of the array.

fun pop[T](self) -> T

Removes the last value of the array, and returns it.