Web Development With HHVM and Hack 9: Tuples
In this tutorial, we will cover tuples. In the last tutorial, we covered loops https://medium.com/@mikeabelar/web-development-with-hhvm-and-hack-8-loops-dbe86a85df4
What are Tuples?
Tuples are a way to bundle multiple variables or expressions into one expression. Suppose we wanted to store a list of users. For each user, we want to store the name and the age of the user. One way to do this is with tuples. We can have a tuple that stores the name (represented as a string) and the age (represented as an integer).
Tuple Example
To address the problem above, create a folder for this tutorial and inside create the hhconfig file:
touch .hhconfig
then
touch tuples.hack
Inside tuples.hack
, paste the following content:
<<__EntryPoint>>
function main(): noreturn {
$user_one = tuple("Joe", 25);
$user_two = tuple("Jack", 21);
print($user_one[0] . "\n");
print($user_one[1] . "\n");
print($user_two[0] . "\n");
print($user_two[1] . "\n");
exit(0);
}
Let us first type check our program with hh_client tuples.hack
and then run our code with hhvm tuples.hack
, which produces the following output:
Joe
25
Jack
21
Looking at the code, our first tuple is stored in the variable user_one
. To create a tuple, we use the tuple
keyword. Then, in parentheses, we separate the values for our tuple using commas. In this case, each tuple has a string for the name followed by an int for the age. Note: tuples can have any combination of types and numbers of elements.
For example, the following tuples are valid:
tuple(1.353)
tuple(1,"mike", 2.242)
After declaring the tuples and storing them, the code then prints out the elements of the tuples. To access the various values in tuples, one can use the index access notation as we used with vectors. To reiterate, the first element of a tuple can be accessed with [0], and the last can be accessed with [n-1] where n is the number of elements in the tuple.
Note: To change the value of an element in the tuple, you can just assign the element as follows:
$user_one[0] = "Mike";
Now, print($user_one[0] . "\n");
will print “Mike”.
Using Tuples In Functions
Say we have a list of tuples of users (using string and name for our tuple), and we want to get the whole tuple given only the name component. Here is an implementation of how to do that:
function get_tuple_of_user(string $name) : (string, int) {
$user_one = tuple("Joe", 25);
$user_two = tuple("Jack", 21);
$users = vec[$user_one, $user_two];
foreach ($users as $user) {
if ($user[0] == $name) {
return $user;
}
}
return tuple("Not found", -1);
}<<__EntryPoint>>
function main(): noreturn {
$t = get_tuple_of_user("Joe");
print($t[1]);
exit(0);
}
the get_tuple_of_user
function takes in a string and looks through each tuple in the users
vector and looks for the tuple that has the corresponding name. This is done with a foreach
loop. If no match is found, a default tuple is returned. However, look at the return type of the function:
(string, int)
This is saying that we are looking to return an expression whose first element is type string and whose second element is type int. Notice that we do not use the tuple keyword for the return type. This is because the return type is type (string, int)
and when we say tuple("Not found", -1)
for example, we are returning an expression whose first element is type string and whose second element is type int.
Declaring Types
Say we want to use the (string, int)
type frequently. It would be great if we could create an alias for (string, int)
so that we can use the alias rather than typing out (string, int)
every time. To do so, we will declare a new type. Let’s see the same code as above but with a new type defined:
newtype User = (string, int);function get_tuple_of_user(string $name) : User {
$user_one = tuple("Joe", 25);
$user_two = tuple("Jack", 21);
$users = vec[$user_one, $user_two];
foreach ($users as $user) {
if ($user[0] == $name) {
return $user;
}
}
return tuple("Not found", -1);
}<<__EntryPoint>>
function main(): noreturn {
$t = get_tuple_of_user("Joe");
print($t[1]);
exit(0);
}
Notice the new first line:
newtype User = (string, int);
we use the newtype
keyword to create a new type. We then follow that with the name of our new type. In this case, User
. Then we set it equal to the type of the tuple which we want. Then, for every instance of (string, int)
, we can instead use User
as shown in the get_tuple_of_user
function.
In the next tutorial, we cover Shapes: https://medium.com/@mikeabelar/web-development-with-hhvm-and-hack-10-shapes-d8a56b067c2b