A procedure's arity is the number of arguments it takes.
For instance, the arity of the
cons procedure is 2 and the
arity of the predicate
char-uppercase? is 1. You'll probably
have noticed that while some of Scheme's built-in procedures always take
the same number of arguments others have variable arity -- that
is, they can take any number of arguments. All one can say about the
arity of some procedures -- such as
string-append -- is that it is some non-negative integer.
Still other Scheme procedures, such as
display, require at least a certain number of arguments, but
will accept one or more additional arguments if they are provided. For
example, the arity of
2 or more, and the arity of
1 or 2. These procedures, too, are said to
have variable arity, because their arity varies from one call to another.
All of the procedures you've written so far have had a fixed arity. Is
it possible to define your own new new variable-arity procedures in Scheme?
Yes! You can create variable-arity procedures by using alternate forms of
The simplest variant takes the following form
(lambda args body)
In all of the programmer-defined procedures that we have seen so far, the
lambda has been followed by a list of parameters --
names for the values that will be supplied by the caller when the procedure
is invoked. If, instead, what follows
lambda is a single
identifier -- not a list, but a simple identifier that is not enclosed in
parentheses -- then the procedure denoted by the
lambda-expression will accept any number of arguments, and the
lambda will name a list of all the
arguments supplied in the call.
Here's a simple example: We'll define a
procedure that takes any number of arguments and prints out each one (by
display procedure to it), then terminates the
output line (by invoking
newline). Note that in the
lambda-expression, the identifier
denotes a list of all the items to be printed:
;;; Procedure: ;;; display-line ;;; Parameters: ;;; val1 ... valn, 0 or more values. ;;; Purpose: ;;; Displays the strings terminated by a carriage return. ;;; Produces: ;;; [Nothing] ;;; Preconditions: ;;; 0 or more values given as parameters. ;;; Postconditions: ;;; All of the values have been displayed. ;;; The output is now at the beginning of a new line. (define display-line (lambda arguments (let kernel ((rest arguments)) (if (null? rest) (newline) (begin (display (car rest)) (kernel (cdr rest)))))))
display-line is invoked, however, the caller does not
assemble the items to be printed into a list, but just supplies them as
> (display-line "+--" "Here is a string!" "--+")
+--Here is a string!--+> (display-line "ratio = " 35/15) ratio = 7/3
If the programmer wishes to require some fixed minimum number of arguments
while permitting (but not requiring) additional ones, she can use yet
another form of the
lambda-expression, in which a dot is
placed between the last two identifiers in the parameter list. This form
looks like the following
(lambda (arg1 arg2 ... argn . remaining-args) body)
All the identifiers to the left of this dot correspond to required arguments. The identifier to the right of the dot designates the list of all of the remaining arguments, the ones that are optional.
For instance, we can define a procedure called
display-separated-line that always takes at least one
separator, but may take any number of additional
Display-separated-line will print out each of the
additional arguments (by invoking
display) and terminate the
line, just as
display-line does, but with the difference that
a copy of
separator will be displayed between any two of the
remaining values. Here is some sample output:
> (display-separated-line "..." "going" "going" "gone")
going...going...gone> (display-separated-line ":-" 5 4 3 2 1 'done) 5:-4:-3:-2:-1:-done> (display-separated-line #\space "+--" "Here is a string!" "--+") +-- Here is a string! --+> (display-separated-line (integer->char 9) 1997 'foo 'wombat 'quux) 1997 foo wombat quux; (integer->char 9) is the tab character.
And here is the definition of the procedure:
;;; Procedure: ;;; display-separated-line ;;; Parameters: ;;; separator, a string ;;; val1 ... valn, 0 or more additional values. ;;; Purpose: ;;; Displays the values separated by the separator and followed ;;; by a carriage return. ;;; Preconditions: ;;; The separator is a string. ;;; Postconditions: ;;; All the values have been displayed. ;;; The output is now at the beginning of a new line. (define display-separated-line (lambda (separator . arguments) (if (null? arguments) (newline) (let kernel ((rest arguments)) (display (car rest)) (if (null? (cdr rest)) (newline) (begin (display separator) (kernel (cdr rest))))))))
The dot notation can be used to specify any number of initial values. Thus, a parameter list of the form
(first-value second-value . remaining-values)
indicates that the first two arguments are required, while additional
arguments will be collected into a list named
Some Unknown Date [John Stone and/or Henry Walker]
Fall 2000 [Samuel A. Rebelsky]
Sunday, 8 April 2001 [Samuel A. Rebelsky]
Tuesday, 12 November 2002 [Samuel A. Rebelsky]
Tuesday, 4 February 2003 [Samuel A. Rebelsky]
I usually create these pages
on the fly, which means that I rarely
proofread them and they may contain bad grammar and incorrect details.
It also means that I tend to update them regularly (see the history for
more details). Feel free to contact me with any suggestions for changes.
This document was generated by
Siteweaver on Fri May 7 09:44:43 2004.
The source to the document was last modified on Wed Jan 21 09:41:33 2004.
This document may be found at