4.5 Definitions: define
A basic definition has the form
(define id expr)
in which case id is bound to the result of expr.
| Examples: | ||
| 
 | ||
| > salutation | ||
| "Hi" | 
4.5.1 Function Shorthand
The define form also supports a shorthand for function definitions:
(define (id arg ) body )
which is a shorthand for
(define id (lambda (arg ...) body ...+))
| Examples: | |||
| 
 | |||
| > (greet "John") | |||
| "Hi, John" | 
| (define (greet first [surname "Smith"] #:hi [hi salutation]) | 
| (string-append hi ", " first " " surname)) | 
| > (greet "John") | 
| "Hi, John Smith" | 
| > (greet "John" #:hi "Hey") | 
| "Hey, John Smith" | 
| > (greet "John" "Doe") | 
| "Hi, John Doe" | 
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
(define id (lambda (arg ... . rest-id) body ...+))
| Examples: | |||
| 
 | |||
| > (avg 1 2 3) | |||
| 2 | 
4.5.2 Curried Function Shorthand
Consider the following make-add-suffix function that takes a string and returns another function that takes a string:
| (define make-add-suffix | 
| (lambda (s2) | 
| (lambda (s) (string-append s s2)))) | 
Although it’s not common, result of make-add-suffix could be called directly, like this:
| > ((make-add-suffix "!") "hello") | 
| "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:
| (define ((make-add-suffix s2) s) | 
| (string-append s s2)) | 
| > ((make-add-suffix "!") "hello") | 
| "hello!" | 
| (define louder (make-add-suffix "!")) | 
| (define less-sure (make-add-suffix "?")) | 
| > (less-sure "really") | 
| "really?" | 
| > (louder "really") | 
| "really!" | 
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
The expansion of this shorthand has one nested lambda form for each head in the definition, where the innermost head corresponds to the outermost lambda.
4.5.3 Multiple Values and define-values
A Scheme 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) | 
| 4 | 
| > (remainder 13 3) | 
| 1 | 
| > (quotient/remainder 13 3) | 
| 4 | 
| 1 | 
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) | 
| 1 | 
| 2 | 
| 3 | 
| (define (split-name name) | 
| (let ([parts (regexp-split " " name)]) | 
| (error "not a <first> <last> name")))) | 
| > (split-name "Adam Smith") | 
| "Adam" | 
| "Smith" | 
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.
| Examples: | ||
| 
 | ||
| > given | ||
| "Adam" | ||
| > surname | ||
| "Smith" | 
A define form (that is not a function shorthand) is equivalent to a define-values form with a single id.
 Definitions: define, define-syntax, ... in Reference: PLT Scheme provides more on definitions.
Definitions: define, define-syntax, ... in Reference: PLT Scheme provides more on definitions.
4.5.4 Internal Definitions
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 | 
| (printf "running\n") | 
| (f 0)) | 
| 
 | 
| (lambda (f) ; one definition | 
| (define (log-it what) | 
| (printf "~a\n")) | 
| (log-it "running") | 
| (f 0) | 
| (log-it "done")) | 
| 
 | 
| (lambda (f n) ; two definitions | 
| (define (call n) | 
| (log-it "done") | 
| (log-it "running") | 
| (f 0) | 
| (call (- n 1))))) | 
| (define (log-it what) | 
| (printf "~a\n")) | 
| (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>.
| Examples: | ||||
| 
 | ||||
| > (weird) | ||||
| #<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, define-struct (see Programmer-Defined Datatypes) or define-syntax (see Macros).
 Internal Definitions in Reference: PLT Scheme documents the fine points of internal definitions.
Internal Definitions in Reference: PLT Scheme documents the fine points of internal definitions.