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

2 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-expression) also written with quote 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

(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:27:0: typecheck failed: string vs. number

  sources:

   "a"

   number

syntax

(quote s-exp)

 
s-exp = id
  | number
  | string
  | boolean
  | (s-exp ...)
The quote form produces a symbol when s-exp is an identifier, otherwise it produces a literal S-expression.

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

Note that `id or (quasiquote id) produces a literal S-expression with symbol content, as opposed to producing a value of type symbol.

Examples:
> 'a

- symbol

'a

> '(a b c)

- s-expression

'(a b c)

> `a

- s-expression

'a

syntax

(quasiquote qq-form)

 
qq-form = id
  | number
  | string
  | boolean
  | (qq-form ...)
  | (unquote expr)
  | (unquote-splicing expr)
  | (quasiquote expr)

syntax

unquote

syntax

unquote-splicing

An S-expression that 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 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.

An id (to generate a symbol S-expression) in a qq-form must not be unquote, unquote-splicing, or quasiquote.

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

- s-expression

'(+ 3 3)

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

- s-expression

'(+ 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]
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])
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 true.

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 ...+)

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 ...] expr)

syntax

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

syntax

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

syntax

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

Local binding forms. The local form accommodates multiple definitions that 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 letrec, each id is visible only to later rhs-exprs as well as in the body expr.

Examples:
> (local [(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)

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 ...)

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 ...)

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 ...)

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 ...)

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)

'#(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])
 
tyid/abs = id
  | (id type ...)
Dispatches based on the variant of the result of val-expr, where 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

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)

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 inexact numbers, the test passes as long as the difference between the number 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)).