You've already seen atomic values when we initialized variables in the previous lesson. An atomic value is a single value. So, for example, we can assign the variable "x" the single value of 8 in the following statement:

        (let* ( (x 8) ) x)
      

(We added the expression x at the end to print out the value assigned to x-- normally you won't need to do this. Notice how let* operates just like a function: The value of the last statement is the value returned.)

A variable may also refer to a list of values, rather than a single value. To assign the variable x the list of values 1, 3, 5, we'd type:

        (let* ( (x '(1 3 5))) x)
      

Try typing both statements into the Script-Fu Console and notice how it replies. When you type the first statement in, it simply replies with the result:

        8
      

However, when you type in the other statement, it replies with the following result:

        (1 3 5)
      

When it replies with the value 8 it is informing you that x contains the atomic value 8. However, when it replies with (1 3 5), it is then informing you that x contains not a single value, but a list of values. Notice that there are no commas in our declaration or assignment of the list, nor in the printed result.

The syntax to define a list is:

         '(a b c)
      

where a, b, and c are literals. We use the apostrophe (') to indicate that what follows in the parentheses is a list of literal values, rather than a function or expression.

An empty list can be defined as such:

        '()
      

or simply:

        ()
      

Lists can contain atomic values, as well as other lists:

        (let*
           (
                (x 
                   '("The Gimp" (1 2 3) ("is" ("great" () ) ) )
                )
            )       
                
            x
         )
      

Notice that after the first apostrophe, you no longer need to use an apostrophe when defining the inner lists. Go ahead and copy the statement into the Script-Fu Console and see what it returns.

You should notice that the result returned is not a list of single, atomic values; rather, it is a list of a literal ("The Gimp"), the list (1 2 3), etc.

        (cons 1 '(2 3 4) )
      

The result is the list (1 2 3 4).

You could also create a list with one element:

        (cons 1 () )
      

You can use previously declared variables in place of any literals, as you would expect.

        (list 5 4 3 a b c)
      

This will compose and return a list containing the values held by the variables a, b and c. For example:

        (let*  (
                  (a 1)
                  (b 2)
                  (c 3)
               )
               (list 5 4 3 a b c)
        )
      

This code creates the list (5 4 3 1 2 3).

        (car '("first" 2 "third"))
      

which is:

        "first"
      
        (cdr '("first" 2 "third"))
      

returns:

        (2 "third")
      

whereas the following:

        (cdr '("one and only"))
      

returns:

        ()
      

The basic naming convention is easy: The a's and d's represent the heads and tails of lists, so

        (car (cdr (car x) ) )
      

could be written as:

        (cadar x)
      

To view a full list of the list functions, refer to the Appendix, which lists the available functions for the version of Scheme used by Script-Fu.

To get some practice with list-accessing functions, try typing in the following (except all on one line if you're using the console); use different variations of car and cdr to access the different elements of the list:

        (let* (
                 (x  '( (1 2 (3 4 5) 6)  7  8  (9 10) )
                 )
              )
              ; place your car/cdr code here
        )
      

Try accessing the number 3 in the list using only two function calls. If you can do that, you're on your way to becoming a Script-Fu Master!

[Note] Note
In Scheme, a semicolon (";") marks a comment. It, and anything that follows it on the same line, are ignored by the script interpreter, so you can use this to add comments to jog your memory when you look at the script later.