1 Shakalmaran

Homework Section

>> [music]. So, at the end of the previous segment, I

said that was everything you needed to know about environments.

And I realize that's not entirely true. The most interesting part of your homework

assignment. The most interesting part of many

programming languages, is implementing closures.

And I want to show you how to do that. I hope you really enjoy this cause I think

it's the most interesting and mind bending part of what we do in this part of the

course. And that's that the language is going to

have first class closures. So you're going to be able to write map

and filter and call them with closures. We're going to implement lexical scope of

course, because that's the appropriate semantics.

And we need to learn how to do that. Fortunately what you have to implement, is

what we have been stressing. How closures work.

I just need to tell you a little bit about how to code them up.

And again the strategy here is I'm just going to do this in English and in power

point. It'll be your job to translate the ideas

into the racket code you're using to write your Interpreter.

So, the magic question is this. We know, thanks to lexical scope, that

when we evaluate a function body. We use the environment where the function

was defined extended to map the argument to the actual result.

So, how are we going to have that environment around?

Our interpreter only takes as an argument the current environment, it does not take

as an argument the environment where the function was defined.

So here is the trick, if you will. The lack of magic is when we define a

function, we will create a closure that includes the environment.

So later when we use that closure We have the environment stores away and we can use

it appropriately. So, when we have our language definition

we have all the structs that programmers use to write their programs.

And then we'll have 1 more, 1 that they should not use in their source programs.

You can use it for testing things out if you like.

And that's the struct closure. It has two parts.

Yes, it has the function that's going to include the argument, and the body for the

code, and all the code parts of the closure.

But then we also store the environment. So here's what happens.

A closure is a value. So like all values, if you have a closure,

your interpreter should just return it. But a function is not quite a value, we

often say that functions are values but really closures are values when you go to

interpret a function you have the current environment You have this function.

Make a closure out of both of them. So now, you return that.

And this closure carries with it, its own environment that we will use later when we

use the closure. So, that is how you interpret.

Functions. The only other thing I have to tell you is

how to interpret a function call. Right?

So now, we handled the function case of our interpreter.

Now what happens when you actually do a call?

So let's do that, and that's all there is to it.

Suppose you had something like call of expression 1 and expression 2.

So expression one should evaluate to some closure.

Expression two should evaluate to some argument.

We should call the closure with the argument.

Okay? So the first thing we need to do, like

many things where we have sub-expressions, is evaluate them.

So use the current environment to evaluate e1 to a closure.

It's an error if you don't get a closure back cause that would be trying to treat a

number as a function or something like that.

And use the current environment to evaluate e2 to a value.

Just normal recursion so far. Now, we have a closure and an argument.

What we need to do next is evaluate the closure's function's body.

Using not the current environment, but the closures environment.

The other thing that is stored in the closure.

We're going to start with that environment, then we'll extend it to map

the functions argument name To the value we have, the result of evaluating e 2.

And, the way we're going to deal with recursion on the homework assignment,

because our functions can be recursive, is we'll go ahead and further extend the

environment. For the purpose of recursion to map the

function's name to the entire closure. Not just to a function but to the entire

closure, because we still need that current environment.

So, that way. When we go to evaluate the closure's

function's body, any variables we look up, will either be the function argument.

And that will be map to the right thing, or we'll use the environment back when the

function was defined. And the only thing left is this little

work around for recursion. If inside dot functions body you want to

recursively call the function, you should use the same closure.

And so that's why we'll map the functions name for the purpose of recursion to the

entire closure. That's what you need to do, rather than

just thinking of it as, let's take what Dan said and try to code that up even

though I don't understand it, I encourage you to actually understand it.

To appreciate that this is the same semantics we learned a few weeks ago.

Back when we learned closures I told you that a closure was a pair.

Well, the struct for closure has two fields.

That's like a pair. There's the code part and there's the

environment part. And the reason why closures are not magic

is when we create a closure, we store the environment.

And then, when we use a closure, we use that environment for evaluating the

function's body. Notice that, given a closure.

That is the only environment we will ever use to evaluate that function's body with

that closure. But every time we evaluate a function

definition, a function that gets return, we create a new closure using whatever

environment was current back when we evaluated that function.

And that is the quote unquote magic of implementing high order functions.

Once you implement it in your programming language, you'll be able to use high order

functions, closures, variables that are not defined in function bodies and all the

wonderful other things we've been studying with closures in our functional

programming languages.

HOMEWORK:     click here for solutions (DO NOT look at these solutions until you have either turned in the HW, or are done working on it).

Please spend at least 2 hours a night reading the material/looking at the proofs/making sure you understand the details. Below is a tentative reading list and homework assignments. It is subject to changes depending on the amount of material covered each week. I strongly encourage you to skim the reading before class, so you are familiar with the definitions, concepts, and the statements of the material we'll cover that day.Also, you can frequently do the homework well before it is due -- you are urged to start working on the problems as soon as you can.

