[previous] [up] [next]     [index]
Next: Lexical Scope and Block Up: Organizing Programs with local Previous: Pragmatics of localPart

Pragmatics of local, Part 3

Consider the following function definition:

;; mult10 : list-of-digits -> list-of-numbers
;; to create a list of numbers by multiplying each digit on alod  
;; by (expt 10 p) where p is the number of digits that follow 
(define (mult10 alod) 
  (cond 
    [(empty? alod) 0] 
    [else (cons (* (expt 10 (length (rest alod))) (first alod)) 
                (mult10 (rest alod)))])) 
Here is a test:
(equal? (mult10 (list 1 2 3)) (list 100 20 3))
Clearly, the function could be used to convert a list of digits into a number.

A small problem with the definition of mult10 is the computation of the first item of the result in the second clause. It is a large expression and doesn't quite correspond to the purpose statement. By using a local-expression in the second clause, we can introduce names for some intermediate values in the computation of the answer:

;; mult10 : list-of-digits -> list-of-numbers
;; to create a list of numbers by multiplying each digit on alod  
;; by (expt 10 p) where p is the number of digits that follow 
(define (mult10 alon) 
  (cond 
    [(empty? alon) empty] 
    [else (local ((define a-digit (first alon)) 
                  (define p (length (rest alon)))) 
            ;; --------------------------- 
            (cons (* (expt 10 p) a-digit) (mult10 (rest alon))))])) 
The use of names helps us understand the expression when we read the definition again because we can study one local-definition at a time.

The use of local for such cases is most appropriate when a value is computed twice as, for example, the expression (rest alon) in mult10. By introducing names for repeated expressions, we might also avoid some (small) effort on DrScheme's side:

(define (mult10 alon)
  (cond 
    [(empty? alon) empty] 
    [else (local ((define a-digit (first alon)) 
                  (define the-rest (rest alon)) 
                  (define p (length the-rest))) 
            ;; --------------------------- 
            (cons (* (expt 10 p) a-digit) (mult10 the-rest)))])) 

For the programs that we have developed, this third usage of local is hardly ever useful. An auxiliary function is almost always better. We will, however, encounter many different styles of functions in the remaining parts of the book and with them the opportunity, and sometimes the necessity, to use local-expressions like the one for mult10.


Exercises

Exercise 18.1.15

Consider the following function definition:

;; extract1 : inventory -> inventory
;; to create an inventory from an-inv for all 
;; those items that cost less than $1 
(define (extract1 an-inv) 
  (cond 
    [(empty? an-inv) empty] 
    [else (cond 
            [(<= (ir-price (first an-inv)) 1.00) 
             (cons (first an-inv) (extract1 (rest an-inv)))] 
            [else (extract1 (rest an-inv))])])) 
Both clauses in the nested cond-expression extract the first item from an-inv and both compute (extract1 (rest an-inv)).

Introduce a local-expression for these expressions. Solution



[previous] [up] [next]     [index]
Next: Lexical Scope and Block Up: Organizing Programs with local Previous: Pragmatics of localPart

PLT