An Introduction to Lists and their operations

Lists are a kind of Object that can hold multiple values; these values are called the elements of the list, and can be any other objects. Lists let us access individual elements using the method at(_), and iterate over their contents using the method do(_), or using for(_)do(_).

In the standard dialect, a list is created like this:

def animals = list ["dog", "cat", "whale", "bird", "mouse"]
def sizes = list [52, 78, 45, 23]

and in dialect beginningStudent, which does not use square brackets, like this:

dialect "beginningStudent"
def animals = list("dog", "cat", "whale", "bird", "mouse")
def sizes = list(52, 78, 45, 23)

The first declaration creates a list with five string elements, and binds it to the name animals; the second declaration creates a list containing four numbers, and binds it to the name sizes. It doesn’t matter how many elements you put into the list; a list can contain arbitrarily many things. Moreover, the “things” can be any kind of object. We have used numbers and strings, but the elements can be anything — even other lists.

In standard you can also write

def animals = list.withAll ["dog", "cat", "whale", "bird", "mouse"]
def sizes = list.withAll [52, 78, 45, 23]

Also note that you can put no elements in a list, creating an empty list.

def empty = list.empty

This works in both beginningStudent and in standard. You can of course also write:

def empty = list.withAll [ ]

Lists are Mutable

One of the most confusing things about list to beginners is that they are mutable. What does that mean? Lets’ explain.

Simple objects like Numbers, Strings, Points, and Booleans are immutable: they don’t change. The number 3 is always 3; it never becomes 4! If the variable x is bound to 3, when you write an expression like x + 1, you are not changing 3: you are creating a new number 4, leaving 3 unchanged. The same is true of Strings: the expression "Hello " ++ "World!" does not change the string "Hello " or the string "World!"; it creates a third string.

In contrast, lists are mutable: they can be changed. Try running this program; then we will discuss what it does.

There is just one list here; a and b both name this list. It’s initially empty. The method requests addLast and addFirst mutate, i.e., change, this list. The request a.addLast 17 adds the new element 17 at the end; the request a.addFirst adds 3 at the beginning. The print statements show how the value of the list changes; the square brackets in the output are the way that lists depict themselves as strings.

Notice that it makes no difference whether we access this list through the variable a or the variable b. There is just one list, so we see the same object both ways.

Now try using removeFirst to change the list a again.

Operations on Lists

There are three broad categories of methods that operate on lists.

  • Observers: methods that let us examine, or observe, the contents of the list. Examples are methods such as first and at(_), which return a particular element of the list, isEmpty which checks if a list is empty, and asString, which returns a string representation of the list and its contents.
  • Constructors: methods that make new lists. Examples are copy, sorted, and ++(_)
  • Mutators: methods that change the list. Examples include at(_)put(_), sort, and addLast(_).

There is a separate tutorial page for each of these categories: Observers, Constructors, and Mutators.

The full set of requests is the part of the specification of standard.

Lists as Collections

Lists are a particular kind of collection; a collection is just an object that can store and provide access to other objects. Other collections include sets, sequences, ranges and strings.

Like all collections, if you need to do some operation to every element of the collection, you can use a for loop or the do method.

In addition to do, there are several other useful methods on collections. This tutorial discusses  fold(_)startingWith(_) and map(_). The full list is in the specification of standard.