Structure and Interpretation of Computer Programs



Yüklə 2,71 Mb.
Pdf görüntüsü
səhifə25/222
tarix08.08.2018
ölçüsü2,71 Mb.
#61085
1   ...   21   22   23   24   25   26   27   28   ...   222

the basis of a technique for constructing ‘‘unbreakable codes’’ suggested by Rivest, Shamir, and 

Adleman (1977). The resulting RSA algorithm has become a widely used technique for enhancing the

security of electronic communications. Because of this and related developments, the study of prime

numbers, once considered the epitome of a topic in ‘‘pure’’ mathematics to be studied only for its own

sake, now turns out to have important practical applications to cryptography, electronic funds transfer,

and information retrieval. 

[Go to first, previous, next page;   contents;   index]



[Go to first, previous, next page;   contents;   index]

1.3  Formulating Abstractions with Higher-Order Procedures

We have seen that procedures are, in effect, abstractions that describe compound operations on

numbers independent of the particular numbers. For example, when we

(define (cube x) (* x x x))

we are not talking about the cube of a particular number, but rather about a method for obtaining the

cube of any number. Of course we could get along without ever defining this procedure, by always

writing expressions such as

(* 3 3 3)

(* x x x)

(* y y y)        

and never mentioning 

cube


 explicitly. This would place us at a serious disadvantage, forcing us to

work always at the level of the particular operations that happen to be primitives in the language

(multiplication, in this case) rather than in terms of higher-level operations. Our programs would be

able to compute cubes, but our language would lack the ability to express the concept of cubing. One

of the things we should demand from a powerful programming language is the ability to build

abstractions by assigning names to common patterns and then to work in terms of the abstractions

directly. Procedures provide this ability. This is why all but the most primitive programming

languages include mechanisms for defining procedures.

Yet even in numerical processing we will be severely limited in our ability to create abstractions if we

are restricted to procedures whose parameters must be numbers. Often the same programming pattern

will be used with a number of different procedures. To express such patterns as concepts, we will need

to construct procedures that can accept procedures as arguments or return procedures as values.

Procedures that manipulate procedures are called higher-order procedures. This section shows how

higher-order procedures can serve as powerful abstraction mechanisms, vastly increasing the

expressive power of our language.

1.3.1  Procedures as Arguments

Consider the following three procedures. The first computes the sum of the integers from 

a

 through 



b

:

(define (sum-integers a b)



  (if (> a b)

      0


      (+ a (sum-integers (+ a 1) b))))

The second computes the sum of the cubes of the integers in the given range:

(define (sum-cubes a b)

  (if (> a b)

      0

      (+ (cube a) (sum-cubes (+ a 1) b))))




The third computes the sum of a sequence of terms in the series 

which converges to   /8 (very slowly):

49

(define (pi-sum a b)



  (if (> a b)

      0


      (+ (/ 1.0 (* a (+ a 2))) (pi-sum (+ a 4) b))))

These three procedures clearly share a common underlying pattern. They are for the most part

identical, differing only in the name of the procedure, the function of 

a

 used to compute the term to be



added, and the function that provides the next value of 

a

. We could generate each of the procedures by



filling in slots in the same template:

(define (<name> a b)

  (if (> a b)

      0


      (+ (<term> a)

         (<name> (<next> a) b))))

The presence of such a common pattern is strong evidence that there is a useful abstraction waiting to

be brought to the surface. Indeed, mathematicians long ago identified the abstraction of summation of



a series and invented ‘‘sigma notation,’’ for example

to express this concept. The power of sigma notation is that it allows mathematicians to deal with the

concept of summation itself rather than only with particular sums -- for example, to formulate general

results about sums that are independent of the particular series being summed.

Similarly, as program designers, we would like our language to be powerful enough so that we can

write a procedure that expresses the concept of summation itself rather than only procedures that

compute particular sums. We can do so readily in our procedural language by taking the common

template shown above and transforming the ‘‘slots’’ into formal parameters:

(define (sum term a next b)

  (if (> a b)

      0

      (+ (term a)



         (sum term (next a) next b))))

Notice that 

sum

 takes as its arguments the lower and upper bounds 



a

 and 


b

 together with the

procedures 

term


 and 

next


. We can use 

sum


 just as we would any procedure. For example, we can

use it (along with a procedure 

inc

 that increments its argument by 1) to define 



sum-cubes

:

(define (inc n) (+ n 1))



(define (sum-cubes a b)

  (sum cube a inc b))




Yüklə 2,71 Mb.

Dostları ilə paylaş:
1   ...   21   22   23   24   25   26   27   28   ...   222




Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©genderi.org 2024
rəhbərliyinə müraciət

    Ana səhifə