A programmer can have Scheme construct a new procedure, not equivalent to any of the built-in ones, by
writing a lambda-expression. For instance, Scheme recognizes
the expression
(lambda (root) (* root root))
as a description of a procedure that, when called, squares its argument. Like any other value, this procedure can be given a name by means of a definition:
;;; square: multiply a given number by itself
;;; John David Stone
;;; Department of Mathematics and Computer Science
;;; Grinnell College
;;; stone@cs.grinnell.edu
;;; created February 13, 1999
;;; last revised March 17, 2000
;;; Given:
;;; ROOT, an exact number.
;;; Result:
;;; SQUARED, an exact number.
;;; Preconditions:
;;; None.
;;; Postcondition:
;;; SQUARED is the product of ROOT and ROOT.
(define square
(lambda (root)
(* root root)))
Such a procedure can be called, just as if it were a built-in procedure:
> (square 12)
144
A Boolean value is a datum that reflects the outcome of a single
yes-or-no test. For instance, if one were to ask Scheme to compute
whether
the empty list has five elements, it would be able to determine that it
does not, and it would signal this result by displaying the Boolean value
for ``no'' or ``false,'' which is #f. There is only one
other
Boolean value, the one meaning ``yes'' or ``true,'' which is
#t. (These are called ``Boolean values'' in honor of the
logician George
Boole, who was the first to develop a satisfactory formal theory of
them.)
A predicate is a procedure that always returns a Boolean value.
A
procedure call in which the procedure is a predicate performs some
yes-or-no test on its arguments. For instance, the predicate
number? -- the question mark is part of the name of the
procedure -- takes one argument and returns #t if that
argument is a number, #f if it does not. Similarly, the
predicate even? takes one argument, which must be an integer,
and returns #t if the integer is even and #f if
it is odd. The names of most Scheme predicates end with question marks,
and I recommend this useful convention even though it is not required by
the rules of the programming language.
Here is a selection of ``primitive'' (that is, built-in) Scheme predicates:
number? tests whether its argument is a number.symbol? tests whether its argument is a symbol.string? tests whether its argument is a string.procedure? tests whether its argument is a
procedure.list? tests whether its argument is a list.null? tests whether its argument is the empty list.boolean? tests whether its argument is a Boolean
value.eq? tests whether its two arguments are identical, in
the very narrow sense of occupying the same storage location in the
computer's memory. In practice, this is useful information only if at
least one argument is known to be a symbol or a Boolean value.eqv? tests whether its two arguments ``should normally be
regarded as the same object'' (as the language standard declares). Note,
however, that two lists can have the same elements without being
``regarded
as the same object.'' Also note that in Scheme's view the number 5, which
is ``exact,'' is not necessarily the same object as the number 5.0, which
might be an approximation.equal? tests whether its two arguments are the same or,
in the case of lists, whether they have the same contents.= tests whether its arguments, which must all be
numbers, are numerically equal; 5 and 5.0 are numerically equal for this
purpose.< tests whether its arguments, which must all be
numbers, are in strictly ascending numerical order.> tests whether its arguments, which must all be
numbers, are in strictly descending numerical order.<= tests whether its arguments, which must all be
numbers, are in ascending numerical order, allowing equality.>= tests whether its arguments, which must all be
numbers, are in descending numerical order, allowing equality.even? tests whether its argument, which must be an
integer, is even.odd? tests whether its argument, which must be an
integer, is odd.zero? tests whether its argument, which must be a
number, is equal to zero.positive? tests whether its argument, which must be a
real number, is positive.negative? tests whether its argument, which must be a
real number, is negative.
Another useful Boolean procedure is not, which takes one
argument and returns #t if the argument is #f
and
#f if the argument is anything else. For example, one can
test whether the square root of 100 is unequal to the absolute value of
-12 by giving the command
(not (= (sqrt 100) (abs -12)))
If Scheme says that the value of this expression is #t, then
the two numbers are indeed unequal.
This document is available on the World Wide Web as
http://www.cs.grinnell.edu/~gum/courses/151/readings/procedure-definitions.xhtml
created September 2, 1997
last revised August 31, 01
John David Stone (stone@cs.grinnell.edu) and Ben Gum (gum@cs.grinnell.edu)