Variables Top ConditionalsAssignment Contents


Once a variable has been created, it is possible to change its value, or binding, Consider the following interaction with the Scam interpreter:

    (define eyeColor 'black)    ; creation
    (inspect eyeColor)          ; reference
    -> eyeColor is black
    (set! eyeColor 'green)      ; assignment
    (eq? eyeColor 'black)       ; equality
    -> #f
    (eq? eyeColor 'green)       ; equality
    -> #t

    (assign eyeColor BROWN)     ; assignment (alternate)

The assignment function is not like the arithmetic operators. Recall that + evaluates all its arguments before performing the addition. For set! and assign, the leftmost operand is not evaluated: If it were, the assignment

    (define x 1)
    (set! x 3)

would be equivalent to:

    (set! 1 3)

In general, an operator which does not evaluate all its arguments is known as a special form2. For assign, the evaluation of the first argument is suppressed.

Other functions for changing the value of a variable

Scam has another functions for changing the value of a varible:

    (set 'x 5)

which changes the current value of x to 5. It is equivalent to the set! function, except that it evaluates all its arguments. This is why the variable name was quoted in the example. The reason for this behavior is that, sometimes, it is useful to derive the variable name to be modified programmatically. The set function allows for this while the set! function does not.

Assignment and Environments/Objects

The assignment functions can take an environment as an optional third argument. Because the predefined variable this always points to the current environment, the following three expressions are equivalent:

        (assign x 5)
        (set! x 5 this)
        (set (symbol "x") 5 this)

The symbol function is used to create a variable name from a string. Since environments form the basis for objects in Scam, set! and set can be used to update the instance variables of objects.

Setting elements of a collection

The set-car! function can be used to set the first element of a collection:

    (define a (list 3 5 7))

    (inspect a)
    -> a is (3 5 7)

    (set-car! a 11)

    (inspect a)
    -> a is (11 5 7)

More generally, the setElement function can be used to set a new value at any legal index. The first argument to setElement is the collection to be modified, the second is in index at which to place the new value, the third argument. Indices are numbered using zero-based counting:

    (define a (list 3 5 7))
    (setElement a 1 44)         ;index 1 refers to the 2nd element
    (inspect a)
    -> a is (3 44 7)

For strings, the new value must be a non-empty string. If the value is composed of multiple characters, the characters after the first character are ignored.

For lists, it is possible to set the tail of a list. The tail of a list is the list of all elements in the list except the first element. Here, we set the tail of list a to be list b, using set-cdr!:

    (define a (list 1 2 3))
    (define b (list "two" "three" "four" "five"))

    (set-cdr! a b)
    (inspect a)
    -> a is (1 "two" "three" "four" "five")

    (set-cdr! (cdr (cdr a)) (list 6))

    (inspect a)
    -> a is (1 "two" "three" 6)

The last two interactions show that any expression that resolves to a list can be passed as the first and second arguments. Note that you cannot set the tail of either an array or a string.

Variables Top ConditionalsAssignment Contents