A list is a series of items inside parentheses. You have been working with lists all throughout this book. (+ 3 5) is a list. Its first element is a function, and the remaining elements are numbers. Again, up until now, every list you have seen has either a function name or a special form as its first element.

But what if you want to create that list of prices from the preceding page? You can’t do this; try it and find out:

ClojureScript does not let you do this because 3.95 isn’t a function that you can call (hence the error message). So, how do you get a list that doesn’t have a function as its first element?

In the case where you have a list of simple values, there is no difference between the methods. However, if you have sub-expressions or symbols, there is a difference, as you can see in this code:

The first list, list1, evaluates all of its elements. The second list, list2, takes them literally as given, without evaluation. At this stage, you will probably want the first method. The second method is useful when you are writing macros, which, as of this writing, is beyond the scope of this book.

Fundamental Operations

The following functions, which work on all collections, not just lists, are the very basics:

  • first returns the first items in the collection
  • rest returns a sequence of all the items except the first one
  • last returns the last item in the collection
  • butlast returns a sequence of all the items except the last one
  • count gives you the number of items in the collection
  • list? returns true if its argument is a list, false otherwise
  • conj takes a collection and an item, and returns a new collection with the item added to it.

In the case of lists, conj adds the new element at the beginning of the list. Try these expressions in the following active code box, or use a series of println to do them all at once; for your convenience, the price-list list has been defined.

(first price-list)
(rest price-list)
(count price-list)
(list? price-list)
(conj price-list 7.86)

As noted previously, lists are designed to be accessed from beginning to end. It is, however, possible to access the nth element of a list by using the appropriately named nth function, which takes a list as its first argument and an index number as its second argument, where zero is the index of the first item in the list. What happens if you give a negative number or a number greater than or equal to the number of items in the list? Try different index numbers and find out:

One important aspect of all ClojureScript collections is that they are persistent. All the functions that ClojureScript provides to manipulate collections return a new version of the collection.

Again, a concrete example: the conj function returns a new collection with the desired item added to it. (The name conj stands for “conjoin.”) When used with a list, conj adds a new element at the beginning of the list that it returns:

The first println adds 7.86 to the list and prints it, but the original list is untouched, as shown by the second println.

Next Section - Vectors