Skip to content

Commit 5a6db84

Browse files
committed
Draft of midterm
1 parent 85a0878 commit 5a6db84

1 file changed

Lines changed: 163 additions & 68 deletions

File tree

www/midterms/2.scrbl

Lines changed: 163 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
@title{Midterm 2}
77

8-
@bold{Due: TBD}
8+
@bold{Due: Friday, November 13th 11:59PM}
99

1010
@(define repo "TBD")
1111

@@ -14,10 +14,10 @@ Midterm repository:
1414

1515
The repository contains a single markdown file @tt{m2.md}, which you can edit
1616
to submit your answers to the following questions. Your submission must be
17-
pushed by 9pm on Saturday (unless you have already arranged otherwise).
17+
pushed by 11:59pm on Friday (unless you have already arranged otherwise).
1818

19-
During the 60 hours of the exam period, you may only ask private
20-
questions on Piazza if you need assistance for the course staff. You
19+
During the 72 hours of the exam period, you may only ask private
20+
questions on Discord if you need assistance for the course staff. You
2121
may not communicate or collaborate with any one else about the content
2222
of this exam.
2323

@@ -33,17 +33,17 @@ equivalent to each of the following:
3333

3434
@itemlist[
3535

36-
@item{@verbatim{'((10) y y z 2)}}
36+
@item{@verbatim{'(y y z (5) 2)}}
3737

38-
@item{@verbatim{'((2) . 2)}}
38+
@item{@verbatim{'((1 2) . 2)}}
3939

4040
@item{@verbatim{'(a . (b . (c)))}}
4141

42-
@item{@verbatim{'(quote (x 2))}}
42+
@item{@verbatim{'(a . (b . c))}}
4343

44-
@item{@verbatim{`(1 . ,(add1 2))}}
44+
@item{@verbatim{`(,(add1 1) . 2)}}
4545

46-
@item{@verbatim|{`(1 ,@'(2 3) ,@'(x))}|}
46+
@item{@verbatim|{`(,@'(1 2) ,@'(x) ,3)}|}
4747
]
4848

4949
For example, @racket['(1 2 3)] is equivalent to @racket[(cons 1 (cons 2 (cons 3 '())))].
@@ -52,30 +52,30 @@ For example, @racket['(1 2 3)] is equivalent to @racket[(cons 1 (cons 2 (cons 3
5252

5353
[10 points]
5454

55-
Will the following program run forever using only a constant amount of
56-
memory, or will it eventually consume all memory and crash? Briefly
57-
justify your answer.
55+
Is it possible for the following program to run out of memory? Justify your
56+
answer.
5857

5958
@#reader scribble/comment-reader
6059
(racketblock
61-
(begin (define (flip x)
62-
(flop (add1 x)))
63-
(define (flop y)
64-
(flip (sub1 y)))
65-
(flip 5))
60+
(define (fact x)
61+
(if (<= x 1)
62+
1
63+
(* x (sub1 x))))
6664
)
6765

6866
How about this one? Again, justify your answer.
6967

7068
@#reader scribble/comment-reader
7169
(racketblock
72-
(begin (define (flip x)
73-
(flip (flop (add1 x))))
74-
(define (flop y)
75-
(flop (flip (sub1 y))))
76-
(flip 5))
70+
(define (fact x)
71+
(define (fact-prime acc i)
72+
(if (<= i 1)
73+
acc
74+
(fact-prime (* acc i) (sub1 i))))
75+
(fact-prime 1 x))
7776
)
7877

78+
Hint: consider Jig.
7979

8080
@bold{Question 3}
8181

@@ -86,13 +86,15 @@ position?
8686

8787
@itemlist[
8888

89-
@item{@verbatim{(if e0 e1 e2)}}
89+
@item{@verbatim{(if (if a0 a1 a2) e1 e2)}}
9090

9191
@item{@verbatim{(match e0 [p1 e1] [p2 e2])}}
9292

93-
@item{@verbatim{((λ (x y) e0) e1 e2)}}
93+
@item{@verbatim{(if e0 (if a0 a1 a2) e2)}}
9494

95-
@item{@verbatim{(eq? e0 e1)}}
95+
@item{@verbatim{(add1 e0)}}
96+
97+
@item{@verbatim{(cons e0 e1)}}
9698

9799
]
98100

@@ -121,7 +123,7 @@ Here's an example (note: @racket[let] is used for sequencing here):
121123
]
122124

123125
Implement the following function in the compiler. (You may assume
124-
this code will be added to the Loot compiler and may use any functions
126+
this code will be added to the Knock compiler and may use any functions
125127
given to you.)
126128

127129
@#reader scribble/comment-reader
@@ -131,82 +133,175 @@ given to you.)
131133
(define (compile-set-box! e0 e1 c) ...)
132134
)
133135

134-
@section[#:tag-prefix "m2"]{Closure Conversion}
136+
@section[#:tag-prefix "m2"]{Program Transformation: Inlining}
135137

136138
@bold{Question 5}
137139

138140
[20 points]
139141

140142

141-
In our @secref["Loot"] compiler we used Closure Conversion to
142-
help us implement higher-order functions on a target language
143-
that does not support higher-order functions natively (x86_64).
143+
In our @secref["Iniquity"] compiler we introduced function definitions to help
144+
us organize our code. Function definitions came along with function @emph{calls},
145+
and unfortunately function calls come with a performance hit.
146+
147+
One solution is @emph{inlining}: Taking the body of a funtion definition and
148+
replacing a call to that function with an instance of its body. This allows the
149+
programmer to have all the benefits of the function abstraction, without the
150+
overhead.
144151

145-
This was done by introducing an appropriate data structure
146-
for storing the environment and accessing the stored environment
147-
when necessary.
152+
For example, consider the following program:
148153

149-
Now imagine that our target was not x86_64, but a dialect of Racket
150-
that did not have higher-order functions. We could still perform
151-
closure conversion!
154+
@#reader scribble/comment-reader
155+
(racketblock
156+
(begin
157+
(define (f x) (+ x 5))
158+
(+ 10 (f 42)))
159+
)
152160

153-
For example, the following application of a constant function:
161+
If you inlined @tt{f}, the result would be the following program:
154162

155163
@#reader scribble/comment-reader
156164
(racketblock
157-
(let ((x 5)) ((lambda (y) x) 10))
165+
(begin
166+
(define (f x) (+ x 5))
167+
(+ 10 (+ 42 5)))
158168
)
159169

160-
Using the same definitions for @tt{lookup} and @tt{ext} first introduced in
161-
@secref["Fraud"], could be transformed to the following:
170+
171+
Your task is to write and document a function named @tt{inline} which takes a
172+
function @tt{f} and a program @tt{p}, and inlines the function @tt{f} @emph{at
173+
all uses of @tt{f} in the program} (this includes other function definitions!).
174+
162175

163176
@#reader scribble/comment-reader
164177
(racketblock
178+
(define (inline f p)
179+
;TODO
180+
)
181+
)
182+
165183

166-
(define (lam1 env y)
167-
(lookup env 'x))
184+
You can assume that you have a function @tt{fvs} that given an expression,
185+
returns a list of all the free variables in that expression. This is be
186+
necessary to avoid creating incorrect programs (see Example 2 below). If dealing
187+
with variable clashes and creating new names seems too complicated, you can
188+
assume the existence of a function @tt{barendregtify} which given a program
189+
makes sure that all variables are unique, running it on the following:
168190

169-
(let ((x 5)) (lam1 (ext '() 'x x) 10))
191+
192+
@#reader scribble/comment-reader
193+
(racketblock
194+
(begin
195+
(define (f x) (+ x 5))
196+
(define (g x) (+ x 10))
197+
(f (g 10)))
170198
)
171199

172-
Perform closure conversion on the following higher-order program:
200+
Would produce something like:
201+
173202

174203
@#reader scribble/comment-reader
175204
(racketblock
176-
(let ((x 10)
177-
(y 20)
178-
(z 30))
179-
((lambda (z) (+ x ((lambda (x) (+ x y)) y) z)) 1))
205+
(begin
206+
(define (f var1) (+ var1 5))
207+
(define (g var2) (+ var2 10))
208+
(f (g 10)))
180209
)
181210

182-
You may assume @tt{lookup} and @tt{ext} exist.
183211

184-
In order to receive full marks, show the steps of your transformation.
212+
In addition to your code, make sure you answer the following question as part of your
213+
submission:
214+
215+
@itemlist[
185216

186-
Clarification: I've completely removed @tt{map} as it was only essential to the
187-
extra credit below. To get full marks you must closure convert both of the
188-
lambdas that are present in the program above.
217+
@item{Recursive functions refer to themselves... What should you do? (You do
218+
not have to worry about mutual recursion between sets of functions, for this
219+
exam we will assume either a function refers to itself directly, or it is not
220+
recusive at all).}
189221

222+
]
190223

191-
@bold{Question 5 Extra Credit}
224+
Other things you should consider:
192225

193-
[10 points]
226+
@itemlist[
227+
228+
@item{If @tt{f} does not exist in the program, the program should be unchanged}
194229

195-
Apply the full defunctionalization transformation introduced in @secref["Loot"]
196-
to the following code:
230+
@item{You have to be careful with variable shadowing/capture (see Example 2).}
231+
232+
]
233+
234+
235+
236+
@subsection{Example 1}
197237

198238
@#reader scribble/comment-reader
199239
(racketblock
200-
(define (map f xs)
201-
(match xs
202-
['() '()]
203-
[(cons y ys) (cons (f y) (map f ys))]))
204-
205-
(define (main)
206-
(let ((x 10)
207-
(y 20)
208-
(z 30))
209-
(map (lambda (z) (+ x ((lambda (x) (+ x y)) y) z)) '(1 2 3))))
240+
;todo
210241
)
211242

212-
You can reuse whatever you feel is appropriate, if anything, from Question 5.
243+
Would be unchanged.
244+
245+
@subsection{Example 2}
246+
247+
@#reader scribble/comment-reader
248+
(racketblock
249+
;todo
250+
)
251+
252+
Becomes:
253+
254+
@#reader scribble/comment-reader
255+
(racketblock
256+
;todo
257+
)
258+
259+
@subsection{Example 3}
260+
261+
Don't forget about nested expressions!
262+
263+
@#reader scribble/comment-reader
264+
(racketblock
265+
;todo
266+
)
267+
268+
Becomes:
269+
270+
@#reader scribble/comment-reader
271+
(racketblock
272+
;todo
273+
)
274+
275+
@bold{Question 5 Extra Credit}
276+
277+
[10 points]
278+
279+
Provide two graphs in dot format (explained in our lecture on Graphviz/Dot)
280+
that shows the difference between interpreters and compilers. You can lay this
281+
out however you'd like, but the following items should definitely be present in
282+
one, or both, of the graphs (though not necessarily connected in the diagram!).
283+
These are in alphabetical order, so don't assume that their order reveals
284+
anything about how the diagram should be layed out.
285+
286+
@itemlist[
287+
288+
@item{Source Language}
289+
@item{Target Language}
290+
@item{AST}
291+
@item{Code-Gen}
292+
@item{CPU Execution}
293+
@item{Interp}
294+
@item{Parser}
295+
@item{RTS}
296+
@item{Source Language}
297+
@item{Target Language}
298+
@item{Value/Result}
299+
300+
]
301+
302+
In order to get the points for this, we will take your description in dot and
303+
run @tt{dot} on it. If it does not produce an output, you will get not points.
304+
305+
If it produces an output that is a good-faith effort (i.e. there is a clear
306+
attempt and showing the difference between compilers and interpreters, you will
307+
get 5 points. If it accurately shows the difference you will get 10 points.

0 commit comments

Comments
 (0)