4.5 Definitions: define
A basic definition has the form
(define id expr)
in which case id is bound to the result of expr.
The define form also supports a shorthand for function definitions:
(define (id arg ...) body ...+)
which is a shorthand for
|> (greet "John")|
The function shorthand via define also supports a “rest” argument (i.e., a final argument to collect extra arguments in a list):
(define (id arg ... . rest-id) body ...+)
which is a shorthand
|> (avg 1 2 3)|
Consider the following make-add-suffix function that takes a string and returns another function that takes a string:
Although it’s not common, result of make-add-suffix could be called directly, like this:
|> ((make-add-suffix "!") "hello")|
In a sense, make-add-suffix is a function takes two arguments, but it takes them one at a time. A function that takes some of its arguments and returns a function to consume more is sometimes called a curried function.
Using the function-shorthand form of define, make-add-suffix can be written equivalently as
|(define (make-add-suffix s2)|
|(lambda (s) (string-append s s2)))|
This shorthand reflects the shape of the function call (make-add-suffix "!"). The define form further supports a shorthand for defining curried functions that reflects nested function calls:
The full syntax of the function shorthand for define is as follows:
(define (head args) body ...+)
head = id | (head args) args = arg ... | arg ... . rest-id
4.5.3 Multiple Values and define-values
A Racket expression normally produces a single result, but some expressions can produce multiple results. For example, quotient and remainder each produce a single value, but quotient/remainder produces the same two values at once:
|> (quotient 13 3)|
|> (remainder 13 3)|
|> (quotient/remainder 13 3)|
As shown above, the REPL prints each result value on its own line.
Multiple-valued functions can be implemented in terms of the values function, which takes any number of values and returns them as the results:
|> (values 1 2 3)|
The define-values form binds multiple identifiers at once to multiple results produced from a single expression:
(define-values (id ...) expr)
The number of results produced by the expr must match the number of ids.
When the grammar for a syntactic form specifies body, then the corresponding form can be either a definition or an expression. A definition as a body is an internal definition.
All internal definitions in a body sequence must appear before any expression, and the last body must be an expression.
For example, the syntax of lambda is
(lambda gen-formals body ...+)
so the following are valid instances of the grammar:
|(lambda (f) ; no definitions|
|(lambda (f) ; one definition|
|(define (log-it what)|
|(lambda (f n) ; two definitions|
|(define (call n)|
|(if (zero? n)|
|(call (- n 1)))))|
|(define (log-it what)|
|(call f n))|
Internal definitions in a particular body sequence are mutually recursive; that is, any definition can refer to any other definition – as long as the reference isn’t actually evaluated before its definition takes place. If a definition is referenced too early, the result is a special value #<undefined>.
A sequence of internal definitions using just define is easily translated to an equivalent letrec form (as introduced in the next section). However, other definition forms can appear as a body, including define-values, struct (see Programmer-Defined Datatypes) or define-syntax (see Macros).