4.5 Definitions: define

► |  | Guide: Racket

1 | Welcome to Racket
2 | Racket Essentials
3 | Built-In Datatypes
4 | Expressions and Definitions
5 | Programmer-Defined Datatypes
6 | Modules
7 | Contracts
8 | Input and Output
9 | Regular Expressions
10 | Exceptions and Control
11 | Iterations and Comprehensions
12 | Pattern Matching
13 | Classes and Objects
14 | Units (Components)
15 | Reflection and Dynamic Evaluation
16 | Macros
17 | Creating Languages
18 | Performance
19 | Running and Creating Executables
20 | Compilation and Configuration
21 | More Libraries
22 | Dialects of Racket and Scheme
| Bibliography
| Index

▼ | 4 | Expressions and Definitions

4.1 | Notation
4.2 | Identifiers and Binding
4.3 | Function Calls (Procedure Applications)
4.4 | Functions (Procedures): lambda
4.5 | Definitions: define
4.6 | Local Binding
4.7 | Conditionals
4.8 | Sequencing
4.9 | Assignment: set!
4.10 | Quoting: quote and ’
4.11 | Quasiquoting: quasiquote and `
4.12 | Simple Dispatch: case
4.13 | Dynamic Binding: parameterize

► | 4.5 | Definitions: define

4.5.1 | Function Shorthand
4.5.2 | Curried Function Shorthand
4.5.3 | Multiple Values and define-values
4.5.4 | Internal Definitions

On this page:

4.5.1`` Function Shorthand
4.5.2`` Curried Function Shorthand
4.5.3`` Multiple Values and define-values
4.5.4`` Internal Definitions

top← prev up next →

#### 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:

( define salutation ( list-ref '("Hi" "Hello") ( random 2)))

> salutation
"Hello"

##### 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:

( define (greet name)
( string-append salutation ", " name))

> (greet "John")
"Hello, John"

( define (greet first [surname "Smith"] #:hi [hi salutation])
( string-append hi ", " first " " surname))

> (greet "John")
"Hello, John Smith"
> (greet "John" #:hi "Hey")
"Hey, John Smith"
> (greet "John" "Doe")
"Hello, 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:

( define (avg . l)
(/ ( apply + l) ( length l)))

> (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 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)
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)])
( if (= ( length parts) 2)
( values ( list-ref parts 0) ( list-ref parts 1))
( 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:

( define-values (given surname) (split-name "Adam Smith"))

> 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: Racket 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.

Expressions and internal definitions in a body sequence can be mixed, as long as the last body is 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)
( if ( zero? n)
(log-it "done")
( begin
(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:

( define (weird)
( define x x)
x)

> (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, struct (see Programmer-Defined Datatypes) or define-syntax (see Macros).

> > > Internal Definitions in Reference: Racket documents the fine points of internal definitions.

top← prev up next →