 Something we may want to do very often in code is deal with large sets of data. For instance, we might want a set of all the names of the presidents of the United States in sequential order. Notice though that there's something very inconvenient and impractical if I have to assign each individual value in this set to its own variable. For starters, it's silly that I have to contrive a unique variable name for each member of the set. But what's much worse is what happens when I want to use every member. I have to use each member individually leading to lots of code repetition. For example, to print each name I would have to write a print statement for each variable. This is bad enough when I'm dealing with sets of a few dozen things. Imagine how bad it would be when dealing with sets of thousands or millions or more. Another problem with using individual variables for each piece of data is that we often want to deal with sets where the number of items may vary or may even grow and shrink during the course of the program. For instance, if we create a program that keeps track of student attendance we want the code to work no matter how many or few students any class has. But if we use a variable to hold each student name our only solution is to create an arbitrary number of variables and hope that no class ever has more than that number of students. So rather than use individual variables for items in a set we usually want to use a kind of value called a collection. A collection is a value which itself is made up of multiple other values. It's a value which represents some set of things. The most basic kind of collection is a list. A list is a collection in which the items are ordered in sequence such that the items are known by their relative order. So if you have say five things in a list one of those things is the first thing, another is the second, another is the third, another is the fourth, and one is the fifth, the last thing in the list. To create a list in Pigeon we use the list operator whose operands make up the initial members of the list. So here the top expression returns a new list with three items first the number 77, second string yo, and third the number negative 6. The bottom expression returns a new list with no initial items in other words an empty list. To access the items of a list we use the get operator which takes two operands first a list and second the index of the item to retrieve from that list. Here we create a list of three items and assign the list to a variable will. The expression get will zero then returns the first item in the list get will one returns a second and get will two returns the third. I'm sure it strikes you as odd that the items are indexed starting at zero instead of one but this is the dominant convention in programming for reasons that will become evident in later units. The lend operator short for length returns the number of items in a list. Here we have two lists one with three items and assign to the variable josh the other with one item and assign to the variable lisa. So the expression lend josh returns three and the expression lend lisa returns one. Using lend we can write a function print all which takes a list of any length and prints every item in the list. To start we assign zero to a counter variable we'll call i as is the convention and then we'll create a while loop that executes as long as i is less than the length of the list. In the loop we'll retrieve the item of the list at index i and print it then we'll increment i by one. So if our list has four items the loop will go through four iterations with i having the value zero then one then two then three and in the last iteration i will be incremented to four which is not less than the length of the list so the loop will end. In programming we often make a distinction between data which is mutable and immutable. Mutable data is data which we allow to change whereas immutable data is data which we do not allow to change. So far we've introduced six different data types in Pigeon numbers, strings, booleans, the value null, functions and now lists. Values of these types are all immutable except lists which are mutable. What this means is that we have operations for modifying lists whereas we don't have any operations for modifying the other types. You might think that the arithmetic operators like add and sub modify their operands but actually what they do is produce new number values leaving their operands unchanged. In the operation add three five the operands three and five remain unchanged. Instead the operation returns a new number value eight. So with the immutable data types we have operations which produce new values based on existing values but the operations don't actually modify those operand values. In contrast we have two operations in Pigeon which modify an existing list. The first of these operators is set. Set replaces an item in a list at a specified index with a specified value. Here the list assigned to Kim starts off with three values, 77, 0 and 6. So when we first print the value returned by get Kim 1 the second item in the list, 0 is printed. But if we then invoke set on the list Kim specifying index 1 and a new value negative 53 then we're modifying the list changing its second item to be the value negative 53 instead of the string yo. So when we again print the value returned by get Kim 1 the value negative 53 is printed. The other operator that mutates lists is append. Append adds additional items to the end of the list increasing its length. Starting with an empty list assigned to the variable hue invoking len hue will first return 0 but if I then append two items to hue invoking len hue will return 2 and if I then append two more items to hue invoking len hue will return 4.