First Unit: Introduction (The Birthday Problem, Roulette, Basics of Probability)

  • Week 1: September 5 to 9
    • Homework: Due Thursday, September 15: (1) If you have 100 days in the year, how many people do you need in a room for there to be at least a 50% chance that two share a birthday? (2) Generalize the argument from class of 20 blocks of 5 to blocks of size 6 (I can do 10 of size 10 without too much work). Note we still have 100 spins, and each spin has a 50% chance of being red, 50% chance of being black.
    • Extra Credit: Due Thursday, September 15: Use the results from Schilling's paper to estimate how long you can play before it is very likely that you have at least one consecutive run of 5 black spins in roulette.
  • Week 2: September 12 to 16
    • Read: Chapter 1: Sections 1.1 (skip all material on odds and gambling), 1.2, 1.3, 1.4.
    • Homework: Due Tuesday, September 20: Section 1.1: Page 9: #3, #5, #7. Section 1.3: Page 30: #3, #10. Also prove if A is a subset of B then Prob(A) is at most Prob(B).
    • Extra Credit: Due Tuesday, September 20: Section 1.3: Page 30: #13, #16a.
  • Week 3: September 19 to 23
    • Read: Sections 1.4, 1.5 (just read the box on page 49 and example 3 on page 50), 1.6, 2.1, 3.1.
    • Homework: Due Tuesday, September 27: Section 1.4: #1, #3, #9. Section 1.6: #5, #6.
    • Extra Credit: Also prove or disprove that if A, B and C are pairwise inidependent then A, B and C are independent.
  • Week 4: September 26 to 30
    • Read: Sections 3.1, 3.2, 3.3, 3.4.
    • HW: Due Thursday, October 13: Section 2.1, Page 91: #2 (just the first part, not the relative frequencies), #7, #10. Section 3.1, Page 158: #3, #10, #16b (but look at #16a). Also do: If X is uniform on [-1,1], find the probability density function of Y if Y = X^2. [[HW moved back b/c TA was sick, then Mountain Day, then Fall Break.]]
  • Week 5: Oct 3 to 7 (no class on Thursday Oct 6 due to Mountain Day)
    • Read: Sections 3.2, 3.3, 3.4.
    • HW: Due Tuesday October 18: Section 3.2, Page 182: #1, #4, #7, #10, #11 (don't do the simple upper bound), #13ad. [[HW moved back b/c of Mountain Day.]]
    • Extra Credit: Section 3.2, Page 183: #13bf, #15 (econ oriented).
  • Week 6: Oct 10 to 14 (no class on Tuesday Oct 11 due to Fall Break)
    • Read: Sections 3.3, 3.4.
    • HW: Due Thursday, October 20: Page 202: #2, #3abcd, #12, #14, #27.
  • Week 7: Oct 17 to 21
    • Read: Sections 3.3, 3.4.
    • HW: Due Thursday, October 27: Section 3.4, Page 217: #1abc, #7abcd, #10abc (hard). Section 3.5, Page 234: #4 (hint: first find the probability of at least five misprints on any one page). Section 4.4, Page 310: #9a.
  • Week 8: Oct 24 to 28
    • Read: Chapters 13 and 14, including sum of Poisson Random Variables.
    • Homework: Midterm due Tuesday, November 1st at the start of class, so no written HW.
  • Week 9: Oct 31 to Nov 4: No class on Thursday due to power outage, use as extra time for the exam
  • Week 10: November 7 to 11: No class on Friday because of (Optional) Midterm II
    • Read: ChiSquare chapter of my book (notes provided in class) and the Method of Least Squares notes.
    • Least squares handout for the lecture.
    • Homework: Due Thursday, November 17: Section 5.3: #3a. Also do (1) Calculate the probability a chi-square distribution with 2 degrees of freedom is at least twice as large as its mean (so if the mean is mu, we want the probability it is 2mu or greater). Problems from my handout on Method of Least Squares notes: Page 9, #3.3, Page 10, #3.9.
    • Optional midterm is due at the start of class on Tuesday, November 15.
  • Week 11: November 14 to 18:
    • Read: ChiSquare chapter of my book (notes provided in class)
    • Homework: Due Thursday, November 17: Section 5.3: #3a. Also do (1) Calculate the probability a chi-square distribution with 2 degrees of freedom is at least twice as large as its mean (so if the mean is mu, we want the probability it is 2mu or greater). Problems from my handout on Method of Least Squares notes: Page 9, #3.3, Page 10, #3.9.

    Do the first few final exam problems by the start of class on Friday, December 2nd; no class on Thursday to have extra time.

Leave a Comment


Your email address will not be published. Required fields are marked *