For Gauche 0.9.5


Next: , Previous: , Up: Core syntax   [Contents][Index]

4.10 Definitions

Special Form: define variable expression
Special Form: define (variable . formals) body …

[R7RS+] This form has different meanings in the toplevel (without no local bindings) or inside a local scope.

On toplevel, it defines a global binding to a symbol variable. In the first form, it globally binds a symbol variable to the value of expression, in the current module.

(define x (+ 1 2))
x ⇒ 3
(define y (lambda (a) (* a 2)))
(y 8) ⇒ 16

The second form is a syntactic sugar of defining a procedure. It is equivalent to the following form.

(define (name . args) body …)
  ≡ (define name (lambda args body …))

If the form appears inside a local scope (internal define), this introduce a local binding of the variable.

Internal defines can appear in the beginning of body of lambda or other forms that introduces local bindings. They are equivalent to a letrec* form, as shown below.

(lambda (a b)
  (define (cube x) (* x x x))
  (define (square x) (* x x))
  (+ (cube a) (square b)))

 ≡

(lambda (a b)
  (letrec* ([cube (lambda (x) (* x x x))]
            [square (lambda (x) (* x x))])
    (+ (cube a) (square b))))

Since internal defines are essentially a letrec* form, you can write mutually recursive local functions, and you can use preceding bindings introduced in the same scope to calculate the value to be defined. However, you can’t use a binding that is introduced after an internal define form to calculate its value; if you do so, Gauche may not report an error immediately, but you may get strange errors later on.

(lambda (a)
  (define x (* a 2))
  (define y (+ x 1))  ; ok to use x to calculate y
  (* a y))

(lambda (a)
  ;; You can refer to even? in odd?, since the value of even?
  ;; isn't used at the time odd? is defined; it is only used
  ;; when odd? is called.
  (define (odd? x) (or (= x 1) (not (even? (- x 1)))))
  (define (even? x) (or (= x 0) (not (odd? (- x 1)))))
  (odd? a))

(lambda (a)
  ;; This is not ok, for defining y needs to use the value
  ;; of x.  However, you may not get an error immediately.
  (define y (+ x 1))
  (define x (* a 2))
  (* a y))

Inside the body of binding constructs, internal defines must appear before any expression of the same level. The following code isn’t allowed, for an expression (print a) precedes the define form.

(lambda (a)
  (print a)
  (define (cube x) (* x x x))  ; error!
  (cube a))

It is also invalid to put no expressions but internal defines inside the body of binding constructs, although Gauche don’t report an error.

Note that begin (see Sequencing) doesn’t introduce a new scope. Defines in the begin act as if begin and surrounding parenthesis are not there. Thus these two forms are equivalent.

(let ((x 0))
  (begin
    (define (foo y) (+ x y)))
  (foo 3))
 ≡
(let ((x 0))
  (define (foo y) (+ x y))
  (foo 3))
Macro: define-values (var …) expr
Macro: define-values (var var1 … . var2) expr
Macro: define-values var expr

[R7RS] Expr is evaluated, and each value of the result is bound to each vars. In the first form, it is an error unless expr yields the same number of values as vars.

(define-values (lo hi) (min&max 3 -1 15 2))

lo ⇒ -1
hi ⇒ 15

In the second form, expr may yield as many values as var var1 … or more; the excess values are made into a list and bound to var2.

(define-values (a b . c) (values 1 2 3 4))

a ⇒ 1
b ⇒ 2
c ⇒ (3 4)

In the last form, all the values yielded by expr are gathered to a list and bound to var.

(define-values qr (quotient&remainder 23 5))

qr ⇒ (4 3)

You can use define-values wherever define is allowed; that is, you can mix define-values in internal defines.

(define (foo . args)
  (define-values (lo hi) (apply min&max args))
  (define len (length args))
  (list len lo hi))

(foo 1 4 9 3 0 7)
 ⇒ (6 0 9)

See Let-values.

Special Form: define-constant variable expression
Special Form: define-constant (variable . formals) body …

This form is only effective in toplevel. Like top-level define, but that the compiler assumes the value of variable won’t change and generates optimized code.

An error is signaled when you use set! to change the value of variable. It is allowed to redefine variable, but a warning is printed.

There’s no “internal define-constant”, since the compiler can figure out whether a local binding is mutated, and optimize code accordingly, without a help of declarations.

Special Form: define-in-module module variable expression
Special Form: define-in-module module (variable . formals) body …

This form must appear in the toplevel. It creates a global binding of variable in module, which must be either a symbol of the module name or a module object. If module is a symbol, the named module must exist.

Expression is evaluated in the current module.

The second form is merely a syntactic sugar of:

(define-in-module module variable (lambda formals body …))

Note: to find out if a symbol has definition (global binding) in the current module, you can use global-variable-bound? (see Module introspection).


Next: , Previous: , Up: Core syntax   [Contents][Index]