読者です 読者をやめる 読者になる 読者になる

計算機プログラムの構造と解釈 第二版 P109 問題2.75

make-from-mag-angをメッセージパッシングの流儀で実装する。


P102のAlyssaの複素数の手続きと
P109のmake-from-real-imagを参考にすれば割とあっさりと解くことができます。


#!/usr/local/bin/gosh
;; -*- coding: utf-8 -*-

(use ggc.debug.trace)
(use math.mt-random)


(define nil '())
(define nl newline)
(define disp display)
(define (square x)
  (* x x)) 


(define (make-from-real-imag x y)
  (define (dispatch op) 
    (cond ((eq? op 'real-part) x)
          ((eq? op 'imag-part) y)
          ((eq? op 'magnitude)
           (sqrt (+ (square x) (square y))))
          ((eq? op 'angle) (atan y x)) 
          (else
            (error "Unknown op -- MAKE-FROM-REAL-IMAG" op))))
  dispatch)


(define (apply-generic op arg)
  (arg op))


(define (make-from-mag-ang x y)
  (define (dispatch op) 
    (cond ((eq? op 'real-part) 
           (* x (cos y)))
          ((eq? op 'imag-part) 
           (* x (sin y)))
          ((eq? op 'magnitude) x)
          ((eq? op 'angle) y)
          (else
            (error "Unknown op -- MAKE-FROM-MAG-ANG" op))))
  dispatch)

(define z1
  (make-from-real-imag 2 1))

(define z2
  (make-from-mag-ang (sqrt 2) (/ 3.14 4)))


;; main
(define (main args)

  (disp "(apply-generic 'real-part z1): ")
  (disp (apply-generic 'real-part z1))
  (nl)
  (disp "(apply-generic 'imag-part z1): ")
  (disp (apply-generic 'imag-part z1))
  (nl)
  (disp "(apply-generic 'magnitude z1): ")
  (disp (apply-generic 'magnitude z1))
  (nl)
  (disp "(apply-generic 'angle z1): ")
  (disp (apply-generic 'angle z1))
  (nl)
  (nl)

  ;;apply-genericの中でやってること
  (disp "(z1 'real-part): ")
  (disp (z1 'real-part))
  (nl)
  (disp "(z1 'imag-part): ")
  (disp (z1 'imag-part))
  (nl)
  (disp "(z1 'magnitude): ")
  (disp (z1 'magnitude))
  (nl)
  (disp "(z1 'angle): ")
  (disp (z1 'angle))
  (nl)
  (nl)

  ;;apply-genericの中でやってること
  (disp "(z2 'real-part): ")
  (disp (z2 'real-part))
  (nl)
  (disp "(z2 'imag-part): ")
  (disp (z2 'imag-part))
  (nl)
  (disp "(z2 'magnitude): ")
  (disp (z2 'magnitude))
  (nl)
  (disp "(z2 'angle): ")
  (disp (z2 'angle))
  (nl)

  0)


実行

(apply-generic 'real-part z1): 2
(apply-generic 'imag-part z1): 1
(apply-generic 'magnitude z1): 2.23606797749979
(apply-generic 'angle z1): 0.4636476090008061

(z1 'real-part): 2
(z1 'imag-part): 1
(z1 'magnitude): 2.23606797749979
(z1 'angle): 0.4636476090008061

(z2 'real-part): 1.0003980841198834
(z2 'imag-part): 0.9996017573460277
(z2 'magnitude): 1.4142135623730951
(z2 'angle): 0.785

オブジェクト指向ですか。