DOC PREVIEW
U of I CS 421 - Lecture

This preview shows page 1-2 out of 5 pages.

Save
View full document
View full document
Premium Document
Do you want full access? Go Premium and unlock all 5 pages.
Access to all documents
Download any document
Ad free experience
View full document
Premium Document
Do you want full access? Go Premium and unlock all 5 pages.
Access to all documents
Download any document
Ad free experience
Premium Document
Do you want full access? Go Premium and unlock all 5 pages.
Access to all documents
Download any document
Ad free experience

Unformatted text preview:

CS 421 – Spring 2007Lecture Notes Set 4:Introduction to OCaml - ContinuedElsa L. Gunter1Transcribed by: Pooja MathurCorresponding to Slides: 01-intro (slides 35-56)Made available: January 24, 2007Revision 1.01 Change Log1.0 Initial Release.2 More on Functions2.1 Closures (slides 35-40)It was mentioned before that functions are technically values in OCaml. But the question is, what value is recordedwhen a function is declared. Well, the answer to that is a closure. A closure is almost just the function, but that doesn’tentirely make sense. When you write a function, there are a few hanging ends. One is that you can use various,previously defined identifiers. And the way OCaml works, you want to be using the bindings that were present at thetime the function was written and not some rewrite that happened later. So, when you try to remember the function touse it, OCaml has to remember the variables and their values at the time.The next loose end is that your input argument is supposed to be taken as different than the variables used inthe body of the program. This is because you don’t want OCaml to look up the value of the argument from the oldenvironment, the value is supposed to be the new input. So now, OCaml has to remember the body of the function,the identifiers in the function and keep separate which are supposed to be previously defined and which are the inputarguments. Basically, this means a closure is comparible to a triple of sorts, where v1-v2 are the identifiers that areused in the expression exp and ρfrefers to the environment that was around when f was written.f → < (v1, ..., vn) → exp, ρf>This is the value stored by OCaml when a function is written.So, for example, recall the function plus x.#let plus x y = y + x;;Also, recall the environment at the time this function was written is as follows:ρplus x= {x → 12, ..., y → 24, ...}This will give the closure of:< y → y + x, ρplus x>So, when we use this, we want to use the inputted value for y and not the value in the environment, which is whatthe y → y + x is referring to.Now that we know how functions are stored, how do we use this information to make an evaluation of the function.This varies from language to language. First, one looks at the whole term and evaluates the outermost term. This is theside that starts with ”fun”. Then the term that is on the left is evaluated until one gets a closure. Once you get to thatpoint, you evalute your argument until it becomes a value of some kind. Then you create a new environment which is1c 2007, Share and Enjoy1the environment that is inside the closure updated with the input identifier being mapped to the value that we just gotfor the argument. Then you proceed to evaluate the body in that new environment.What this is doing is basically evaluating a function from the left most argument onwards. Recall add three x y z.This evaluation is what makes it apply the funtion to x first and then to y and then to z. However, OCaml does allowsome degree of freedom in that sometimes the order of evaluation can be left undecided. That is, whether you evaluatethe function or the argument first, means that you have a level of non-determination in your function, which in turncan lead to different values or side effects in terms of printing.So let’s look at an example with plus x:First we have the environment at the time plus x was defined.ρ = {plus x →< y → y + x, ρplus x>, ..., y → 3, } where ρplus x= {x → 12, , y → 24,Now we look at what identifiers are defined as argumentsEval (plus x y)Next we evaluate the body:Eval (app < y → y + x, ρplus x> 3)Then the input is placed into the environment:Eval (y + x) in (y → 3) + ρplus xLastly, the final evaluation is made.Eval (3 + 12) = 15We have been discussing to some degree the idea of environments of functions leading to the scope of variables.So let’s look at an example:let x = 27;;let f x =let x = 5 in(funx → print intx) 10;;f 12;;We start off by binding 27 to x. Then we define a function that takes the argument x and for the body of thefunction binds 5 to x. The expression continues by declaring another function that is then applied to 10. And we endby calling function f on 12.So what value of x is printed?Well, the x = 27 will never be used because f takes in x as an argument. And by the previous discussion on howclosures work, wo know that arguments take precedence over bindings when used in a function. The 12 used whencalling the function f is not used because once the function starts to run, the 12 is hidden by the 5. Then, the expressionin f, the fun x → print int x hides the 5 because the fun x part is saying that we have another function that is taking inx as an argument. Like the 27, the previously bound 5 is hidden. We are then left with the 10, which is then printed tothe screen after the function is finished.2.2 Curried and Uncurried Functions (slides 45-46)We know that OCaml lets you write a function that takes an argument that returns a function that takes an argumentthat returns a function, etc.What can happen now is instead of sending in multiple arguments, you can send in a more complex data structurethat can allow the function to perform its same evaluation.Recall the function add three which had a type of:val add three : int → int → int → int = <fun>The function takes an integer and returns a function that takes an integer, etc. But, how does that compare to thefunction add triple# let add triple (u,v,w) = u + v + w;;val add triple : int * int * int → int = <fun>This function takes a triple and does the same thing that add three does, except, this function has ”one” argumentwhere add three has three. add triple takes all its input at once, there doesn’t seem to be any partial application of thefunction. So, when writing functions, you have to think, which application of arguments is better for the function.2There is some terminology associated with these terms. Functions that take arguments one at a time are calledcurried. This means add three is curried. Functions that take all their input at once are called uncurried. There is afunction that you can write that can convert the a function from curried to uncurried and vice versa. This is referred toas uncurrying and currying.You can make a function out of uncurried functions that make it seem like you are doing a partial application. Youcan define a function that takes an argument, for example, and


View Full Document

U of I CS 421 - Lecture

Documents in this Course
Lecture 2

Lecture 2

12 pages

Exams

Exams

20 pages

Lecture

Lecture

32 pages

Lecture

Lecture

21 pages

Lecture

Lecture

15 pages

Lecture

Lecture

4 pages

Lecture

Lecture

68 pages

Lecture

Lecture

68 pages

Lecture

Lecture

84 pages

s

s

32 pages

Parsing

Parsing

52 pages

Lecture 2

Lecture 2

45 pages

Midterm

Midterm

13 pages

LECTURE

LECTURE

10 pages

Lecture

Lecture

39 pages

Load more
Download Lecture
Our administrator received your request to download this document. We will send you the file to your email shortly.
Loading Unlocking...
Login

Join to view Lecture and access 3M+ class-specific study document.

or
We will never post anything without your permission.
Don't have an account?
Sign Up

Join to view Lecture 2 2 and access 3M+ class-specific study document.

or

By creating an account you agree to our Privacy Policy and Terms Of Use

Already a member?