 To truly understand how variables work in Pigeon, you have to understand that variables in Pigeon are reference variables, meaning that they actually hold addresses, not actual values. When we create a new value in Pigeon, the language finds a space to store that value, but when we assign that value to a variable, the data assigned to the variable is not the value itself, but rather the address of memory where the value is stored. So consider this piece of code involving only immutable pieces of data, some numbers. The top line stores the number value 3 somewhere in memory, designates another place in memory for the variable Z, and writes at this location the address of that value 3. The second line then simply stores another number value 5, and changes which address is written in the variable Z. Instead of referencing the location of the value 3, Z now references the location of the value 5. In the third line, the sub-operation stores a new number value 4 somewhere in memory, designates another place in memory for the variable Mali, and writes at this location the address of the value 4. So when we assign to a variable, it is really an address that is changed in memory, not any value. But now, look what happens when we deal with mutable values. Here we create an empty list which we assign to the variable Leo, and we assign the value of Leo to Bruce. What we have in memory then is a list stored somewhere in memory and two variables, Leo and Bruce, both holding the same address of that list. Both variables reference the same list. Consequently, when we modify the list via one variable, the changes are visible when we access the list through the other. Here when Leo first returns 0, but if we append an item to Bruce, when Leo then returns 1. Because parameters are variables, and because variables are really those references, we say that arguments to functions in Pigeon are passed by reference. This simply means that it is the addresses of the argument values which are written in the parameter variables, not the values themselves. Again, when dealing with immutable data, this distinction is not significant, because you can't change immutable things anyway. However, you do have to be cognizant when passing mutable values as arguments, because the function then might modify those values. Here for instance, we create a list which we assign to Chris, and we pass this list as argument to the function Ian. The function Ian modifies its parameter within a PEND operation, so this change is reflected in Chris. Before the call to Ian, Chris had the length 2, but afterwards it has the length 3. So as just discussed, variables really store addresses, not values directly. Well, the same is true of lists. The items of a list are stored in the list as their addresses, not as values directly. The significance of this is that a list can be an item of another list, and in fact a list can be an item in itself. Here for example, we create two lists. The first is assigned to Joe, and then this variable is specified as the first item in the second list. So the first item in the second list is actually our first list. To make a list an item of itself, we use set, such as here, where the list Eve is set as the new third item of itself. Just to be clear what's going on in memory. The date of a list consists of a sequence of addresses, and now the third address in the sequence is the address of the list itself. Another important distinction in programming is between the concepts of equality and identity. When we say that two values are equal, we mean that they have the same type and the same content. So say, if you have two strings stored separately in memory, if both of those strings represent the same sequence of characters, then they are equal to each other. In contrast, when we say that two values are identical, we mean that they are not just equal, they are actually the very same values stored in memory. In other words, they are not separate values at all, but really just one value. So any value in memory is of course equal to itself, but it is also identical to itself. Because multiple variables can reference the same value, it can be useful to have a test for whether two operands are identical. In Pigeon, this is called the ID operator. Here we create two lists with the same values, assigning one list to ed and the other to tom. Because they are both lists with the same content, they are equal, but because they are two separate lists in memory, they are not identical.