-
Notifications
You must be signed in to change notification settings - Fork 4
/
sidequest19.1-template.rkt
219 lines (171 loc) · 7.13 KB
/
sidequest19.1-template.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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
;
; CS1101S --- Programming Methodology
;
; Sidequest 19.1
;
; Note that written answers are commented out to allow us to run your
; code easily while grading your problem set.
;;;;;;;;;;;;;;;;;;;;;;;;;
; START SUPPORTING CODE ;
;;;;;;;;;;;;;;;;;;;;;;;;;
;true if message matches is-x? for some x
(define (is-x? message)
(let* ((str (symbol->string message))
(len (string-length str))
(left (if (> len 2) (substring str 0 3)))
(right (if (> len 0) (substring str (- len 1) len))))
(and (equal? left "is-")
(equal? right "?"))))
;resolve m on x
;use this to dispatch unknown methods
;on classes which implement multiple inheritance
(define (mro x m full-message)
(define (helper parents)
(if (eq? parents '()) ;root class
(apply x full-message)
(let* ((immediate (map car parents))
(immediate-methods (map (lambda (x) (list x (x 'methods))) immediate))
(immediate-supports (map (lambda (x) (list (car x) (pair? (member m (cadr x))))) immediate-methods))
(all-supports (filter cadr immediate-supports)))
(if (pair? all-supports)
(apply (caar all-supports) full-message)
(helper (filter pair? (map cadr parents)))
))))
(helper (filter pair? (x 'parents))))
(define (make-object . child)
(define (self . message)
(case (car message)
((is-object?) #t)
((parents) '())
((methods) '(is-object?))
(else (if (is-x? (car message))
#f
(list 'no-method-found (car message))))))
(define true-self (if (null? child) self (car child)))
self)
(define (make-named-object name . child)
(define (self . message)
(case (car message)
((is-named-object?) #t)
((parents) (list parent (parent 'parents)))
((methods) '(name))
((name) (if (null? (cdr message))
name
(set! name (cadr message))))
(else (apply parent message))))
(define true-self (if (null? child) self (car child)))
(define parent (make-object true-self))
self)
(define (make-person name . child)
(let ((partner #f))
(define (self . message)
(case (car message)
((is-person?) #t)
((parents) (list parent (parent 'parents)))
((methods) '(talk join-partner partner))
((talk) (if partner
(display (string-append
(true-self 'name)
" says: Hi, I am " (true-self 'name) " and I am partnered with " (partner 'name) "!\n"))
(display (string-append (true-self 'name) " says: Hi, I am " (true-self 'name) "!\n"))))
((join-partner)
(cond (partner (display (string-append (true-self 'name) " exclaims: I am already partnered!\n")))
((not ((cadr message) 'is-person? )) (display
(string-append
(true-self 'name)
" exclaims: That is not a person! I can't partner with it!\n")))
(else
(let* ((potential-partner (cadr message))
(check ((cadr message) 'partner)))
(cond ((eq? check #t) (set! partner potential-partner))
((not check) (begin (set! partner #t)
(potential-partner 'join-partner true-self)
(set! partner potential-partner)))
(else (display (string-append (true-self 'name) " exclaims: "
(potential-partner 'name) " is already partnered!\n"))))))))
((partner) partner)
(else (apply parent message))))
(define true-self (if (null? child) self (car child)))
(define parent (make-named-object name true-self))
self))
(define (make-JFDI-warrior name . child)
(define (self . message)
(case (car message)
((is-JFDI-warrior?) #t)
((parents) (list parent (parent 'parents)))
((methods) '(is-JFDI-warrior? swing))
((swing) (display (string-append (true-self 'name) " swings lightsaber!\n")))
(else (apply parent message))))
(define true-self (if (null? child) self (car child)))
(define parent (make-person name true-self))
self)
(define (make-SITH-lord name SITH-name . child)
(define (self . message)
(case (car message)
((is-SITH-lord?) #t)
((parents) (list parent (parent 'parents)))
((methods) '(is-SITH-lord? SITH-name talk))
((SITH-name) (if (null? (cdr message))
SITH-name
(set! SITH-name (cadr message))))
((talk) (begin
(apply parent message)
(display (string-append
(true-self 'name)
" says: Make that Lord "
(true-self 'SITH-name)
", muahahaha...\n"))))
(else (apply parent message))))
(define true-self (if (null? child) self (car child)))
(define parent (make-person name true-self))
self)
(define (make-traitor JFDI-name SITH-name . child)
(define (self . message)
(case (car message)
((is-traitor?) #t)
((parents) (list (list parent1 (parent1 'parents)) (list parent2 (parent2 'parents))))
((methods) '(is-traitor))
(else (if (is-x? (car message))
(or (apply parent1 message) (apply parent2 message))
(mro self (car message) message))))) ;use mro on a class that uses multiple inheritance
(define true-self (if (null? child) self (car child)))
(define parent1 (make-JFDI-warrior JFDI-name true-self))
(define parent2 (make-SITH-lord JFDI-name SITH-name true-self))
self)
;;;;;;;;;;;;;;;;;;;;;;;;;
; END SUPPORTING CODE ;
;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;
; Count Dooku Example ;
;;;;;;;;;;;;;;;;;;;;;;;
(define dooku (make-traitor "Dooku" "Tyranus"))
(dooku 'is-JFDI-warrior?)
; #t
(dooku 'is-SITH-lord?)
; #t
(dooku 'is-traitor?)
; #t
(dooku 'swing)
; dooku swings lightsaber!
(dooku 'talk) ; error here - why didn't he mention that he is Lord Tyranus?
; dooku says: Hi, I am Dooku!
;;;;;;;;;;
; Task 1 ;
;;;;;;;;;;
;I will use a list to denote ties; for eg 1,(2,3),4 means that the order can be 1,2,3,4 or 1,3,2,4
;Junwei's search order: G,E,F,(B,D),(C,A)
;Joe's search order: F,E,D,B,C,A
;pros/cons: Joe's method is easier to code, requiring each class to mantain only a list of parent:distance
;pairs while Junwei's method requires breadth-first search.
;the current method is basically dfs which sucks.
;;;;;;;;;;
; Task 2 ;
;;;;;;;;;;
;I think Junwei's method is more intuitive because in his method creating indirection (inheritance)
;between the superclass implementing the function you want to use and the root class doesn't
;affect the method resolution order since the distance from the superclass to the child class is
;the same while in Joe's method it does affect.
;;;;;;;;;;
; Task 3 ;
;;;;;;;;;;
;;; Implement the method