DOC PREVIEW
UMD CMSC 330 - Relationships between Functional, Imperative, and Object-Oriented Programming

This preview shows page 1-2-3 out of 8 pages.

Save
View full document
View full document
Premium Document
Do you want full access? Go Premium and unlock all 8 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 8 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 8 pages.
Access to all documents
Download any document
Ad free experience
Premium Document
Do you want full access? Go Premium and unlock all 8 pages.
Access to all documents
Download any document
Ad free experience

Unformatted text preview:

CMSC 330: Organization of Programming Languages Relationships between Functional, Imperative, and Object-Oriented Programming CMSC 330 2 OCaml Language Choices •! Implicit or explicit declarations? –! Explicit – variables must be introduced with let before use –! But you don’t need to specify types •! Static or dynamic types? –! Static – but you don’t need to state types –! OCaml does type inference to figure out types for you –! Good: less work to write programs –! Bad: easier to make mistakes, harder to find errors So Far, only Functional Programming •! We haven’t given you any way so far to change something in memory in OCaml –! All you can do is create new values from old •! This actually makes programming easier ! –! Don’t care whether data is shared in memory •! Aliasing is irrelevant –! Provides strong support for compositional reasoning and abstraction •! Ex: Calling a function f with argument x always produces the same result CMSC 330 3 What about Imperative Programming? •! In C or Java, we’re used to doing things like: –! Can we model this without imperative constructs? •! Imperative = able to change values in memory CMSC 330 4 int x = 3; int y = 4; void foo(void) { x = 42; y = x + 2; } int bar(void) { return x + y; }Idea: “Thread” State through Fns CMSC 330 5 type state = (char * int) list let read (s:state) (x:char):int = List.assoc x s let write (s:state) (x:char) (i:int):state = let s’ = List.remove_assoc s x in (x,i)::s’ let foo (s0:state):state = (* could change to state*unit *) let s1 = write s0 ‘x’ 42 in let s2 = write s1 ‘y’ ((read s1 ‘x’) + 2) in s2 let bar (s0:state):(state*int) = (s0, (read s0 ‘x’) + (read s0 ‘y’)) This Can Actually be a Good Idea •! The Haskell language is purely functional –! No way to write to memory, ever •! But, you can play the trick we just saw –! In Haskell, something that behaves like the state type is a monad –! Used for a bunch of different things •! And there’s some interesting theory to go with it •! OCaml is only mostly functional –! It does actually have imperative constructs CMSC 330 6 CMSC 330 7 Imperative OCaml •! There are three basic operations on memory: –! ref : 'a -> 'a ref •! Allocate an updatable reference –! ! : 'a ref -> 'a •! Read the value stored in reference –! := : 'a ref -> 'a -> unit •! Write to a reference let x = ref 3 (* x : int ref *) let y = !x x := 4 CMSC 330 8 Comparison to L- and R-values •! Recall that in C/C++/Java, there’s a strong distinction between l- and r-values –! An r-value refers to just a value, like an integer –! An l-value refers to a location that can be written •! A variable's meaning depends on where it appears –! On the right-hand side, it’s an r-value, and it refers to the contents of the variable –! On the left-hand side of an assignment, it’s an l-value, and it refers to the location the variable is stored in y = x; l-value r-valueCMSC 330 9 L-Values and R-Values (cont’d) •! Notice that x, y, and 3 all have type int int x, y; x = 3; y = x; 3 = x; Store 3 in location x Read contents of x and store in location y Makes no sense CMSC 330 10 Comparison to OCaml •! In OCaml, an updatable location and the contents of the location have different types –! The location has a ref type int x, y; x = 3; y = x; 3 = x; let x = ref 0;; let y = ref 0;; x := 3;; (* x : int ref *) y := (!x);; 3 := x;; (* 3 : int; error *) CMSC 330 11 Capturing a ref in a Closure •! We can use refs to make things like counters that produce a fresh number “everywhere” let next = let count = ref 0 in function () -> let temp = !count in count := (!count) + 1; temp;; # next ();; -! : int = 0 # next ();; -! : int = 1 CMSC 330 12 Semicolon Revisited; Side Effects •! Now that we can update memory, we have a real use for ; and () : unit –! e1; e2 means evaluate e1, throw away the result, and then evaluate e2, and return the value of e2 –! () means “no interesting result here” –! It’s only interesting to throw away values or use () if computation does something besides return a result •! A side effect is a visible state change –! Modifying memory –! Printing to output –! Writing to diskCMSC 330 13 Grouping with begin...end •! If you’re not sure about the scoping rules, use begin...end to group together statements with semicolons let x = ref 0 let f () = begin print_string "hello"; x := (!x) + 1 end CMSC 330 14 The Trade-Off of Side Effects •! Side effects are absolutely necessary –! That’s usually why we run software! We want something to happen that we can observe •! They also make reasoning harder –! Order of evaluation now matters –! Calling the same function in different places may produce different results –! Aliasing is an issue •! If we call a function with refs r1 and r2, it might do strange things if r1 and r2 are aliased Object-Oriented Languages •! We’ve seen how we could model state without imperative features •! What about object-oriented constructs? –! Can we encode them? CMSC 330 15 CMSC 330 16 The Stack Class class Stack<Typ> { class Entry { Typ elt; Entry next; Entry(Typ e, Entry n) { elt = e; next = n; } }; private Entry theStack; void push(Typ e) { theStack = new Entry(e, theStack); } Typ pop() { if (theStack == null) throw new NoSuchElementException(); Typ temp = theStack.elt; theStack = theStack.next; return temp; } }CMSC 330 17 Writing a “Stack” in OCaml: Take 1 module type STACK = sig type 'a stack val new_stack : unit -> 'a stack val push : 'a stack -> 'a -> unit val pop : 'a stack -> 'a end module Stack : STACK = struct type 'a stack = 'a list ref let new_stack () = ref [] let push s x = s := (x::!s) let pop s = match !s with [] -> failwith "Empty stack" | (h::t) -> s := t; h end CMSC 330 18 Writing a “Stack” in OCaml: Take 2 let new_stack () = let this = ref [] in let push x = this := (x::!this) in let pop () = match !this with [] -> failwith "Empty stack" | (h::t) -> this := t; h in (push, pop) # let s = new_stack ();; val s : ('_a -> unit) * (unit -> '_a) = (<fun>, <fun>) # fst s 3;; - : unit = () …


View Full Document

UMD CMSC 330 - Relationships between Functional, Imperative, and Object-Oriented Programming

Documents in this Course
Exam #1

Exam #1

6 pages

Quiz #1

Quiz #1

2 pages

Midterm 2

Midterm 2

12 pages

Exam #2

Exam #2

7 pages

Ocaml

Ocaml

7 pages

Parsing

Parsing

38 pages

Threads

Threads

12 pages

Ruby

Ruby

7 pages

Quiz #3

Quiz #3

2 pages

Threads

Threads

7 pages

Quiz #4

Quiz #4

2 pages

Exam #2

Exam #2

6 pages

Exam #1

Exam #1

6 pages

Threads

Threads

34 pages

Quiz #4

Quiz #4

2 pages

Threads

Threads

26 pages

Exam #2

Exam #2

9 pages

Exam #2

Exam #2

6 pages

Load more
Download Relationships between Functional, Imperative, and Object-Oriented Programming
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 Relationships between Functional, Imperative, and Object-Oriented Programming 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 Relationships between Functional, Imperative, and Object-Oriented Programming 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?