1 Welcome to PLT Scheme
2 Scheme Essentials
3 Built-In Datatypes
4 Expressions and Definitions
5 Programmer-Defined Datatypes
6 Modules
7 Contracts
8 Input and Output
9 Regular Expressions
10 Exceptions and Control
11 Iterations and Comprehensions
12 Pattern Matching
13 Classes and Objects
14 Units (Components)
15 Reflection and Dynamic Evaluation
16 Macros
17 Performance
18 Running and Creating Executables
19 Compilation and Configuration
20 More Libraries
Bibliography
Index
On this page:
4.3.1 Evaluation Order and Arity
4.3.2 Keyword Arguments
4.3.3 The apply Function
Version: 4.0.2

 

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