You can declare a variable using a !
form.
This takes a variable name, and an expression. It declares a new
variable with the given name, and gives it the value of the expression.
#|kawa:1|#(! binary-kilo 1024)
#|kawa:2|#(! binary-mega (* binary-kilo binary-kilo))
#|kawa:3|#binary-mega
1048576
If you prefer, you can use define
instead of !
:
#|kawa:1|#(define binary-kilo 1024)
#|kawa:2|#(define binary-mega (* binary-kilo binary-kilo))
#|kawa:3|#binary-mega
1048576
The advantage of using define
is that it is portable
to other Scheme implementations.
The advantages of using !
is that it is shorter;
it generalizes to patterns (see later);
and it guards against accidentally “shadowing” a variable
by a nested variable with the same name.
A !
(or define
) typed into the command-line
defines a top-level variable.
You can also declare local variables, which are variables defined for
a given block of code. For example, in the following code let
is used to set up a local binding of x
to 3: this does not affect
the outer binding of x
to 5:
(define x 5) (let ((x 3)) (display x)) ⇒ 3 (display x) ⇒ 5
Alternative forms for defining local variables are
let
, let*
, or letrec
/letrec*
.
The differences are in the order in which definitions are made.
let
evaluates all its definitions in the environment holding
at the start of the let
statement. In the following example,
the local variables are defined using values from the global variables:
(define x 5) (define y 2) (let ((x (+ 2 y)) ; uses value of global y, i.e. 2 (y (+ 3 x))) ; uses value of global x, i.e. 5 (display (list x y))) ⇒ (4 8)
let*
instead evaluates each definition in the environment holding
at the start of the let*
statement, along with all previous
local definitions. In the following example, y
is now defined with the
local value of x
:
(define x 5) (define y 2) (let* ((x (+ 2 y)) ; uses value of global y, i.e. 2 (y (+ 3 x))) ; uses value of local x, i.e. 4 (display (list x y))) ⇒ (4 7)
letrec/letrec*
are similar, but allow the definition of recursive
functions:
(letrec ((is-even? (lambda (n) (and (not (= 1 n)) (or (zero? n) (is-odd? (- n 1)))))) (is-odd? (lambda (n) (and (not (zero? n)) (or (= 1 n) (is-even? (- n 1))))))) (display (is-even? 11))) ⇒ #f