[previous] [up] [next]     [index]
Next: Intermezzo 1 Syntax and Semantics Up: The Varieties of Data Previous: Extended Exercise: Moving Shapes

Input Errors

Recall our first function:

;; area-of-disk : number -> number
;; to compute the area of a disk with radius r 
(define (area-of-disk r) 
  (* 3.14 (* r r))) 
Clearly, our friends may wish to use this function, especially for some of their geometry homework. Unfortunately, when our friends use this function, they may accidentally apply it to a symbol rather than a number. When that happens, the function stops with a whimsical and uninformative error message:
> (area-of-disk 'my-disk)
*: expects type <number> as 1st argument, given: 'my-disk; ...  
Using predicates, we can do better.

To prevent this kind of accident, we should define checked versions of our functions, when we wish to hand them to our friends. In general, a CHECKED FUNCTION inputs an arbitrary Scheme value: a number, a boolean, a symbol, or a structure. For all those values that are in the class of values for which the original function is defined, the checked version applies the latter; for all others, it signals an error. Concretely, checked-area-of-disk consumes an arbitrary Scheme value, uses area-of-disk to compute the area of the a disk if the input is a number, and stops with an error message otherwise.

Based on the enumeration of Scheme's classes of values, the template for a checked function is as follows:

;; f : Scheme-value -> ???
(define (f v) 
  (cond 
    [(number? v) ...] 
    [(boolean? v) ...] 
    [(symbol? v) ...] 
    [(struct? v) ...])) 
Each line corresponds to one possible class of input. If we need to distinguish between the structures, we expand the last line appropriately.

The first clause is the only one where we can use area-of-disk. For the others, however, we must signal an error. In Scheme we use the operation error to do so. It consumes a symbol and a string. Here is an example:

(error 'checked-area-of-disk ``number expected'')

Hence the full definition of checked-area-of-disk is:

(define (checked-area-of-disk v)
  (cond 
    [(number? v) (area-of-disk v)] 
    [(boolean? v) (error 'checked-area-of-disk ``number expected'')] 
    [(symbol? v) (error 'checked-area-of-disk ``number expected'')] 
    [(struct? v) (error 'checked-area-of-disk ``number expected'')])) 
Using else we can greatly simplify the function:
;; checked-area-of-disk : Scheme-value -> number
;; to compute the area of a disk with radius v,  
;; if v is a number 
(define (checked-area-of-disk v) 
  (cond 
    [(number? v) (area-of-disk v)] 
    [else (error 'checked-area-of-disk ``number expected'')])) 
Of course, such a simplification may not always be possible and may require a reordering of the cond-clauses first.

Writing checked functions and simplifying them is important if we distribute the programs to others. Designing programs that work properly, however, is far more important. The book therefore focuses on the design process for the program proper and deemphasizes writing checked versions.


Exercises

Exercise 7.5.1

A checked version of area-of-disk can also enforce that the arguments to the function are positive numbers, not just arbitrary numbers. Modify checked-area-of-disk in this way. Solution

Exercise 7.5.2

Develop checked versions of the functions profit (figure [cross-reference]), is-between-5-6? (section [cross-reference]), reply (section [cross-reference]), distance-to-0 (section [cross-reference]), and perimeter (in the left column of figure [cross-reference]). Solution

Exercise 7.5.3

Take a look at these structure and data definitions:

(define-struct vec (x y))

A speed-vector (vec) is a structure:

(make-vec x y) where both x and y are positive numbers.

Develop the function checked-make-vec, which should be understood as a checked version of the primitive operation make-vec. It ensures that the arguments to make-vec are positive numbers, and not just arbitrary numbers. In other words, checked-make-vec enforces our informal data definition. Solution



[previous] [up] [next]     [index]
Next: Intermezzo 1 Syntax and Semantics Up: The Varieties of Data Previous: Extended Exercise: Moving Shapes

PLT