-
Notifications
You must be signed in to change notification settings - Fork 0
/
2-78.rkt
52 lines (41 loc) · 1.44 KB
/
2-78.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#lang racket
(define *op-table* (make-weak-hash))
(define (put op type proc)
(hash-set! *op-table* (list op type) proc))
(define (get op type)
(hash-ref *op-table* (list op type) #f))
(define (attach-tag type-tag contents)
(if (eq? type-tag 'scheme-number)
contents
(cons type-tag contents)))
(define (type-tag datum)
(cond [(number? datum) 'scheme-number]
[(pair? datum) (car datum)]
[else (error "Bad tagged datum -- TYPE-TAG" datum)]))
(define (contents datum)
(cond [(number? datum) datum]
[(pair? datum) (cdr datum)]
[else (error "Bad tagged datum -- CONTENTS" datum)]))
(define (apply-generic op . args)
(let ((type-tags (map type-tag args)))
(let ((proc (get op type-tags)))
(if proc
(apply proc (map contents args))
(error
"No method for these types -- APPLY-GENERIC"
(list op type-tags))))))
(define (install-scheme-number-package)
(define (tag x)
(attach-tag 'scheme-number x))
(put 'add '(scheme-number scheme-number) +)
(put 'sub '(scheme-number scheme-number) -)
(put 'mul '(scheme-number scheme-number) *)
(put 'div '(scheme-number scheme-number) /)
'done)
(install-scheme-number-package)
(define (add x y) (apply-generic 'add x y))
(define (sub x y) (apply-generic 'sub x y))
(define (mul x y) (apply-generic 'mul x y))
(define (div x y) (apply-generic 'div x y))
(define (make-scheme-number n)
((get 'make 'scheme-number) n))