Functions are values. lambda makes one, define with a parenthesised head gives it a name, and a function can be passed, returned and stored. Racket procedures take positional arguments, optional arguments with defaults, a rest list, and arguments passed by keyword.
The argument list
(lambda formals body …+) (also written (λ formals body …+)) and (define (name formals) body …+) share one grammar for formals:
| Formal | Meaning |
|---|---|
id | a required positional argument |
[id default-expr] | an optional positional argument; the default is evaluated when the argument is missing, and it can use the arguments before it (like let*). No optional argument may come before a required positional one that has no keyword |
#:key id | a required keyword argument, given as #:key value in a call |
#:key [id default-expr] | an optional keyword argument |
. rest-id after the others | the remaining positional arguments, as a list |
rest-id instead of a list | (lambda args …) takes any number of positional arguments, all in the list |
A keyword may stand anywhere in the formals, and each keyword may appear only once. In a call, keyword arguments are given in any order and may be mixed among the positional ones; their expressions are evaluated left to right in the order written. A call with a keyword the procedure does not accept, a missing required keyword or the wrong number of positional arguments raises exn:fail:contract.
(define (greet name [greeting "Hello"] #:punct [punct "!"] #:shout? [shout? #f])
(define text (string-append greeting ", " name punct))
(if shout? (string-upcase text) text))
(greet "Ada") ; "Hello, Ada!"
(greet "Ada" "Hi") ; "Hi, Ada!"
(greet "Ada" #:shout? #t #:punct "?") ; "HELLO, ADA?"
(define (sum . xs) (apply + xs)) ; rest arguments
(sum 1 2 3) ; 6
((lambda (x #:scale s) (* x s)) 2 #:scale 10) ; 20
Several arities in one procedure
(case-lambda [formals body …+] …) makes a procedure that picks the first clause whose formals accept the number of arguments (case-lambda clauses take no keywords, no optional arguments, only plain and rest formals). (case-λ …) is the same.
(define area
(case-lambda
[(r) (* 3.14159 r r)]
[(w h) (* w h)]))
(area 2) ; a circle
(area 2 3) ; a rectangle
case-lambda.Calling procedures from data
| Form | Meaning |
|---|---|
(apply f v … lst) | calls f with the vs followed by the elements of lst; (apply f #:key v … args) accepts keyword arguments too |
(keyword-apply f keywords values lst) | a call where the keywords and their values come from two lists |
(procedure-arity f) | the number of positional arguments accepted: an integer, an arity-at-least structure or a list of those; procedure-arity-includes? tests one number |
(procedure-keywords f) | the accepted keywords, as two values: the required keywords and the allowed keywords (or #f for any) |
(procedure-rename f 'name), (object-name f) | give or get the name shown in error messages |
(procedure-reduce-arity f n) | a procedure that only accepts the stated arity |
(make-keyword-procedure (lambda (kws kw-args . rest) …)) | a procedure that accepts any keywords and gets them as lists, for wrappers |
Higher-order functions
racket/base and racket/list hold the usual ones, and each takes a procedure as its first argument:
| Function | Does |
|---|---|
map, for-each, andmap, ormap | apply a function to each element of one or more equal-length lists; for-each returns void, andmap and ormap stop early |
filter, filter-not, filter-map, remove*, partition, findf, takef, dropf, splitf-at, count, argmin, argmax, group-by, index-where | select, find or split by a predicate |
foldl, foldr, append-map, remf, sort | combine a list ((foldl cons '() '(1 2 3)) gives '(3 2 1)); sort takes a less-than procedure and the keywords #:key and #:cache-keys? |
build-list, build-vector, build-string | make a collection from a procedure of the index |
compose, compose1, curry, curryr, const, identity, thunk, negate, conjoin, disjoin | build and combine procedures: ((compose add1 abs) -4) is 5; ((curry + 1) 2) is 3; (thunk e) is (lambda () e); (negate even?) is odd? for integers |
Closures capture the variables they refer to, not copies: a (lambda () counter) sees later set!s of counter. A procedure that is a structure (with prop:procedure) can be applied like any other.
Definition forms that make procedures
Several forms are define with extras and take the same head: define/contract adds a contract; define/match matches its arguments; define/public and its relatives define methods; define-inline makes an inlined function; (: f type) with define in Typed Racket declares its type. In Typed Racket each argument may carry a type, as in (define (f [x : Integer]) : String …).
Not described
Known, not yet covered
- Reference: the complete lists of functions in
racket/list,racket/functionandracket/baseare summarised by role here and on The standard library; argument lists and edge cases of each function are not given. - Reference: chaperones and impersonators of procedures,
procedure-closure-contents-eq?, the arity-mask functions andracket/unsafe/opswere not described.
See also
- Expressions and binding –
defineand application - Contracts – checking arguments and results
- Scheme: procedures and numbers – Scheme's smaller lambda lists