Consider the following expression:
(make-posn 'Albert 'Meyer)It constructs a posn structure from two symbols. If we now apply distance-to-0 to this structure, the computation fails miserably:
(distance-to-0 (make-posn 'Albert 'Meyer))That is, it requires us to multiply 'Albert with itself. Similarly,= (sqrt (+ (sqr (posn-x (make-posn 'Albert 'Meyer))) (sqr (posn-y (make-posn 'Albert 'Meyer)))))
= (sqrt (+ (sqr 'Albert) (sqr (posn-y (make-posn 'Albert 'Meyer)))))
= (sqrt (+ (* 'Albert 'Albert) (sqr (posn-y (make-posn 'Albert 'Meyer)))))
(make-star 'Albert 'Meyer 10000 'electric-organ)does not produce a star structure according to our intentions. In particular, the structure is not suitable for processing by increment-sales.
To avoid such problems and to assist with the development of functions, we
must add a data definition to each structure
definition.
A DATA DEFINITION
states, in a mixture of English and Scheme, how we intend to use
a class of structures and how we construct elements of this class of
data. For example, here is a data definition for posn structures:
A posn is a structure:
(make-posn x y) where x and y are numbers.
It says that a valid posn structure always contains two numbers, and nothing else. Hence, when we use make-posn to create a posn structure, we must apply it to two numbers; when a function contains selector expressions for posn structures, we may now assume that their result is a number.
The data definition for star structures is only slightly more complicated:
A star is a structure:
(make-star last first instrument sales) where last, first, and instrument are symbols and sales is a number.
This data definition says that valid star structures contain symbols in the fields for last name, first name, and instrument, and a number in the sales field.
In general, a data definition identifies a subclass of Scheme's universe of
values: see figure
. As we have seen so far, Scheme's
universe contains numbers, symbols, images, strings, chars, booleans, and
many different classes of structures. Our functions, however, are intended
to work only for a subclass of values. For example, area-of-disk
consumes only numbers; reply from section
consumes
only symbols. A few subclasses, such as number, already have
names, because they are useful for all kinds of programming tasks. Others
are only interesting in the context of a specific problem. For those
cases, a programmer should introduce a data definition.
The most important role of a data definition is that of a covenant between
programmers and users. We expect both groups to respect such data
definitions, and we expect the programmer to exploit it for the function
construction. For example, when the programmer of distance-to-0
specifies that all posns contain two numbers, a user must always
apply distance-to-0 to a posn structure with two
numbers. Furthermore, as we will discuss over the next few sections, we
expect a programmer to exploit data definitions for function
developments. Naturally, a data definition in English and Scheme does not
prevent us from abusing make-posn. It is, however, a written
statement of intent, and a person who willingly violates or ignores this
covenant must face the consequences of ill-behaving
computations.
Exercise 6.4.1
Provide data definitions for the following structure definitions:
Exercise 6.4.2
Provide a structure definition and a data definition for representing points in time since midnight. A point in time consists of three numbers: hours, minutes, and seconds. Solution
Exercise 6.4.3
Provide a structure definition and a data definition for representing
three-letter words. A word consists of letters, which we
represent with the symbols 'a through
'z. Solution