CMSC 330: Organization of Programming Languages. OCaml Imperative Programming

Similar documents
CMSC 330: Organization of Programming Languages. OCaml Imperative Programming

OCaml Data CMSC 330: Organization of Programming Languages. User Defined Types. Variation: Shapes in Java

Mutable Data Types. Prof. Clarkson Fall A New Despair Mutability Strikes Back Return of Imperative Programming

OCaml Language Choices CMSC 330: Organization of Programming Languages

CMSC 330: Organization of Programming Languages. Functional Programming with Lists

CMSC 330: Organization of Programming Languages. Functional Programming with Lists

Dialects of ML. CMSC 330: Organization of Programming Languages. Dialects of ML (cont.) Features of ML. Functional Languages. Features of ML (cont.

CMSC 330: Organization of Programming Languages. OCaml Expressions and Functions

Programming Languages and Techniques (CIS120)

CMSC 330: Organization of Programming Languages. Lets, Tuples, Records

CMSC 330: Organization of Programming Languages. OCaml Higher Order Functions

CMSC 330: Organization of Programming Languages. Formal Semantics of a Prog. Lang. Specifying Syntax, Semantics

CSCI-GA Scripting Languages

CMSC 330: Organization of Programming Languages. OCaml Higher Order Functions

CMSC 330: Organization of Programming Languages. OCaml Higher Order Functions

Background. CMSC 330: Organization of Programming Languages. Useful Information on OCaml language. Dialects of ML. ML (Meta Language) Standard ML

CS1622. Semantic Analysis. The Compiler So Far. Lecture 15 Semantic Analysis. How to build symbol tables How to use them to find

Topics Covered Thus Far CMSC 330: Organization of Programming Languages

Ruby: Introduction, Basics

CMSC 430 Introduction to Compilers. Fall Everything (else) you always wanted to know about OCaml (but were afraid to ask)

Some Advanced ML Features

QUIZ. What is wrong with this code that uses default arguments?

Mutation. COS 326 David Walker Princeton University

CMSC 330: Organization of Programming Languages

Introduction to OCaml

CSE413: Programming Languages and Implementation Racket structs Implementing languages with interpreters Implementing closures

CS 11 Ocaml track: lecture 3

CSCI 2041: Functions, Mutation, and Arrays

Closures. Mooly Sagiv. Michael Clarkson, Cornell CS 3110 Data Structures and Functional Programming

Tail Calls. CMSC 330: Organization of Programming Languages. Tail Recursion. Tail Recursion (cont d) Names and Binding. Tail Recursion (cont d)

CS558 Programming Languages

Control Structures. Lecture 4 COP 3014 Fall September 18, 2017

OCaml. ML Flow. Complex types: Lists. Complex types: Lists. The PL for the discerning hacker. All elements must have same type.

CMSC 330: Organization of Programming Languages

Tuples. CMSC 330: Organization of Programming Languages. Examples With Tuples. Another Example

CMSC 631. Functional Programming with OCaml

Begin at the beginning

G Programming Languages - Fall 2012

Closures. Mooly Sagiv. Michael Clarkson, Cornell CS 3110 Data Structures and Functional Programming

Datatype declarations

G Programming Languages Spring 2010 Lecture 4. Robert Grimm, New York University

CS Lectures 2-3. Introduction to OCaml. Polyvios Pratikakis

CMSC 330: Organization of Programming Languages. OCaml Data Types

CSE341: Programming Languages Lecture 9 Function-Closure Idioms. Dan Grossman Winter 2013

Functional programming Primer I

CS558 Programming Languages

COL728 Minor2 Exam Compiler Design Sem II, Answer all 5 questions Max. Marks: 20

CMSC330 Fall 2016 Midterm #1 2:00pm/3:30pm

Chapter 13: Reference. Why reference Typing Evaluation Store Typings Safety Notes

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

Mini-ML. CS 502 Lecture 2 8/28/08

CSCI 2041: Basic OCaml Syntax and Features

Mutable References. Chapter 1

CMSC 330: Organization of Programming Languages

1007 Imperative Programming Part II

Side note: Tail Recursion. Begin at the beginning. Side note: Tail Recursion. Base Types. Base Type: int. Base Type: int

Lists. Prof. Clarkson Fall Today s music: "Blank Space" by Taylor Swift

Tail Recursion: Factorial. Begin at the beginning. How does it execute? Tail recursion. Tail recursive factorial. Tail recursive factorial

Reasoning About Imperative Programs. COS 441 Slides 10

A Functional Evaluation Model

Mutation. COS 326 Andrew W. Appel Princeton University. slides copyright David Walker and Andrew W. Appel

Ruby: Introduction, Basics

Semantic Analysis. Outline. The role of semantic analysis in a compiler. Scope. Types. Where we are. The Compiler Front-End

Recap. Recap. If-then-else expressions. If-then-else expressions. If-then-else expressions. If-then-else expressions

CS131 Typed Lambda Calculus Worksheet Due Thursday, April 19th

G Programming Languages - Fall 2012

These are notes for the third lecture; if statements and loops.

L3 Programming September 19, OCaml Cheatsheet

Lecture 16: Static Semantics Overview 1

Programming Languages

CS558 Programming Languages. Winter 2013 Lecture 3

Control Flow. COMS W1007 Introduction to Computer Science. Christopher Conway 3 June 2003

CSE341: Programming Languages Lecture 9 Function-Closure Idioms. Dan Grossman Fall 2011

CMSC330. Objects, Functional Programming, and lambda calculus

CS Lecture 7: The dynamic environment. Prof. Clarkson Spring Today s music: Down to Earth by Peter Gabriel from the WALL-E soundtrack

CS 314 Principles of Programming Languages

Topics Covered Thus Far. CMSC 330: Organization of Programming Languages. Language Features Covered Thus Far. Programming Languages Revisited

Lecture 2: SML Basics

CS558 Programming Languages

CS 320: Concepts of Programming Languages

CS558 Programming Languages

Scope and Introduction to Functional Languages. Review and Finish Scoping. Announcements. Assignment 3 due Thu at 11:55pm. Website has SML resources

Programming Languages

CMSC 330: Organization of Programming Languages. Lambda Calculus

CMSC 330: Organization of Programming Languages

The role of semantic analysis in a compiler

Haske k ll An introduction to Functional functional programming using Haskell Purely Lazy Example: QuickSort in Java Example: QuickSort in Haskell

Recap: Functions as first-class values

Introduction to Haskell

CITS 3242 Programming Paradigms Part II. Topic 10: Imperative Programming

Formal Specification and Verification

An introduction introduction to functional functional programming programming using usin Haskell

Programming Languages Third Edition. Chapter 7 Basic Semantics

CS 11 Haskell track: lecture 1

Lecture 15 CIS 341: COMPILERS

Types and Type Inference

Variables and Bindings

CS152: Programming Languages. Lecture 11 STLC Extensions and Related Topics. Dan Grossman Spring 2011

Programming Language Features. CMSC 330: Organization of Programming Languages. Turing Completeness. Turing Machine.

CMSC 330: Organization of Programming Languages

Transcription:

CMSC 330: Organization of Programming Languages OCaml Imperative Programming CMSC330 Fall 2017 1

So Far, Only Functional Programming We haven t given you any way so far to change something in memory All you can do is create new values from old This makes programming easier since it supports mathematical (i.e., functional) reasoning Don t care whether data is shared in memory Ø Aliasing is irrelevant Calling a function f with argument x always produces the same result Ø f x = f x for all x 2

Imperative OCaml Sometimes it is useful for values to change Call a function that returns an incremented counter Store aggregations in efficient hash tables OCaml variables are immutable, but OCaml has references, fields, and arrays that are actually mutable I.e., they can change 3

References 'a ref: Pointer to a mutable value of type 'a There are three basic operations on references: ref : 'a -> 'a ref Ø Allocate a reference! : 'a ref -> 'a Ø Read the value stored in reference := : 'a ref -> 'a -> unit Ø Change the value stored in reference Binding variable x to a reference is immutable The contents of the reference x points to may change 4

References Usage Example: # let z = 3;; val z : int = 3 # let x = ref z;; val x : int ref = {contents = 3} # let y = x;; val y : int ref = {contents = 3} z 3 x y contents = 3 5

References Usage Example: # let z = 3;; val z : int = 3 # let x = ref z;; val x : int ref = {contents = 3} # let y = x;; val y : int ref = {contents = 3} # x := 4;; - : unit = () z 3 x y contents = 34 6

References Usage Example: # let z = 3;; val z : int = 3 # let x = ref z;; val x : int ref = {contents = 3} # let y = x;; val y : int ref = {contents = 3} # x := 4;; - : unit = () #!y;; - : int = 4 z 3 x y contents = 34 7

Aliasing Reconsider our example let z = 3;; let x = ref z;; let y = x;; x := 4;;!y;; Here, variables y and x are aliases: In let y = x, variable x evaluates to a location, and y is bound to the same location So, changing the contents of that location will cause both!x and!y to change 8

Quiz 1: What is the value w? let x = ref 42 in let y = ref 42 in let z = x in let () = x := 43 in let w =!y +!z in w A. 42 B. 84 C. 85 D. 86 9

Quiz 1: What is the value w? let x = ref 42 in let y = ref 42 in let z = x in let () = x := 43 in let w =!y +!z in w A. 42 B. 84 C. 85 D. 86 10

Quiz 1a: What is the value w? let x = ref 42 in let y = ref 42 in let z =!x in let () = x := 43 in let w =!y + z in w A. 42 B. 84 C. 85 D. Error 11

Quiz 1a: What is the value w? let x = ref 42 in let y = ref 42 in let z =!x in let () = x := 43 in let w =!y + z in w A. 42 B. 84 C. 85 D. Error 12

Implement a Counter # let counter = ref 0 ;; val counter : int ref = { contents=0 } # let next = fun () -> counter :=!counter + 1;!counter ;; val next : unit -> int = <fun> # next ();; - : int = 1 # next ();; - : int = 2 13

Hide the Reference # let next = let counter = ref 0 in fun () -> counter :=!counter + 1;!counter ;; val next : unit -> int = <fun> # next ();; - : int = 1 # next ();; - : int = 2 14

Quiz 2: What is wrong with the counter? let next = fun () -> let counter = ref 0 in counter :=!counter + 1;!counter A. Error, because counter isn't in scope in the final line B. It returns a reference to an integer instead of an integer C. It returns the same integer every time D. Nothing is wrong 15

Quiz 2: What is wrong with the counter? let next = fun () -> let counter = ref 0 in counter :=!counter + 1;!counter A. Error, because counter isn't in scope in the final line B. It returns a reference to an integer instead of an integer C. It returns the same integer every time D. Nothing is wrong 16

Hide the Reference, Visualized let next = let ctr = ref 0 in fun () -> ctr :=!ctr + 1;!ctr à let next = let ctr = loc in fun () -> ctr :=!ctr + 1;!ctr à let next = contents = 0 fun () -> ctr :=!ctr + 1;!ctr ctr = loc 17

References: Syntax and Semantics Syntax: ref e Evaluation Evaluate e to a value v Allocate a new location loc in memory to hold v Store v in contents of memory at loc Return loc Note: locations are first-class values Type checking (ref e) : t ref if e : t 18

References: Syntax and Semantics Syntax: e1 := e2 Evaluation Evaluate e2 to a value v2 Evaluate e1 to a location loc Store v2 in contents of memory at loc Return () Type checking (e1 := e2) : unit if e1 : t ref and e2 : t 19

References: Syntax and Semantics Syntax:!e This is not negation Evaluation Evaluate e to a location loc Return contents v of memory at loc Type checking!e : t if e : t ref 20

Sequences: Syntax and Semantics Syntax: e1; e2 e1; e2 is the same as let () = e1 in e2 Evaluation Evaluate e1 to a value v1 Evaluate e2 to a value v2 Return v2 We throw away v1 so e1 is useful only if it has effects, e.g., if it changes a reference s contents or accesses a file Type checking e1;e2 : t if e1 : unit and e2 : t 21

;; versus ; ;; ends an expression in the top-level of OCaml Use it to say: Give me the value of this expression Not used in the body of a function Not needed after each function definition Ø Though for now it won t hurt if used there e1; e2 evaluates e1 and then e2, and returns e2 let print_both (s, t) = print_string s; print_string t; "Printed s and t" notice no ; at end it s a separator, not a terminator print_both ( Colorless green ", ideas sleep") Prints Colorless green ideas sleep", and returns "Printed s and t" 22

Grouping Sequences If you re not sure about the scoping rules, use begin...end, or parentheses, to group together statements with semicolons let x = ref 0 let f () = begin print_string "hello"; x :=!x + 1 end let x = ref 0 let f () = ( print_string "hello"; x :=!x + 1 ) 24

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 No referential transparency Ø Calling the same function with the same arguments may produce different results Aliasing may result in hard-to-understand bugs Ø If we call a function with refs r1 and r2, it might do strange things if r1 and r2 are aliased 25

Quiz 3: What is the value w? let f _ z = z+1 in let y = ref 1 in let w = f (y:=2)!y in w A. 3 B. 2 C. Type Error D. () 26

Quiz 3: What is the value w? let f _ z = z+1 in let y = ref 1 in let w = f (y:=2)!y in w A. 3 B. 2 C. Type Error D. () 27

Quiz 4: What is the value w? let f z _ = z+1 in let y = ref 1 in let w = f!y (y:=2) in w A. 3 B. 2 C. Type Error D. () 28

Quiz 4: What is the value w? let f z _ = z+1 in let y = ref 1 in let w = f!y (y:=2) in w A. 3 B. 2 C. Type Error D. () 29

Structural vs. Physical Equality In OCaml, the = operator compares objects structurally [1;2;3] = [1;2;3] (* true *) (1,2) = (1,2) (* true *) The = operator is used for pattern matching The == operator compares objects physically [1;2;3] == [1;2;3] (* false *) Mostly you want to use the first one But it s a problem with cyclic data structures 30

Cyclic Data Structures Possible With Ref type 'a rlist = Nil Cons of 'a * ('a rlist ref);; let newcell x y = Cons(x,ref y);; let updnext (Cons (_,r)) y = r := y;; # let x = newcell 1 Nil;; val x : int reflist = Cons (1, {contents = Nil}) x Cons (1, ) contents = Nil 31

Cyclic Data Structures Possible With Ref type 'a rlist = Nil Cons of 'a * ('a rlist ref);; let newcell x y = Cons(x,ref y);; let updnext (Cons (_,r)) y = r := y;; # let x = newcell 1 Nil;; val x : int reflist = Cons (1, {contents = Nil}) # updnext x x;; - : unit = () x Cons (1, ) # x == x;; - : bool = true # x = x;; (* hangs *) contents = Nil 32

Mutable fields Fields of a record type can be declared as mutable: # type point = {x:int; y:int; mutable c:string};; type point = { x : int; y : int; mutable c : string; } # let p = {x=0; y=0; c="red"};; val p : point = {x = 0; y = 0; c = "red"} # p.c <- white ;; - : unit = () # p;; val p : point = {x = 0; y = 0; c = white"} # p.x <- 3;; Error: The record field x is not mutable 33

Implementing Refs Ref cells are essentially syntactic sugar: type 'a ref = { mutable contents: 'a } let ref x = { contents = x } let (!) r = r.contents let (:=) r newval = r.contents <- newval ref type is declared in Pervasives ref functions are compiled to equivalents of above 34

Arrays Arrays generalize ref cells from a single mutable value to a sequence of mutable values # let v = [ 0.; 1. ];; val v : float array = [ 0.; 1. ] # v.(0) <- 5.;; - : unit = () # v;; - : float array = [ 5.; 1. ] 35

Arrays Syntax: [ e1;...; en ] Evaluation Evaluates to an n-element array, whose elements are initialized to v1 vn, where e1 evaluates to v1,..., en evaluates to vn Ø Evaluates them right to left Type checking [ e1; ; en ] : t array Ø If for all i, each ei : t 36

Arrays Syntax: e1.(e2) Evaluation Evaluate e2 to integer value v2 Evaluate e1 to array value v1 If 0 v2 < n, where n is the length of array v1, then return element at offset v2 of v1 Else raise Invalid_argument exception Type checking: e1.(e2) : t if e1 : t array and e2 : int 37

Arrays Syntax: e1.(e2) <- e3 Evaluation Evaluate e3 to v3 Evaluate e2 to integer value v2 Evaluate e1 to array value v1 If 0 v2 < n, where n is the length of array v1, then update element at offset v2 of v1 to v3 Ø Else raise Invalid_argument exception Return () Type checking: e1.(e2) <- e3 : unit if e1 : t array and e2 : int and e3 : t 38

Quiz 5: What is the value w? let x = [ 0; 1 ] in let w = x in x.(0) <- 1; w A. 1 B. [ 0; 1 ] C. Type Error D. [ 1; 1 ] 39

Quiz 5: What is the value w? let x = [ 0; 1 ] in let w = x in x.(0) <- 1; w A. 1 B. [ 0; 1 ] C. Type Error D. [ 1; 1 ] 40

Control structures Traditional loop structures are useful with imperative features: while e1 do e2 done for x=e1 to e2 do e3 done for x=e1 downto e2 do e3 done 41

Comparison To OCaml int x; int y; C let x = ref 0;; let y = ref 0;; OCaml x = 3; x := 3;; (* x : int ref *) y = x; y := (!x);; 3 = x; 3 := x;; (* 3 : int; error *) In OCaml, an updatable location and the contents of the location have different types The location has a ref type 44

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 45

OCaml Programming Tips Compile your program often, after small changes The OCaml parser often produces inscrutable error messages It s easier to figure out what s wrong if you ve only changed a few things since the last compile If you re getting strange type error messages, add in type declarations Try writing down types of arguments For any expression e, can write (e:t) to assert e has type t 46

OCaml Programming Tips (cont.) Watch out for precedence and function application let mult x y = x*y mult 2 2+3 (* returns 7 *) (* parsed as (mult 2 2)+3 *) mult 2 (2+3) (* returns 10 *) 47

OCaml Programming Tips (cont.) All branches of a pattern match must return the same type match x with... -> -1 (* branch returns int *)... -> () (* uh-oh, branch returns unit *)... -> print_string foo (* also returns unit *) 48

OCaml Programming Tips (cont.) You cannot assign to ordinary variables! # let x = 42;; val x : int = 42 # x = x + 1;; (* this is a comparison *) -: bool = false # x := 3;; Error: This expression has type int but is here used with type 'a ref 49

OCaml Programming Tips (cont.) Again: You cannot assign to ordinary variables! # let x = 42;; val x : int = 42 # let f y = y + x;; (* captures x = 42*) val f : int -> int = <fun> # let x = 0;; (* shadows binding of x *) val x : int = 0 # f 10;; (* but f still refers to x=42 *) - : int = 52 50