Код Ревью

Сравни свои решения

    #| BEGIN (Введите свое решение) |#
(define (=number? exp num)
  (and (number? exp) (= exp num)))

(define (make-sum a1 a2)
  (cond ((=number? a1 0) a2)
        ((=number? a2 0) a1)
        ((and (number? a1) (number? a2)) (+ a1 a2))
        (else (list '+ a1 a2))))

(define (make-product m1 m2)
  (cond ((or (=number? m1 0) (=number? m2 0)) 0)
        ((=number? m1 1) m2)
        ((=number? m2 1) m1)
        ((and (number? m1) (number? m2)) (* m1 m2))
        (else (list '* m1 m2))))

(define (make-exponentiation base exponent)
  (list '** base exponent))

;; а. 
;; 1 потому что числа и переменные — это примитивные типы данных, они не имеют оператора (operator exp на них неприменим).
;; 2 Они — атомы, не списки.
;; 3 У них нет структуры вида (операция . операнды), и значит подход "оператор + таблица процедур" к ним неприменим.
;; 4 Поэтому они обрабатываются отдельно через cond.

;; б.
;; Производная суммы
(define (deriv-sum operands var)
  (make-sum (deriv (car operands) var)
            (deriv (cadr operands) var)))

;; Производная произведения
(define (deriv-product operands var)
  (make-sum
    (make-product (car operands)
                  (deriv (cadr operands) var))
    (make-product (deriv (car operands) var)
                  (cadr operands))))

;; (put 'deriv '+ deriv-sum)
;; (put 'deriv '* deriv-product)

;; в.
(define (deriv-expt operands var)
  (let ((base (car operands))
        (exponent (cadr operands)))
    (make-product
     exponent
     (make-product
      (make-exponentiation base
                           (make-sum exponent -1))
      (deriv base var)))))

;; (put 'deriv '** deriv-expt)

;; д.
;; (get 'deriv (operator exp)) (operands exp) var
;; но это лишнее, правильное использование уже в функции deriv
;; Так что строчку ((get (operator exp) 'deriv) (operands exp) var) — можно вообще убрать.

;; Пакеты

(define (install-sum-package)
  (define (addend operands) (car operands))
  (define (augend operands) (cadr operands))
  
  (define (make-sum a1 a2)
    (cond ((=number? a1 0) a2)
          ((=number? a2 0) a1)
          ((and (number? a1) (number? a2)) (+ a1 a2))
          (else (list '+ a1 a2))))
  
  (define (=number? exp num)
    (and (number? exp) (= exp num)))
  
  (define (deriv-sum operands var)
    (make-sum (deriv (addend operands) var)
              (deriv (augend operands) var)))
  
  (put 'deriv '+ deriv-sum)
  'done)

(define (install-product-package)
  (define (multiplier operands) (car operands))
  (define (multiplicand operands) (cadr operands))
  
  (define (make-product m1 m2)
    (cond ((or (=number? m1 0) (=number? m2 0)) 0)
          ((=number? m1 1) m2)
          ((=number? m2 1) m1)
          ((and (number? m1) (number? m2)) (* m1 m2))
          (else (list '* m1 m2))))
  
  (define (=number? exp num)
    (and (number? exp) (= exp num)))
  
  (define (deriv-product operands var)
    (make-sum
     (make-product (multiplier operands)
                   (deriv (multiplicand operands) var))
     (make-product (deriv (multiplier operands) var)
                   (multiplicand operands))))
  
  (put 'deriv '* deriv-product)
  'done)

#| END |#