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

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

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

OCaml Language Choices CMSC 330: Organization of Programming Languages

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. Lets, Tuples, Records

Programming Languages and Techniques (CIS120)

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

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

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

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

Ruby: Introduction, Basics

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

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

CSCI-GA Scripting Languages

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

Functional programming Primer I

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

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

CMSC 330: Organization of Programming Languages

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

CSCI 2041: Functions, Mutation, and Arrays

Topics Covered Thus Far CMSC 330: Organization of Programming Languages

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

Some Advanced ML Features

CS 11 Ocaml track: lecture 3

Introduction to OCaml

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

1007 Imperative Programming Part II

Mutation. COS 326 David Walker Princeton University

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

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

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

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

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

Begin at the beginning

Datatype declarations

Programming Languages

CS558 Programming Languages

Mutable References. Chapter 1

The Environment Model. Nate Foster Spring 2018

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

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

CS 320: Concepts of Programming Languages

CSCI 2041: Basic OCaml Syntax and Features

CMSC 330: Organization of Programming Languages

Ruby: Introduction, Basics

A Functional Evaluation Model

CS558 Programming Languages

CMSC 330: Organization of Programming Languages. OCaml Data Types

Programming Languages Third Edition. Chapter 7 Basic Semantics

Intro. Scheme Basics. scm> 5 5. scm>

Formal Specification and Verification

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

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

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

CMSC 330: Organization of Programming Languages. Operational Semantics

CS 360 Programming Languages Interpreters

CMSC 631. Functional Programming with OCaml

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

Imperative programming in F#

CS558 Programming Languages. Winter 2013 Lecture 3

CS558 Programming Languages

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

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

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

CMSC330. Objects, Functional Programming, and lambda calculus

An introduction introduction to functional functional programming programming using usin Haskell

CS131 Typed Lambda Calculus Worksheet Due Thursday, April 19th

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

The Environment Model

The Compiler So Far. CSC 4181 Compiler Construction. Semantic Analysis. Beyond Syntax. Goals of a Semantic Analyzer.

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

Objectives. Chapter 4: Control Structures I (Selection) Objectives (cont d.) Control Structures. Control Structures (cont d.) Relational Operators

G Programming Languages - Fall 2012

CSE 413 Languages & Implementation. Hal Perkins Winter 2019 Structs, Implementing Languages (credits: Dan Grossman, CSE 341)

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

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

Intermediate Code Generation

Lecture 2: SML Basics

L3 Programming September 19, OCaml Cheatsheet

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

CSE341: Programming Languages Lecture 17 Implementing Languages Including Closures. Dan Grossman Autumn 2018

15 150: Principles of Functional Programming. More about Higher-Order Functions

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

CS 231 Data Structures and Algorithms, Fall 2016

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

array Indexed same type

The role of semantic analysis in a compiler

CVO103: Programming Languages. Lecture 5 Design and Implementation of PLs (1) Expressions

