SICP 全笔记

Exercise 2.74. Insatiable Enterprises, Inc., is a highly decentralized conglomerate company consisting of a large number of independent divisions located all over the world. The company’s computer facilities have just been interconnected by means of a clever network-interfacing scheme that makes the entire network appear to any user to be a single computer. Insatiable’s president, in her first attempt to exploit the ability of the network to extract administrative information from division files, is dismayed to discover that, although all the division files have been implemented as data structures in Scheme, the particular data structure used varies from division to division. A meeting of division managers is hastily called to search for a strategy to integrate the files that will satisfy headquarters’ needs while preserving the existing autonomy of the divisions.

Show how such a strategy can be implemented with data-directed programming. As an example, suppose that each division’s personnel records consist of a single file, which contains a set of records keyed on employees’ names. The structure of the set varies from division to division. Furthermore, each employee’s record is itself a set (structured differently from division to division) that contains information keyed under identifiers such as address and salary. In particular:

a. Implement for headquarters a get-record procedure that retrieves a specified employee’s record from a specified personnel file. The procedure should be applicable to any division’s file. Explain how the individual divisions’ files should be structured. In particular, what type information must be supplied?

b. Implement for headquarters a get-salary procedure that returns the salary information from a given employee’s record from any division’s personnel file. How should the record be structured in order to make this operation work?

c. Implement for headquarters a find-employee-record procedure. This should search all the divisions’ files for the record of a given employee and return the record. Assume that this procedure takes as arguments an employee’s name and a list of all the divisions’ files.

d. When Insatiable takes over a new company, what changes must be made in order to incorporate the new personnel information into the central system?

往简单了说,现在有 N 个部门,每个部门的人事部的文件结构却不一样(但题目中说,是 scheme 的数据结构)。比如

A 部门的人事信息的结构

(("John" . ((salary . 1) (street . "Drive St.") (id . 12339))),
 ("Joe"  . (...)))

B 部分的人事信息的结构

("Krihm" . ((monthly-salary . 1) (address . "Long St.") (id-number . 192)))

get-record 过程

这里每个部门都应该提供一个过程,这个过程可以得到每一条人事记录中的姓名的信息,并且我们需要知道,这个人名是 string 还是 symbol

(define (get-record name records)
  (cond ((null? records) #f)
        ((string=? (car (car records)) name)
         (car records))
        (else
         (get-record (cadr records) name))))

; structure:
; record = ((item1 . "item1") (his-salary . "item2")...)
;
; (get-salary 'his-salary record)

get-salary

文件的组织结构应该类似如下:

(("name" . ((item1 . "item1") (his-salary . "item2")...))
 ("name2" . ((item1 . "item1")...)))

我们的 get-salary 就可以如下实现

(define (get-salary key record)
  (cond ((null? record) #f)
        ((eq? key (car (car record))) (cdr (car record)))
        (else
         (get-salary key (cdr record)))))

find-employee-record

我们可以借用之前实现的 get-record 来实现

(define (find-employee-record name record-files)
  (cond ((null? record-files) '())
        (else
         (let ((record (get-record name (car record-files))))
           (if record
               (cons record (find-employee-record name (cdr record-files)))
               (find-employee-record name (cdr record-files)))))))