On this page:
....
has-type
quote
quasiquote
unquote
unquote-splicing
#%app
lambda
λ
if
cond
case
begin
when
unless
local
letrec
let
let*
shared
parameterize
set!
and
or
list
vector
values
type-case
try
test
test/  exn
time
let/  cc

3 Expressions🔗ℹ

An expression can be a literal constant that is a number (type Number), a string (type String), a symbol (type Symbol) written with quote or ', an S-expression (type S-Exp) written with quasiquote or `, #t (type Boolean), #f (type Boolean), or a character (type Char). An expression also can be a bound identifier (in which case its type comes from its binding).

syntax

....

The .... form is intended as a placeholder for a expression. It can be used in any expression position and can have any type, but .... reports an error when evaluated.

Examples:
> (if #f .... 'ok)

- Symbol

'ok

> (if #t .... 'no)

- Symbol

reached a `....` placeholder

syntax

(has-type expr : type)

Equivalent to expr, but declares/asserts that expr has type type.

Examples:
> (has-type 1 : Number)

- Number

1

> (has-type "a" : Number)

eval:24:0: typecheck failed: String vs. Number

  sources:

   "a"

   Number

syntax

(quote q-form)

 
q-form = id
  | Number
  | String
  | Boolean
  | (q-form ...)
  | #(q-form ...)
  | #&q-form

For an introduction, see the tutorial section Lists.

The quote form is usually written as just a ' before a q-form; that is, 'id and (quote id) are equivalent.

The quote form produces a symbol, number, string, boolean, list, vector, or box value:

Beyond the syntactic contraints of q-form, the resulting list must have a type. So, for example, quote cannot create a list that mixes numbers and symbols.

Examples:
> 'a

- Symbol

'a

> '(1 2 3)

- (Listof Number)

'(1 2 3)

> '(1 a)

eval:27:0: typecheck failed: Number vs. Symbol

  sources:

   (quote (1 a))

   1

   a

> '((a) (b c))

- (Listof (Listof Symbol))

'((a) (b c))

syntax

(quasiquote qq-form)

 
qq-form = id
  | Number
  | String
  | Boolean
  | (qq-form ...)
  | (unquote expr)
  | (unquote-splicing expr)
  | (quasiquote expr)

syntax

unquote

syntax

unquote-splicing

For an introduction, see the tutorial section S-Expressions.

The quasiquote form is similar to quote, but it produces an S-expression, and it supports escapes via unquote and unquote-splicing. A (unquote expr) form is replaced with the value of expr, while a (unquote-splicing expr) form requires that expr produces a list and is replaced by the list content as an inlined sequence of S-expressions.

The quasiquote form is usually written as just a ` before qq-form; that is, 'qq-form and (quasiquote qq-form) are equivalent.

The unquote form is usually written as just a , before expr; that is, ,expr and (unquote expr) are equivalent.

The unquote-splicing form is usually written as just a ,@ before expr; that is, ,@expr and (unquote-splicing expr) are equivalent.

With a nested quasiquote form, escapes are preserved while escaping to the enclosing level of quotation. For example, ``(,(+ 1 2)) is equivalent to '(quasiquote (unquote 1)) where the quasiquote and unquote symbols are preserved in the result S-expression.

Examples:
> `a

- S-Exp

`a

> `(1 a)

- S-Exp

`(1 a)

> `(+ ,(number->s-exp (+ 1 2)) 3)

- S-Exp

`(+ 3 3)

> `(+ ,@(list `1 `2) 3)

- S-Exp

`(+ 1 2 3)

syntax

(#%app expr expr ...)

A function call, which is normally written without the #%app keyword.

Example:
> (add1 1)

- Number

2

syntax

(lambda (id/ty ...) expr)

(lambda (id/ty ...) : type expr)
 
id/ty = id
  | [id : type]

For an introduction, see the tutorial section Anonymous Functions.

An anonymous function which takes as many argument as specified id/tys and produces the result of expr. Each argument has an optional type specification, and when a type is written after (id/ty ...), it declares the result type of the function.

Examples:
> (lambda (x) (+ x 1))

- (Number -> Number)

#<procedure>

> (lambda ([x : Number]) (+ x 1))

- (Number -> Number)

#<procedure>

> ((lambda (x) (+ x 1)) 3)

- Number

4

> (map (lambda (x) (+ x 1)) (list 1 2 3))

- (Listof Number)

'(2 3 4)

syntax

λ

An alias for lambda.

syntax

(if test-expr expr expr)

syntax

(cond [test-expr expr] ...)

(cond [test-expr expr] ... [else expr])

For an introduction, see the tutorial section Conditionals.

An if form produces the value of the first expr if test-expr produces true or the value of the second expr otherwise. Only one of the two exprs is evaluated.

A cond form produces the value of the first expr whose test-expr produces true. The test-exprs are tried in order until a true result is found, and at most one of the exprs is evaluated. If no test-expr produces a true result, a “no matching clause“ exception is raised. An else in place of the last test-expr is equivalent to #t.

Each test-expr must have type Boolean.

Examples:
> (if (< 1 2)
      'less
      'greater-or-equal)

- Symbol

'less

> (cond
   [(< 2 1) 'bad]
   [(< 2 2) (begin (/ 1 0) 'oops)]
   [(< 2 3) 'ok]
   [(< 2 (/ 1 0)) 'oops]
   [else (begin (/ 1 0) 'oops)])

- Symbol

'ok

syntax

(case val-expr [(id-or-number ...) expr] ...)

(case val-expr [(id-or-number ...) expr] ... [else expr])
Performs a case dispatch on a symbol or number. The value of the case form is the value of an expr whose (id-or-number ...) sequence includes the result of val-expr, when symbols are matched to identifiers. If no id-or-number matches, a “no matching clause“ exception is raised.

The dispatching mode, symbol or number, is inferred from the id-or-numbers, which must all be symbols or numbers for a given use of case. If no clause provides a number or symbol, then symbol dispatch is inferred.

Examples:
> (case (+ 1 2)
    [(0 1 2) 'too-small]
    [(3) 'ok]
    [else 'other])

- Symbol

'ok

> (case 'goodbye
    [(hello) 'hi]
    [(goodbye) 'bye])

- Symbol

'bye

syntax

(begin expr ...+)

For an introduction, see the tutorial section State.

Evaluates the exprs in sequence, producing the result of the last expr.

Example:
> (+ (begin
      (display "hi\n")
      1)
     (begin
      (display "bye\n")
      2))

- Number

hi

bye

3

syntax

(when test-expr expr ...+)

syntax

(unless test-expr expr ...+)

Conditionally evaluates exprs for their side effects, always returning (void). A when form evaluates its exprs only test-expr produces true, while an unless form evaluates its exprs only test-expr produces false.

Examples:
> (when (< 1 2) (display "yes"))

- Void

yes

> (unless (< 1 2) (display "no"))

- Void

syntax

(local [definition-or-type-declaration ...] expr)

syntax

(letrec ([id rhs-expr] ...) expr)

syntax

(let ([id rhs-expr] ...) expr)

syntax

(let* ([id rhs-expr] ...) expr)

For an introduction, see the tutorial section Definitions.

Local binding forms. The local form accommodates multiple definitions and type declarations (using :) that are visible only among the definitions and the body expr. The letrec, let, and let* forms bind each id to the value of the corresponding rhs-expr (where the rhs-exprs are evaluated in order). In the case of letrec, each id is visible to every rhs-expr as well as in the body expr. In the case of let, each id is visible only in the body expr. In the case of let*, each id is visible only to later rhs-exprs as well as in the body expr.

Examples:
> (local [(add-x : (Number -> Number))
          (x : Number)
          (define (add-x y) (+ x y))
          (define x 2)]
    (add-x 3))

- Number

5

> add-x

eval:46:0: add-x: free variable while typechecking

  in: add-x

> (letrec ([add-x (lambda (y) (+ x y))]
           [x 2])
    (add-x 3))

- Number

5

> (let ([x 1])
    (let ([add-x (lambda (y) (+ x y))]
          [x 2])
     (add-x 3)))

- Number

4

> (let ([x 1])
    (let* ([add-x (lambda (y) (+ x y))]
           [x 2])
     (add-x 3)))

- Number

4

> (let ([x 1])
    (let* ([x 2]
           [add-x (lambda (y) (+ x y))])
     (add-x 3)))

- Number

5

syntax

(shared ([id expr] ...) expr)

Creates cyclic data for a restricted set of restricted expr patterns. See shared from racket/shared for a description of allowed patterns, besides the additional restriction that the form must be typed.

Example:
> (shared ([infinite-ones (cons 1 infinite-ones)])
    (list-ref infinite-ones 1001))

- Number

1

syntax

(parameterize ([param-expr val-expr] ...) expr)

The parameterize form implements a kind of dynamic binding. Each param-expr must have type (Parameterof type) where the corresponding val-expr has type type, and the parameter produces by param-expr is set to val-expr for the dynamic extent of expr.

Examples:
> (define current-mode (make-parameter 'straight))
> (define (display-line)
    (display (case (parameter-ref current-mode)
              [(straight) "---"]
              [(curvy) "~~~"])))
> (parameterize ([current-mode 'curvy])
    (display-line))

- Void

~~~

> (display-line)

- Void

---

> (define f
    (parameterize ([current-mode 'curvy])
      (lambda () (display-line))))
> (f)

- Void

---

syntax

(set! id expr)

For an introduction, see the tutorial section State.

Mutates id to have the value of expr.

Examples:
> (define x 1)
> (set! x (+ 1 1))

- Void

> x

- Number

2

syntax

(and expr ...)

syntax

(or expr ...)

For an introduction, see the tutorial section Conditionals.

Boolean combinations with short-circuiting: as soon as an expr produces false in and or true in or, the remaining exprs are not evaluated. The value of (and) is true and (or) is false. The exprs must have type Boolean.

Examples:
> (and (< 1 2) (< 3 4))

- Boolean

#t

> (and (< 2 1) (< 3 (/ 1 0)))

- Boolean

#f

> (or (< 2 1) (< 3 4))

- Boolean

#t

> (or (< 2 1) (< 1 2) (< 3 (/ 1 0)))

- Boolean

#t

syntax

(list elem ...)

For an introduction, see the tutorial section Lists.

Builds a list. All elems must have the same type.

Examples:
> (list 1 2 3)

- (Listof Number)

'(1 2 3)

> (list "a" "b")

- (Listof String)

'("a" "b")

> (list (list 1 2) empty (list 3 4))

- (Listof (Listof Number))

'((1 2) () (3 4))

syntax

(vector elem ...)

For an introduction, see the tutorial section State.

Builds a vector. All elems must have the same type.

Examples:
> (vector 1 2 3)

- (Vectorof Number)

'#(1 2 3)

> (vector "a" "b")

- (Vectorof String)

'#("a" "b")

> (vector (list 1 2) empty (list 3 4))

- (Vectorof (Listof Number))

'#((1 2) () (3 4))

syntax

(values elem ...)

For an introduction, see the tutorial section Tuples and Options.

Combines multiple values into tuple, where a tuple containing one value is equivalent to the value. Match a tuple result using define-values.

The type of each elem is independent.

Example:
> (values 1 'two "three")

- (Number * Symbol * String)

(values 1 'two "three")

syntax

(type-case tyid/abs val-expr
  [(variant-id field-id ...) expr] ...)
(type-case tyid/abs val-expr
  [(variant-id field-id ...) expr] ...
  [else expr])
(type-case (Listof type) val-expr
  [list-variant expr] ...)
(type-case (Listof type) val-expr
  [list-variant expr] ...
  [else expr])
 
tyid/abs = id
  | (id type ...)
     
list-variant = empty
  | (cons first-id rest-id)

For an introduction, see the tutorial section Datatypes.

Dispatches based on the variant of the result of val-expr.

In the form that has tyid/abs, val-expr must have type tyid/abs, and tyid/abs must refer to a type defined via define-type. The result is the value of expr for the variant-id that is instantiated by val-expr or the expr in an else clause if no variant-id matches. Each field-id is bound to a corresponding (by position) value of a field within the variant instance for use in the same clause’s expr.

The number of field-ids must match the number of fields declared for variant-id in the definition of tyid/abs, and either every variant-id of tyid/abs must have a clause in the type-case form or an else clause must be present.

Examples:
> (define-type Shape
    (circle [radius : Number])
    (rectangle [width : Number]
               [height : Number]))
> (define (area [s : Shape])
    (type-case Shape s
      [(circle r) (* (* r r) 3.14)]
      [(rectangle w h) (* w h)]))
> (area (circle 1))

- Number

3.14

> (area (rectangle 2 3))

- Number

6

In the (Listof type) form, val-expr must have type (Listof type). Each non-else clause is either a (cons first-id rest-id) clause or an empty clause, and both most appear without else, or at most one of those can appear with else.

Examples:
> (define (my-length l)
    (type-case (Listof 'a) l
      [empty 0]
      [(cons a b) (+ 1 (my-length b))]))
> (length '(1 2 3))

- Number

3

> (length '(a b))

- Number

2

syntax

(try expr (lambda () handle-expr))

Either returns expr’s result or catches an exception raised by expr and calls handle-expr.

Examples:
> (try 1 (lambda () 2))

- Number

1

> (try (/ 1 0) (lambda () 2))

- Number

2

> (try (begin (error 'demo "oops") 1) (lambda () 2))

- Number

2

> (try (begin (error 'demo "oops") 1) (lambda () (/ 2 0)))

- Number

/: division by zero

syntax

(test expr expr)

syntax

(test/exn expr string-expr)

For an introduction, see the tutorial section Testing and Debugging.

The test form checks whether the value of the first expr matches the value of the second expr, and reports a test failure or success. If the results of the two exprs are numbers and either is inexact, the test passes as long as the difference between the numbers is less than 0.01.

The test/exn form checks whether the expr raises an exception whose error message includes the string produced by string-expr.

The test and test/exn forms have type Void, although they do not actually produce a void value; instead, they produce results suitable for automatic display through a top-level expression, and the Void type merely prevents your program from using the result.

See also print-only-errors and module+.

syntax

(time expr)

Shows the time taken to evaluate expr and returns the value of expr.

syntax

(let/cc id expr)

Equivalent to (call/cc (lambda (id) expr)).