Chapter 4: Control Structures I (Selection) Objectives. Objectives (cont d.) Control Structures. Control Structures (cont d.

G Programming Languages - Fall 2012

CS 314 Principles of Programming Languages

Programming Languages

Compilers. Type checking. Yannis Smaragdakis, U. Athens (original slides by Sam

Programming Languages Third Edition

Transcription:

CMSC 330: Organization of Programming Languages OCaml Imperative Programming CMSC330 Spring 2018 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 Ø For all x and y: f x = f y when x = y 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 12 in let y = ref 13 in let z = y in let _ = y := 4 in let w =!y +!z in w A. 25 B. 8 C. 17 D. 16 9

Quiz 1: What is the value w? let x = ref 12 in let y = ref 13 in let z = y in let _ = y := 4 in let w =!y +!z in w A. 25 B. 8 C. 17 D. 16 10

Quiz 1a: What is the value w? let x = ref 12 in let y = ref 13 in let z =!y in let _ = y := 4 in let w =!y + z in w A. 25 B. 8 C. 17 D. 16 11

Quiz 1a: What is the value w? let x = ref 12 in let y = ref 13 in let z =!y in let _ = y := 4 in let w =!y + z in w A. 25 B. 8 C. 17 D. 16 12

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 13

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 14

References: Syntax and Semantics Syntax:!e This is not negation. Operator! is like operator * in C Evaluation Evaluate e to a location loc Return contents v of memory at loc Type checking!e : t if e : t ref 15

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 16

;; 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" 17

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 ) 18

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 20

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

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 22

Quiz 2: What is wrong with the counter? let next = fun () -> let counter = ref 0 in counter :=!counter + 1;!counter A. Nothing is wrong B. It returns a boolean, not an integer C. It returns a reference to an integer instead of an integer D. It returns the same integer every time 23

Quiz 2: What is wrong with the counter? let next = fun () -> let counter = ref 0 in counter :=!counter + 1;!counter A. Nothing is wrong B. It returns a boolean, not an integer C. It returns a reference to an integer instead of an integer D. It returns the same integer every time 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

Order of Evaluation Consider this example let y = ref 1;; let f _ z = z+1;; (* ignores first arg *) let w = f (y:=2)!y;; w;; The first argument to the call to f is the result of the assignment expression y:=2, which is unit () The second argument is the current contents of reference y What is w if f s arguments are evaluated left to right? 3 What if they are evaluated right to left? 2 26

OCaml Order of Evaluation In OCaml, the order of evaluation is unspecified This means that the language doesn t take a stand, and different implementations may do different things On my Mac, OCaml evaluates right to left True for the bytecode interpreter and x86 native code Run the previous example and see for yourself! Strive to make your programs produce the same answer regardless of evaluation order 27

Quiz 3: Will w s value differ If evaluation order is left to right, rather than right to left? let y = ref 1 in let f z = z :=!z+1;!z in let w w = (f y) +!y in A. True B. False 28

Quiz 3: Will w s value differ If evaluation order is left to right, rather than right to left? let y = ref 1 in let f z = z :=!z+1;!z in let w w = (f y) +!y in A. True B. False 29

Quiz 4: Will w s value differ If evaluation order is left to right, rather than right to left? let y = ref 1 in let f z = z :=!z+1;!z in let w w = (f y) + (f y) in A. True B. False 30

Quiz 4: Will w s value differ If evaluation order is left to right, rather than right to left? let y = ref 1 in let f z = z :=!z+1;!z in let w w = (f y) + (f y) in A. True B. False 31

Quiz 5: Which f is not referentially transparent? I.e., not the case that f x = f y for all x = y A. let f z = let y = ref z in y :=!y + z;!y B. let f = let y = ref 0 in fun z -> y :=!y + z;!y C. let f z = let y = z in y+z D. let f z = z+1 32

Quiz 5: Which f is not referentially transparent? I.e., not the case that f x = f y for all x = y A. let f z = let y = ref z in y :=!y + z;!y B. let f = let y = ref 0 in fun z -> y :=!y + z;!y C. let f z = let y = z in y+z D. let f z = z+1 This is basically the counter function 33

Structural vs. Physical Equality 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 is the negation of structural equality The == operator compares objects physically [1;2;3] == [1;2;3] (* false *) The!= operator is the negation of physical equality Mostly you want to use structural equality But it s a problem with cyclic data structures 34

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 35

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 36

Equality of refs themselves Refs are compared structurally by their contents, physically by their addresses ref 1 = ref 1 (* true *) ref 1 <> ref 2 (* true *) ref 1!= ref 1 (* true *) let x = ref 1 in x == x (* true *) 37

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 38

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 39

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. ] 40

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 41

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 42

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 43

Quiz 6: 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 ] 44

Quiz 6: 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 ] 45

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 46

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 49

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 write down types OCaml uses type inference to figure out types for you Good: less work to write programs Bad: easier to make mistakes, harder to find errors 50

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 51

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 *) 52

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 *) 53

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 54

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 55