On this page:
4.3.1 Evaluation Order and Arity
4.3.2 Keyword Arguments
4.3.3 The apply Function
Version: 4.2.1

4.3 Function Calls (Procedure Applications)

An expression of the form

(proc-expr arg-expr ...)

is a function call – also known as a procedure application – when proc-expr is not an identifier that is bound as a syntax transformer (such as if or define).

4.3.1 Evaluation Order and Arity

A function call is evaluated by first evaluating the proc-expr and all arg-exprs in order (left to right). Then, if proc-expr produces a function that accepts as many arguments as supplied arg-exprs, the function is called. Otherwise, an exception is raised.

Examples:

  > (cons 1 null)

  (1)

  > (+ 1 2 3)

  6

  > (cons 1 2 3)

  cons: expects 2 arguments, given 3: 1 2 3

  > (1 2 3)

  procedure application: expected procedure, given: 1;

  arguments were: 2 3

Some functions, such as cons, accept a fixed number of arguments. Some functions, such as + or list, accept any number of arguments. Some functions accept a range of argument counts; for example substring accepts either two or three arguments. A function’s arity is the number of arguments that it accepts.

4.3.2 Keyword Arguments

Some functions accept keyword arguments in addition to by-position arguments. For that case, an arg can be an arg-keyword arg-expr sequence instead of just a arg-expr:

Keywords introduces keywords.

(proc-expr arg ...)
 
arg = arg-expr
  | arg-keyword arg-expr

For example,

  (go "super.ss" #:mode 'fast)

calls the function bound to go with "super.ss" as a by-position argument, and with 'fast as an argument associated with the #:mode keyword. A keyword is implicitly paired with the expression that follows it.

Since a keyword by itself is not an expression, then

  (go "super.ss" #:mode #:fast)

is a syntax error. The #:mode keyword must be followed by an expression to produce an argument value, and #:fast is not an expression.

The order of keyword args determines the order in which arg-exprs are evaluated, but a function accepts keyword arguments independent of their position in the argument list. The above call to go can be equivalently written

  (go #:mode 'fast "super.ss")

Procedure Applications and #%app in Reference: PLT Scheme provides more on procedure applications.

4.3.3 The apply Function

The syntax for function calls supports any number of arguments, but a specific call always specifies a fixed number of arguments. As a result, a function that takes a list of arguments cannot directly apply a function like + to all of the items in the list:

  (define (avg lst) ; doesn’t work...
    (/ (+ lst) (length lst)))

 

  > (avg '(1 2 3))

  +: expects argument of type <number>; given (1 2 3)

  (define (avg lst) ; doesn’t always work...
   (/ (+ (list-ref lst 0) (list-ref lst 1) (list-ref lst 2))
      (length lst)))

 

  > (avg '(1 2 3))

  2

  > (avg '(1 2))

  list-ref: index 2 too large for list: (1 2)

The apply function offers a way around this restriction. It takes a function and a list arguments, and it applies the function to the arguments:

  (define (avg lst)
    (/ (apply + lst) (length lst)))

 

  > (avg '(1 2 3))

  2

  > (avg '(1 2))

  3/2

  > (avg '(1 2 3 4))

  5/2

As a convenience, the apply function accepts additional arguments between the function and the list. The additional arguments are effectively consed onto the argument list:

  (define (anti-sum lst)
    (apply - 0 lst))

 

  > (anti-sum '(1 2 3))

  -6

The apply function supports only by-position arguments. To apply a function with keyword arguments, use the keyword-apply function, which accepts a function to apply and three lists. The first two lists are in parallel, where the first list contains keywords (sorted by keyword<), and the second list contains a corresponding argument for each keyword. The third list contains by-position function arguments, as for apply.

  (keyword-apply go
                 '(#:mode)
                 '(fast)
                 '("super.ss"))