Scheme is a lexically scoped language as opposed to using dynamic-scope. With this scope the identifier is fixed at interpretation and or compilation in some region in the source code containing the identifier's declaration. For example

 (define x 2) 
 (define y 10) 
 (define multiply 
   (lambda (x y) 
      (* x y))) 
 (+ x y) 
 (multiply y 10) 

When evaluated in the interpreter it outputs


We can see the binding of x to 2 as the identifier's declaration. In the first two lines of the program x is bound to 2 and y is bound to 10. In the definition of multiply using lambda x and y are bound to 10 and 10 respectively in the call to the procedure of multiply.

The form set! modifies the binding of the variable. Note that set! scope is also lexical

 (define x 10) 
 (set! x 20) 
 (define add 
  (lambda (x y) 
    (set! x (+ x y)) 
 (add 10 100) 

When evaluated in the interpreter you see


Even though set! in the lambda does the exact same thing as not being in there it is important to point out that set! only changes a binding in its own scope which is local as defined by the lambda.

Local variables can also be introduced without using lambda. To do this we use the let special form.

 (define x 4) 
 (define y 5) 
 (let ((x 1) 
       (y 2)) 
   (* x y)) 
 (* x y) 

When evaluated in the interpreter you see


Basically it binds x to 1 and y to 2 only in the scope of the let form which evaluates the product of x and y. Then the global variables x and y are evaluated which when their product is computed you get 20.