On this page:
set!
set!-values

2.17 Assignment: set! and set!-values

+Assignment: set! in Guide: Racket introduces set!.

(set! id expr)
If id has a transformer binding to an assignment transformer, as produced by make-set!-transformer or as an instance of a structure type with the prop:set!-transformer property, then this form is expanded by calling the assignment transformer with the full expressions. If id has a transformer binding to a rename transformer as produced by make-rename-transformer or as an instance of a structure type with the prop:rename-transformer property, then this form is expanded by replacing id with the target identifier (e.g., the one provided to make-rename-transformer). If a transformer binding has both prop:set!-transformer ad prop:rename-transformer properties, the latter takes precedence.

Otherwise, evaluates expr and installs the result into the location for id, which must be bound as a local variable or defined as a top-level variable or module-level variable. If id refers to an imported binding, a syntax error is reported. If id refers to a top-level variable that has not been defined, the exn:fail:contract exception is raised.

See also compile-allow-set!-undefined.

Examples:

  (define x 12)
  > (set! x (add1 x))
  > x

  13

  > (let ([x 5])
      (set! x (add1 x))
      x)

  6

  > (set! i-am-not-defined 10)

  set!: cannot set undefined variable: i-am-not-defined

(set!-values (id ...) expr)
Assuming that all ids refer to variables, this form evaluates expr, which must produce as many values as supplied ids. The location of each id is filled with the corresponding value from expr in the same way as for set!.

Example:

  > (let ([a 1]
          [b 2])
      (set!-values (a b) (values b a))
      (list a b))

  '(2 1)

More generally, the set!-values form is expanded to

  (let-values ([(tmp-id ...) expr])
    (set! id tmp-id) ...)

which triggers further expansion if any id has a transformer binding to an assignment transformer.