2.1.1 Example: Arithmetic Operations for Rational Numbers

Printer-friendly versionPrinter-friendly version

Suppose we want to do arithmetic with rational numbers. We want to be able to add, subtract, multiply, and divide them and to test whether two rational numbers are equal.

Let us begin by assuming that we already have a way of constructing a rational number from a numerator and a denominator. We also assume that, given a rational number, we have a way of extracting (or selecting) its numerator and its denominator. Let us further assume that the constructor and selectors are available as procedures:

  • (make-rat <n> <d>) returns the rational number whose numerator is the integer <n> and whose denominator is the integer <d>.
  • (numer <x>) returns the numerator of the rational number <x>.
  • (denom <x>) returns the denominator of the rational number <x>.

We are using here a powerful strategy of synthesis: wishful thinking. We haven’t yet said how a rational number is represented, or how the procedures numer, denom, and make-rat should be implemented. Even so, if we did have these three procedures, we could then add, subtract, multiply, divide, and test equality by using the following relations:

We can express these rules as procedures:

(define (add-rat x y)
  (make-rat (+ (* (numer x) (denom y))
               (* (numer y) (denom x)))
            (* (denom x) (denom y))))
(define (sub-rat x y)
  (make-rat (- (* (numer x) (denom y))
               (* (numer y) (denom x)))
            (* (denom x) (denom y))))
(define (mul-rat x y)
  (make-rat (* (numer x) (numer y))
            (* (denom x) (denom y))))
(define (div-rat x y)
  (make-rat (* (numer x) (denom y))
            (* (denom x) (numer y))))
(define (equal-rat? x y)
  (= (* (numer x) (denom y))
     (* (numer y) (denom x))))

Now we have the operations on rational numbers defined in terms of the selector and constructor procedures numer, denom, and make-rat. But we haven’t yet defined these. What we need is some way to glue together a numerator and a denominator to form a rational number.

Pairs

To enable us to implement the concrete level of our data abstraction, our language provides a compound structure called a pair, which can be constructed with the primitive procedure cons. This procedure takes two arguments and returns a compound data object that contains the two arguments as parts. Given a pair, we can extract the parts using the primitive procedures car and cdr.[2] Thus, we can use cons, car, and cdr as follows:

(define x (cons 1 2))

(car x)
1

(cdr x)
2

Notice that a pair is a data object that can be given a name and manipulated, just like a primitive data object. Moreover, cons can be used to form pairs whose elements are pairs, and so on:

(define x (cons 1 2))

(define y (cons 3 4))

(define z (cons x y))

(car (car z))
1

(car (cdr z))
3

In section 2.2 we will see how this ability to combine pairs means that pairs can be used as general-purpose building blocks to create all sorts of complex data structures. The single compound-data primitive pair, implemented by the procedures cons, car, and cdr, is the only glue we need. Data objects constructed from pairs are called list-structured data.

Representing rational numbers

Pairs offer a natural way to complete the rational-number system. Simply represent a rational number as a pair of two integers: a numerator and a denominator. Then make-rat, numer, and denom are readily implemented as follows:[3]

(define (make-rat n d) (cons n d))

(define (numer x) (car x))

(define (denom x) (cdr x))

Also, in order to display the results of our computations, we can print rational numbers by printing the numerator, a slash, and the denominator:[4]

(define (print-rat x)
  (newline)
  (display (numer x))
  (display "/")
  (display (denom x)))

Now we can try our rational-number procedures:

(define one-half (make-rat 1 2))

(print-rat one-half)
1/2

(define one-third (make-rat 1 3))
(print-rat (add-rat one-half one-third))
5/6

(print-rat (mul-rat one-half one-third))
1/6

(print-rat (add-rat one-third one-third))
6/9

As the final example shows, our rational-number implementation does not reduce rational numbers to lowest terms. We can remedy this by changing make-rat. If we have a gcd procedure like the one in section 1.2.5 that produces the greatest common divisor of two integers, we can use gcd to reduce the numerator and the denominator to lowest terms before constructing the pair:

(define (make-rat n d)
  (let ((g (gcd n d)))
    (cons (/ n g) (/ d g))))

Now we have

(print-rat (add-rat one-third one-third))
2/3

as desired. This modification was accomplished by changing the constructor make-rat without changing any of the procedures (such as add-rat and mul-rat) that implement the actual operations.

[2] The name cons stands for “construct.” The names car and cdr derive from the original implementation of Lisp on the IBM 704. That machine had an addressing scheme that allowed one to reference the “address” and “decrement” parts of a memory location. Car stands for “Contents of Address part of Register” and cdr (pronounced “could-er”) stands for “Contents of Decrement part of Register.” [back]
[3]

Another way to define the selectors and constructor is

(define make-rat cons)
(define numer car)
(define denom cdr)

The first definition associates the name make-rat with the value of the expression cons, which is the primitive procedure that constructs pairs. Thus make-rat and cons are names for the same primitive constructor.

Defining selectors and constructors in this way is efficient: Instead of make-rat calling cons, make-rat is cons, so there is only one procedure called, not two, when make-rat is called. On the other hand, doing this defeats debugging aids that trace procedure calls or put breakpoints on procedure calls: You may want to watch make-rat being called, but you certainly don’t want to watch every call to cons.

We have chosen not to use this style of definition in this book.[back]

[4] Display is the Scheme primitive for printing data. The Scheme primitive newline starts a new line for printing. Neither of these procedures returns a useful value, so in the uses of print-rat below, we show only what print-rat prints, not what the interpreter prints as the value returned by print-rat. [back]

Exercises

Exercise 2.1

Define a better version of make-rat that handles both positive and negative arguments. Make-rat should normalize the sign so that if the rational number is positive, both the numerator and denominator are positive, and if the rational number is negative, only the numerator is negative.

Comments

Clojure equivalent for cons/car/cdr here

(cons 1 2) doesn’t work in Clojure; you get:

Don't know how to create ISeq from: java.lang.Integer
[Thrown class java.lang.IllegalArgumentException]

In Scheme, “a chain of pairs not ending in the empty list is called an improper list. Note that an improper list is not a list. ”

(cons 'a 3) => (a . 3)

To do the exercises in Clojure, one can use

(def x (list 1 2))
(first x)
(last x)

dress karen millen

The Appealing Dress is Karen Millen for Superstars

Karen Millen Dress disigers are dedicated to shape the womens line grace, especially this Karen Millen Tribal crochet Dress, that really help you actually hot and lovely. The celebrities are her free speaking on another’s behalf that saw the engaging dress is Karen Millen! None people will ingore your grace no matter where you’re using this leading-edge and eye-catching karen millen outlet.

While a large number of women thronged to fashion world-famous Ladies Day, their counterparts attended what’s fast-becoming its popular Welsh equivalent at Ffos Las in Carmarthenshire, the first new all-purpose racecourse in Britain for 81 years.

People to the event cheered on champion jockey Tony McCoy with an evening that marked the 2nd anniversary from the opening of the racecourse. Fashion tycoon Kevin Stanford made a fortune by selling his be part of Karen Millen, the womenswear chain he co-founded.She gave high praise to Karen Millen Dress.

Since my son Jimmy was born in 2008 year, I can no longer wear tight-fitting Karen Millen dresses, the Karen Millen Dress lauched a brand new Tribal crochet dress,this really is fit me perfectly. This dress allow me to look the sunshine in Dark space. and I am thinking of buying another cheap karen millen dress out of this site again.
ebay karen millen outlet

aItGaKyDIJyyV

Why does this have to be the ONLY rleibale source? Oh well, gj!

Post new comment