Here is a simple function that tests some condition about a number:
;; is-5? : number -> boolean ;; to determine whether n is equal to 5 (define (is-5? n) (= n 5))The function produces true if, and only if, its input is equal to 5. Its contract contains one novel element: the word boolean. Just like number, boolean represents a class of values that is built into Scheme. Unlike number, boolean consists of just two values: true and false.
Here is a slightly more interesting function with a boolean output:
;; is-between-5-6? : number -> boolean ;; to determine whether n is between 5 and 6 (exclusive) (define (is-between-5-6? n) (and (< 5 n) (< n 6)))It consumes a number and produces true if the number is between, but does not include, 5 and 6. One good way to understand the function is to say that it describes the following interval on the number line:
Interval Boundaries: An interval boundary marked with ``('' or ``)'' is excluded from the interval; an interval boundary marked with ``['' or ``]'' is included.
The following third function from numbers to boolean values represents the most complicated form of interval:
;; is-between-5-6-or-over-10? : number -> boolean ;; to determine whether n is between 5 and 6 (exclusive) ;; or larger than or equal to 10 (define (is-between-5-6-or-over-10? n) (or (is-between-5-6? n) (>= n 10)))The function returns true for two portions of the number line:
The left part of the interval is the portion between, but not including, 5 and 6; the right one is the infinite line starting at, and including, 10. Any point on those two portions of the line satisfies the condition expressed in the function is-between-5-6-or-over-10?.
All three functions test numeric conditions. To design or to comprehend such functions, we must understand intervals and combinations (also known as unions) of intervals. The following exercises practice this important skill.
Exercise 4.2.1
Translate the following five intervals on the real line into Scheme functions that accept a number and return true if the number is in the interval and false if it is outside:
Exercise 4.2.2
Translate the following three Scheme functions into intervals on the line of reals:
1. (define (in-interval-1? x)
(and (< -3 x) (< x 0)))
2. (define (in-interval-2? x)
(or (< x 1) (> x 2)))
3. (define (in-interval-3? x)
(not (and (<= 1 x) (<= x 5))))
Also formulate contracts and purpose statements for the four functions.
Evaluate the following expressions by hand:
Exercise 4.2.3
Mathematical equations in one variable are claims about an unknown number. For example, the quadratic equation
is a claim concerning some unknown number x. For x = -1, the claim holds:
For x = 1, it doesn't, because
and 4 is not equal to 0. A number for which the claim holds is called a solution to the equation.
We can use Scheme to formulate equational conditions as a function. If someone then claims to have a solution, we can use the function to test whether the proposed solution is, in fact, a solution. Our running example corresponds to the function
;; equation1 : number -> boolean ;; to determine whether x is a solution forWhen we apply equation1 to some number, we get true or false:(define (equation1 x) (= (+ (* x x) (+ (* 2 x) 1)) 0))
(equation1 -1) = trueand
(equation1 +1) = false
Translate the following equations into Scheme functions:
Exercise 4.2.4
Equations are not only ubiquitous in mathematics, they are also heavily
used in programming. We have used equations to state what a function should
do with examples, we have used them to evaluate expressions by hand, and we
have added them as test cases to the Definitions
window. For example,
if our goal is to define Fahrenheit->Celsius, we might have
added our examples as test cases as follows:
;; test expression: (Fahrenheit->Celsius 32) ;; expected result: 0and
;; test expression: (Fahrenheit->Celsius 212) ;; expected result: 100After clicking the Execute button we can compare the numbers to the left and right of =. If they are equal, we know our function works.
As our results become more and more complex, comparing values becomes more and more tedious. Using =, we can instead translate these equations into claims:
(= (Fahrenheit->Celsius 32) 0)and
(= (Fahrenheit->Celsius 212) 100)Now, if all claims evaluate to true, we know that our function works for the specified examples. If we see a false anywhere, something is still wrong.
Reformulate the test cases for exercises
,
,
, and
as claims.
Testing: Writing tests as claims is good practice, though we need
to know more about equality to develop good automatic tests. To do so, we
resume the discussion of equality and testing in
section
. Solution