2 Special Form Reference
Typed Racket provides a variety of special forms above and beyond those in Racket. They are used for annotating variables with types, creating new types, and annotating expressions.
2.1 Binding Forms
loop, f, a, and v are names, t is a type. e is an expression and body is a block.
Examples: | |||||||||||||||||
|
Examples: | |||||||||||||||||
|
syntax
(plet: (a ...) ([v : t e] ...) . body)
syntax
(letrec: ([v : t e] ...) . body)
syntax
(let*: ([v : t e] ...) . body)
syntax
(let-values: ([([v : t] ...) e] ...) . body)
syntax
(letrec-values: ([([v : t] ...) e] ...) . body)
syntax
(let*-values: ([([v : t] ...) e] ...) . body)
2.2 Anonymous Functions
syntax
(lambda: formals . body)
formals = ([v : t] ...) | ([v : t] ... v : t *) | ([v : t] ... v : t ooo bound)
syntax
(λ: formals . body)
syntax
(case-lambda: [formals body] ...)
Example: | ||||||||||
|
syntax
(pcase-lambda: (a ...) [formals body] ...)
(pcase-lambda: (a ... b ooo) [formals body] ...)
syntax
(opt-lambda: formals . body)
formals = ([v : t] ... [v : t default] ...) | ([v : t] ... [v : t default] ... v : t *) | ([v : t] ... [v : t default] ... v : t ooo bound)
syntax
(popt-lambda: (a ...) formals . body)
(popt-lambda: (a ... a ooo) formals . body)
2.3 Loops
syntax
(for: type-ann-maybe (for:-clause ...) expr ...+)
type-ann-maybe =
| : u for:-clause = [id : t seq-expr] | [id seq-expr] | #:when guard
syntax
(for/list: type-ann-maybe (for:-clause ...) expr ...+)
syntax
(for/hash: type-ann-maybe (for:-clause ...) expr ...+)
syntax
(for/hasheq: type-ann-maybe (for:-clause ...) expr ...+)
syntax
(for/hasheqv: type-ann-maybe (for:-clause ...) expr ...+)
syntax
(for/vector: type-ann-maybe (for:-clause ...) expr ...+)
syntax
(for/flvector: type-ann-maybe (for:-clause ...) expr ...+)
syntax
(for/and: type-ann-maybe (for:-clause ...) expr ...+)
syntax
(for/or: type-ann-maybe (for:-clause ...) expr ...+)
syntax
(for/first: type-ann-maybe (for:-clause ...) expr ...+)
syntax
(for/last: type-ann-maybe (for:-clause ...) expr ...+)
syntax
(for/sum: type-ann-maybe (for:-clause ...) expr ...+)
syntax
(for/product: type-ann-maybe (for:-clause ...) expr ...+)
syntax
(for*/list: type-ann-maybe (for:-clause ...) expr ...+)
syntax
(for*/hash: type-ann-maybe (for:-clause ...) expr ...+)
syntax
(for*/hasheq: type-ann-maybe (for:-clause ...) expr ...+)
syntax
(for*/hasheqv: type-ann-maybe (for:-clause ...) expr ...+)
syntax
(for*/vector: type-ann-maybe (for:-clause ...) expr ...+)
syntax
(for*/flvector: type-ann-maybe (for:-clause ...) expr ...+)
syntax
(for*/and: type-ann-maybe (for:-clause ...) expr ...+)
syntax
(for*/or: type-ann-maybe (for:-clause ...) expr ...+)
syntax
(for*/first: type-ann-maybe (for:-clause ...) expr ...+)
syntax
(for*/last: type-ann-maybe (for:-clause ...) expr ...+)
syntax
(for*/sum: type-ann-maybe (for:-clause ...) expr ...+)
syntax
(for*/product: type-ann-maybe (for:-clause ...) expr ...+)
syntax
(for/lists: type-ann-maybe ([id : t] ...) (for:-clause ...) expr ...+)
syntax
(for/fold: type-ann-maybe ([id : t init-expr] ...) (for:-clause ...) expr ...+)
syntax
(for*: void-ann-maybe (for-clause ...) expr ...+)
syntax
(for*/lists: type-ann-maybe ([id : t] ...) (for:-clause ...) expr ...+)
syntax
(for*/fold: type-ann-maybe ([id : t init-expr] ...) (for:-clause ...) expr ...+)
syntax
(do: : u ([id : t init-expr step-expr-maybe] ...) (stop?-expr finish-expr ...) expr ...+)
step-expr-maybe =
| step-expr
2.4 Definitions
syntax
(define: v : t e)
(define: (a ...) v : t e) (define: (a ... a ooo) v : t e) (define: (f . formals) : t . body) (define: (a ...) (f . formals) : t . body) (define: (a ... a ooo) (f . formals) : t . body)
Examples: | |||||||||||||||||||
|
2.5 Structure Definitions
syntax
(struct: maybe-type-vars name-spec ([f : t] ...) options ...)
maybe-type-vars =
| (v ...) name-spec = name | name parent options = #:transparent | #:mutable
Options provided have the same meaning as for the struct form.
syntax
(define-struct: maybe-type-vars name-spec ([f : t] ...) options ...)
maybe-type-vars =
| (v ...) name-spec = name | (name parent) options = #:transparent | #:mutable
syntax
(define-struct/exec: name-spec ([f : t] ...) [e : proc-t])
name-spec = name | (name parent)
2.6 Names for Types
syntax
(define-type name t maybe-omit-def)
(define-type (name v ...) t maybe-omit-def)
maybe-omit-def = #:omit-define-syntaxes |
Examples: | ||||||
|
If #:omit-define-syntaxes is specified, no definition of name is created. In this case, some other definition of name is necessary.
2.7 Generating Predicates Automatically
syntax
(make-predicate t)
syntax
(define-predicate name t)
2.8 Type Annotation and Instantiation
syntax
(: v t)
syntax
(provide: [v t] ...)
syntax
#{v : t}
syntax
(ann e t)
syntax
#{e :: t}
syntax
(cast e t)
Examples: | ||||||||||||||
|
Examples: | ||||||||||||||||||||||
|
syntax
#{e @ t ...}
syntax
#{e @ t ... t ooo bound}
2.9 Require
Here, m is a module spec, pred is an identifier naming a predicate, and maybe-renamed is an optionally-renamed identifier.
syntax
(require/typed m rt-clause ...)
rt-clause = [maybe-renamed t] |
[#:struct name ([f : t] ...) struct-option ...] |
[#:struct (name parent) ([f : t] ...) struct-option ...] | [#:opaque t pred] maybe-renamed = id | (orig-id new-id) struct-option = #:constructor-name constructor-id | #:extra-constructor-name constructor-id
The first case requires maybe-renamed, giving it type t.
The second and third cases require the struct with name name with fields f ..., where each field has type t. The third case allows a parent structure type to be specified. The parent type must already be a structure type known to Typed Racket, either built-in or via require/typed. The structure predicate has the appropriate Typed Racket filter type so that it may be used as a predicate in if expressions in Typed Racket.
Examples: | ||||||||||||||||||||
|
The fourth case defines a new type t. pred, imported from module m, is a predicate for this type. The type is defined as precisely those values to which pred produces #t. pred must have type (Any -> Boolean). Opaque types must be required lexically before they are used.
Examples: | |||||||||||||
|
In all cases, the identifiers are protected with contracts which enforce the specified types. If this contract fails, the module m is blamed.
Some types, notably the types of predicates such as number?, cannot be converted to contracts and raise a static error when used in a require/typed form. Here is an example of using case-> in require/typed.
(require/typed racket/base [file-or-directory-modify-seconds (case-> [String -> Exact-Nonnegative-Integer] [String (Option Exact-Nonnegative-Integer) -> (U Exact-Nonnegative-Integer Void)] [String (Option Exact-Nonnegative-Integer) (-> Any) -> Any])])
file-or-directory-modify-seconds has some arguments which are optional, so we need to use case->.
syntax
(require/typed/provide m rt-clause ...)
Examples: | ||||||||||||||
|
2.10 Other Forms
syntax
syntax
syntax
syntax
Note that unlike define, define does not bind functions with keyword arguments to static information about those functions.
Examples: | ||||||||||||||||||||||||||||||
|
syntax
(#%module-begin form ...)
syntax
(#%top-interaction . form)